#-*-coding:utf8-*-
#
# On reprend tout le chiffrement. On souhaite chiffrer, par itérations
# chaotiques, des images.

import Image as im
from numpy import array
from outilsBase import conversion
from operator import xor
from BitVector import BitVector
from math import log
from coefficients import Coefficients

class Chiffrement:

    _bits_par_coef = { '1' : 1, 'L' : 8, 'RGB' : 8}

    def __init__(self, fichier_image = 'lena.png',
                       iterations = None,
                       authentification = None,
                       mu = None, Xo = None):
        if iterations == None:
            self._iterations = input("Combien d'itérations ? ")
        else:
            self._iterations = iterations

        self._authentification = authentification
        if self._authentification == None:
            self._authentification = eval(raw_input("Authentification (True/False) ? "))
            if self._authentification:
                self._bits_forts = eval(raw_input("Liste des MSB : "))

        self._image = im.open(fichier_image)
        self._mode = self._image.mode
        liste = list(self._image.getdata())

        if self._authentification:
            self._msb = Coefficients().getAllCoefs(fichier_image, self._bits_forts)

        if self._mode == '1':
            liste = [k/255 for k in liste]
        elif self._mode == 'RGB':
            liste2 = []
            for k in liste:
                liste2 += k
            liste = liste2

        self._systeme = [conversion(k,2).zfill(self._bits_par_coef[self._mode]) for k in liste]
        self._systeme = ''.join(self._systeme)
        self._systeme = BitVector(bitstring = self._systeme)

        self._strategie = []

        self._mu = mu
        if self._mu == None:
            self._mu = input("\nQuel mu pour la suite logistique ? ")

        self._X = Xo
        self._Xo = Xo
        if self._X == None:
            self._X = input("Quel Xo ? ")




    def chiffrement(self):
        # Suite de bits à partir de la suite logistique
        code = ''
        self._taille = int(log(len(self._systeme),2))+1
        cpt = 0

        for k in range(self._iterations*self._taille):
            Y = 0 if self._X<0.5 else 1
            self._X = self._mu*self._X*(1-self._X)
            if not self._authentification:
                code += str(Y)
            else:
                code += str(int(xor(Y,self._msb[cpt%len(self._msb)])))
                cpt += 1
            if len(code)%self._taille == 0:
                code = int(code,2)
                if code < len(self._systeme):
                    self._systeme[code] = not self._systeme[code]
                self._strategie.append(code)
                code = ''




    def get_image(self):
        image2 = im.new(self._mode, self._image.size)
        (x,y) = self._image.size
        compteur = 0
        for k in range(x):
            for l in range(y):
                coef = ''
                for m in range(self._bits_par_coef[self._mode]):
                    coef += str(self._systeme[compteur])
                    compteur += 1
                valeur = int(coef,2)
                if self._mode == '1':
                    valeur *= 255
                image2.putpixel((l,k),valeur)
        return image2



    def get_strategie(self):
        return self._strategie


    def get_parametres(self):
        return [self._mu, self._Xo]



    def get_iterations(self):
        return self._iterations



if __name__ == '__main__':
    ch = Chiffrement(fichier_image = 'invader.png', iterations = 10000)
    ch.chiffrement()
    print "Strategie : ", ch.get_strategie()[:10]
    ch.get_image().save('invader_chiffre.png')
