from Tkinter import *
from random import randrange
from time import sleep

#initialisation des constantes
NbChif = 10
bas    = [0]*NbChif
haut   = [0]*NbChif
moulin = [0]*NbChif
erase = True
decal = 0
max_decal = 8
delai = 1
menu_aide = False
hauteur = 50

#initialisation de l affichage
fen = Tk()
can = Canvas(fen, width = 850, height = 800, bg = 'SteelBlue2')
can.pack()


Coul_bas   = 'Black'
Coul_haut  = 'Black'
Coul_moulin= 'Black'
Fonte = 'Arial 30'

bas_aff     =[0]*NbChif
haut_aff    =[0]*NbChif
moulin_aff  =[0]*NbChif
haut_cadre  =[0]*NbChif
moulin_cadre=[0]*NbChif
#affichage des trois registres
for k in range(NbChif) :
    can.create_rectangle(382-30*k, 167, 411-30*k, 222, fill='Grey')
    bas_aff[k] = can.create_text(400-30*k,200,text=str(bas[k]), fill=Coul_bas, font=Fonte)
    haut_cadre[k]=can.create_rectangle(382-30*k, 65, 411-30*k, 120, fill='Grey')
    haut_aff[k] = can.create_text(400-30*k,90,text=str(haut[k]), fill=Coul_haut, font=Fonte)
    moulin_cadre[k]=can.create_rectangle(382-30*k, 515, 411-30*k, 575, fill='Grey')
    moulin_aff[k] = can.create_text(400-30*k,540,text=str(moulin[k]), fill=Coul_moulin, font=Fonte)
#affichage des boutons de saisie
for k in range(NbChif) :
    for chif in range(10) :
        can.create_oval(387-30*k, 228+25*chif, 413-30*k, 252+25*chif, fill='SteelBlue3', width=3)
        can.create_text(400-30*k, 240+25*chif, text=str(chif), font = 'TrueType 10')
#affichage des symboles
def symbole_droit(hauteur, texte, police) :
    can.create_oval(450, hauteur, 590, hauteur+50, fill='LightGreen', width=4)
    can.create_text(520, hauteur+30, text=texte, font = 'TrueType '+police)

symbole_droit(  0, 'Raz', '20')
symbole_droit(180, 'Raz', '20')
symbole_droit(300, '-'  , '40')
symbole_droit(400, '+'  , '40')
symbole_droit(460, 'Raz', '20')
can.create_rectangle(20, 160, 80, 210, fill='Brown', width=4)
erase_texte=can.create_text(50, 190, text='erase', font = 'Arial 10')
can.create_rectangle(20, 10, 80, 60, fill='Brown', width=4)
can.create_text(50, 40, text='<---', font = 'ArialBold 10')
can.create_rectangle(20, 80, 80, 130, fill='Brown', width=4)
can.create_text(50, 100, text='--->', font = 'ArialBold 10')
can.create_rectangle(20, 230, 80, 280, fill='Brown', width=4)
can.create_text(50, 250, text='Aide', font = 'ArialBold 10')




def alea() :
    return(randrange(10))

def souris(event) :
    global menu_aide
    ix, iy = event.x, event.y
    ix = int(NbChif-1-(ix-120)/30)
    iy = int((iy-225)/25)
    print('souris', ix, iy)
    if ix in range(NbChif) and iy in range(10) :
        bas[ix] = iy
        can.itemconfig(bas_aff[ix],text=str(bas[ix]))
        print('modif')
    if ix in range(11,13) and iy in range(-3,-1) :
        print('lock')
        modif_erase()
    if ix in range(11,13) and iy in range(-6,-4) :
        print('decale+')
        decale_affichage(1)
    if ix in range(11,13) and iy in range(-9,-7) :
        print('decale-')
        decale_affichage(-1)
    if ix in range(11,13) and iy in range(0, 2) :
        print('aide')
        if not(menu_aide) :
            menu_aide = True
            fenetre_aide()
        
    if ix in range(-6, -1) :
        print('action')
        if iy in range(7, 9) :
            addition()
        if iy in range(3, 5) :
            soustraction()
        if iy in range(-2, 0) :
            for k in range(NbChif) :
                bas[k] = 0
                can.itemconfig(bas_aff[k], text='0')
        if iy in range(-9, -7) :
            for k in range(NbChif) :
                haut[k] = 0
                can.itemconfig(haut_aff[k], text='0')
        if iy in range(10, 12) :
            for k in range(NbChif) :
                moulin[k] = 0
                can.itemconfig(moulin_aff[k], text='0')
                
