#Module permettant de lire le nombre de carre blanc, gris et noir d'une image suivant la taille de la grille

import Image
import sys
from math import log,ceil


class Box_Counting:
    "Module to count the box in one image"
    def __init__(self,image_name):
        try :
            self.Im=Image.open(image_name).convert("1")
        except:
            print "This image is not a valid one" 
            sys.exit()
       
        largeur=self.Im.size[0]
        hauteur=self.Im.size[1] 
        size=hauteur
        if largeur > hauteur:
            size=largeur
        self.Size_max_box=size/8+1

        self.setboxes('pair')
        self.Precison=1.2




            
    def setboxes(self,method):
        if method == 'all':
            self.Boxes=range(2,self.Size_max_box)
        elif method == 'pair':
            self.Boxes=[x for x in range(2,self.Size_max_box) if x%2 == 0]
        elif method == 'exponential' :
            def unique(list):
                return dict([(i,0) for i in list]).keys()

            self.Boxes=unique([int(ceil(self.Precision**i)) for i in range(1,int(log(self.Size_max_box,self.Precision)))])
        else:
            raise InvalidArgument, 'invalid method' 

            
    def setprecicion(self,precision):
        self.Precison=precision


    def compute(self):
        self.Nb_BGW_for_each_box()

    def plot(self):
        Plot=[]
        for box in self.Computation.keys():
            (white,grey,black)=self.Computation[box]
            Plot.append((log(box),log(grey)))
        return Plot

    def Nb_BGW_for_each_box(self):
        width=self.Im.size[0]
        height=self.Im.size[1]
        Structure=Structure_Creation(width,height,self.Boxes)
        for i in range(0,width):
            for j in range(0,height):
                pixel=self.Im.getpixel((i,j))
                for box in self.Boxes:
                    table=Structure[box]
                    color_box=table[i/box][j/box]
                    if not color_box==1:
                        if color_box==-1:
                            table[i/box][j/box]=pixel
                            Structure[box]=table
                        elif not color_box==pixel:
                            table[i/box][j/box]=1
                            Structure[box]=table
        self.Computation=Structure
        for box in self.Computation.keys():
            self.Computation[box]=count_box(self.Computation[box],box,width,height)
        



def Structure_Creation(width,height,Boxes):
    structure={}
    def Table_creation(box):     
        result=[[]]*((width+box-1)/box)
        for i in range((width+box-1)/box):
            result[i]=[-1]*((height+box-1)/box)
        return result
    for box in Boxes:
        structure[box]=Table_creation(box)
    return structure


def count_box(table,box,width,height): #we use width and height to know if the box is complete
    def count_2d(element):
        width_poucent=width%box
        if width_poucent ==0 :
            width_poucent =1
        else:
            width_poucent=(width_poucent+0.0)/box

        height_poucent=height%box
        if height_poucent ==0 :
            height_poucent =1
        else:
            height_poucent=(height_poucent+0.0)/box

        
        res=0
        for i in table[0:-1]:
            for j in i[0 : -1]:               
                if j == element:
                    res+=1
            j=i[-1]
            if j == element:
                res+=height_poucent
        i=table[-1]
        for j in i[0:-1]:               
            if j == element:
                res+=width_poucent
        j=i[-1]
        if j == element:
            res+=height_poucent*width_poucent
        
        return res
    #begin debug
  #  if count_2d(-1)!=0:
   #     print "There is -1 left :",count_2d(-1)
    return((count_2d(255),count_2d(1),count_2d(0)))
        
#color code
#-1 no information
#0=black
#1=grey
#255=white



