#-*- coding:utf-8 -*-
from os import system
import Image as Im
import ImageEnhance
from numpy import random
from ConfigParser import ConfigParser

class Attaque:
    '''
    Classe pour attaquer une image tatouée, en vue d'enlever la marque.
    '''

    def __init__(self, nom = '', configuration = None):
        '''
        Constructeur : récupère l'image à attaquer.
        '''
        assert nom != ''

        self._nom   = nom
        self._image = Im.open(nom)
        choix = 0

        # Affichage du menu d'attaque, si rien n'est précisé
        if configuration == None:
            print "\n====================== Attaque ====================="
            print "Quelle attaque ?"
            print "  1. rotation"
            print "  2. redimensionnement"
            print "  3. découpage"
            print "  4. flou"
            print "  5. contraste"
            print "  6. jpeg"
            print "  7. bruit gaussien"
            print "  8. bruit uniforme"
            choix = eval(raw_input("Votre choix ? "))
        else:
            config = ConfigParser()
            config.read([configuration])
            attaque = config.get("ATTAQUE","type")
            choix_attaques = {'rotation':1,'redimensionnement':2,
                              'decoupage':3, 'flou':4, 'contraste':5,
                              'jpeg':6, 'gaussien':7, 'uniforme':8}
            choix = choix_attaques[attaque]
        if choix == 1:
            if configuration == None:
                print "Attaque par rotation"
                angle = eval(raw_input("  Quel angle ? "))
                nombre = eval(raw_input("  Combien de rotations ? "))
                self.rotation(angle = angle, nombre = nombre)
        elif config.get('ATTAQUE','type') == 'rotation':
            angle = config.getint('ROTATION','angle')
            nombre = config.getint('ROTATION','nombre')
            self.rotation(angle = angle, nombre = nombre)
        elif choix == 2:
            print "Attaque par redimensionnement"
            pixels = eval(raw_input("  Combien de pixels ? "))
            nombre = eval(raw_input("  Combien de fois ? "))
            self.redimensionnement(nombrePixels = pixels, nombre = nombre)
        elif choix == 3:
            if configuration == None:        
                print "Attaque par découpage"
                taille = eval(raw_input("  Quelle taille ? "))
                position = eval(raw_input("  Quelle position ? "))
            else:
                taille = config.getint("DECOUPAGE","taille")
                position = eval(config.get("DECOUPAGE","position"))
            self.decoupage(taille = taille, position = position)
        elif choix == 4:
            print "Attaque par flou"
            taux = eval(raw_input("  Quel taux ? "))
            self.flou(taux = taux)
        elif choix == 5:
            print "Attaque par contraste"
            taux = eval(raw_input("  Quel taux ? "))
            self.contraste(taux = taux)
        elif choix == 6:
            print "Attaque par jpeg"
            taux = eval(raw_input("  Quel taux ? "))
            self.jpeg(taux = taux)
        elif choix == 7:
            print "Attaque par bruit gaussien"
            taux = eval(raw_input("  Quel écart-type ? "))
            self.bruitGaussien(taux)
        elif choix == 8:
            print "Attaque par bruit uniforme"
            taux = eval(raw_input("  Quel écart ? "))
            self.bruitUniforme(taux)




    def rotation(self,angle = 2, nombre = 1):
        '''
        Attaque par rotation.

        On fait pivoter l'image de 2 degrés (ou de l'angle fixé par l'attaquant)
        dans un sens et dans l'autre.
        On peut préciser le nombre de fois à le faire.
        '''
        for k in range(nombre):
            carreNoir=Im.new('L',(500,500),color=1)
            carreNoir.paste(self._image,(100,100))

            tourne = carreNoir.rotate(angle)
            carreNoir = tourne.rotate(-angle)

            self._image = carreNoir.crop((101,101,357,357))




    def redimensionnement(self, nombrePixels = 1, nombre = 1):
        '''
        Attaque par redimensionnement de l'image.
        '''
        for k in range(nombre):
            self._image = \
                   self._image.resize((self._image.size[0] + nombrePixels,
                                       self._image.size[1] + nombrePixels))




    def decoupage(self, taille = 50, position = (0,0)):
        '''
        Attaque par découpage de l'image.
        '''
        carreNoir=Im.new('L',(taille,taille),color=1)
        self._image.paste(carreNoir,position)



    def flou(self,taux = 1):
        '''
        Attaque en jouant sur le flou/la netteté :
               - taux = 1 : image d'origine,
               - taux < 1 : image plus floue,
               - taux > 1 : image plus nette.
        '''
        amelioration = ImageEnhance.Sharpness(self._image)
        self._image = amelioration.enhance(taux)


    def contraste(self,taux = 1):
        '''
        Attaque en jouant sur le contraste :
               - taux = 1 : image d'origine,
               - taux < 1 : image moins contrastée,
               - taux > 1 : image plus contrastée.
        '''
        amelioration = ImageEnhance.Contrast(self._image)
        self._image = amelioration.enhance(taux)


    def jpeg(self, taux = 100):
        '''Attaque par compression jpeg :
               - taux = 100 : image d'origine,
               - taux 75 : compression par défaut,
               - taux = 1 : le plus fort taux de compression.'''
        #TODO : utiliser le module de fichier temporaire de python
        self._image.save('tempo.jpg',quality = taux)
        self._image = Im.open('tempo.jpg')
        system('rm tempo.jpg')


    def bruitGaussien(self, ecarttype):
        '''
        Ajoute un bruit gaussien.
        '''
        for x in range(self._image.size[0]):
            for y in range(self._image.size[1]):
                self._image.putpixel((x,y),
                     int(random.normal(self._image.getpixel((x,y)), ecarttype)))


    def bruitUniforme(self, ecart):
        '''
        Ajoute un bruit uniforme.
        '''
        for x in range(self._image.size[0]):
            for y in range(self._image.size[1]):
                self._image.putpixel((x,y),
                                     self._image.getpixel((x,y)) + \
                                     int(random.uniform(-ecart,ecart)))


    def getImage(self):
        '''
        Renvoie l'objet Image.
        '''
        return self._image



    def show(self):
        '''
        Montre l'image attaquée.
        '''
        self._image.show()


    def save(self, nom = ''):
        '''
        Méthode pour sauvegarder l'image marquée.
        '''
        if len(nom)==0:
            self._image.save(self._nom)
        else:
            self._image.save(nom)