def addition() :
    global bas, haut, moulin, decal, erase
    retenue_haut = 0
    retenue_moulin=0
    ajoute_moulin = 1
    for k in range(decal, NbChif) :
        haut[k] = haut[k]+bas[k-decal]+retenue_haut
        retenue_haut = haut[k]/10
        haut[k] = haut[k]%10
        moulin[k] = moulin[k]+ajoute_moulin+retenue_moulin
        retenue_moulin = moulin[k]/10
        moulin[k] = moulin[k]%10
        ajoute_moulin=0
    if erase :
        for k in range(NbChif) :
            bas[k] = 0
            can.itemconfig(bas_aff[k],text='0')
    affiche()
    
def modif_erase() :
    global erase 
    erase=not(erase)
    if erase :
        can.itemconfig(erase_texte, text='erase')
    else :
        can.itemconfig(erase_texte, text='lock')
    
    
def soustraction() :
    global bas, haut, moulin, decal, erase
    retenue_haut = 0
    retenue_moulin=0
    ajoute_moulin = -1
    for k in range(decal, NbChif) :
        haut[k] = haut[k]-bas[k-decal]+retenue_haut
        retenue_haut = haut[k]/10
        haut[k] = haut[k]%10
        moulin[k] = moulin[k]+ajoute_moulin+retenue_moulin
        retenue_moulin = moulin[k]/10
        moulin[k] = moulin[k]%10
        ajoute_moulin=0
    if erase :
        bas = [0]*NbChif
    affiche()

def decale_affichage(pm) :
    global decal
    decal = decal+pm
    if decal in range(0, max_decal) :
        for k in range(NbChif) :
            can.move(haut_aff[k],pm*30,0)
            can.move(haut_cadre[k],pm*30,0)
            can.move(moulin_aff[k],pm*30,0)
            can.move(moulin_cadre[k],pm*30,0)
    else :
        decal = decal-pm
        
def affiche() :
    print('haut', haut)
    print('bas', bas)
    for k in range(NbChif) :
        can.itemconfig(bas_aff[k],text=str(bas[k]))
        can.itemconfig(haut_aff[k],text=str(haut[k]))
        can.itemconfig(moulin_aff[k],text=str(moulin[k]))
    can.update()
    sleep(delai)

def bas_aleatoire() :
    for k in range(NbChif) :
        modifchiffre(k,alea())

def modifchiffre(rang, valeur) :
    global bas
    bas[rang]=valeur
    
def fenetre_aide() :
    global menu_aide, hauteur
    hauteur = 20
    def texte(larg, texte) :
        global hauteur
        print('haut=',hauteur)
        fond.create_text(larg, hauteur, text='*-'+texte, font='Garamond 9',anchor=W)
        hauteur +=20
        print(texte)
        
    def detruit() :
        global menu_aide
        menu_aide = False
        aide.destroy()
        print('retour aide')
    aide=Tk()
    fond = Canvas(aide, width = 800, height = 600, bg = 'Green')
    fond.pack()
    bou = Button(aide, text='Fermeture', command = detruit)
    bou.pack()
    hauteur = 20
    texte( 10,'Ce programme simule une calculatrice de bureau mecanique')
    texte( 10,'Pour additionner : ')
    texte(100,'saisissez un nombre a l aide des touches rondes')
    texte(100,'tapez sur la touche ovale +')
    texte(100,'le nombre est additionne dans le registre du haut')
    texte(100,'pour additionner un autre nombre, saisissez le a son tour,')
    texte(200,'puis tapez sur +')
    texte(100,'et pour soustraire, tapez sur la touche ovale -')
    texte( 10,'Pour effacer, utilisez les touches RAZ')
    texte( 10,'Pour additionner plusieurs fois le meme nombre :')
    texte(100,'Basculez la touche erase/lock sur sa position lock')
    texte(100,'les actions sur les touches ovales n effacent plus le nombre')
    texte(10,'Pour multiplier un nombre a par un nombre b :')
    texte(100,'saisissez le nombre a avec les touches rondes')
    texte(100,'bloquez le avec la touche lock/erase')
    texte(100,'remettez a zero le compteur du bas')
    texte(100,'effectuez alors b additions consecutives')
    texte(100,'le compteur du bas affiche au fur et a mesure la valeur de b')
    texte(100,'si b est multiple de 10, n effectuez pas dix additions')
    texte(200,'utilisez --> et <-- pour translater les registres')
    texte(100,'et plus generalement, decomposez b en dizaines, unites, centaines, milliers')
    texte(10,'Pour effectuer une division :')
    texte(100,'entrez le dividende dans le registre du haut, par addition')
    texte(100,'remettez a zero le compteur du bas')
    texte(100,'saisissez le diviseur avec les touches rondes')
    texte(100,'maintenez le en position lock')
    texte(100,'effectuez des soustractions jusqu a ce que le reste soit plus petit que le diviseur')
    texte(100,'le compteur vous donne le quotient')
    
    aide.mainloop()
    
    
    
affiche()
can.bind("<Button-1>", souris)
fen.mainloop()
