#!/usr/bin/env python
# -*- coding: utf-8 -*-
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os.path
from tkinter import *
from random import *
import tkinter.font as tkFont
import time
from statistics import mean
import pickle
import os
import sys
import pathlib
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)
from tkinter import tix
from functools import partial

if sys.platform == "linux":
    linux=1
else:
    linux=0

ok_maj_canvas=0


#Détermination du dossier utilisateur selon l'OS
def get_datadir() -> pathlib.Path:
    home = pathlib.Path.home()
    if sys.platform == "win32":
        return home / "AppData/Roaming"
    elif sys.platform == "linux":
        return home / ".local/share"
    elif sys.platform == "darwin":
        return home / "Library/Application Support"

#Déclaration du dossier utilisateur
my_datadir = get_datadir() / "tuxblocs"

#Test si le dossier existe
try:
    my_datadir.mkdir(parents=True)
except FileExistsError:
    pass

couleur="#dfe5fe"
couleur_bouton="#b5c3fd"

#Création de la fenêtre
fenetre = tix.Tk()
fenetre.title("Tuxblocs")
if linux==1:
    fenetre.attributes("-zoomed",1)
else:
    fenetre.state('zoomed')
fenetre.minsize(width=1000,height=700)
fenetre.configure(background=couleur)
fenetre.update()
larg=fenetre.winfo_width()
haut=fenetre.winfo_height()
fenetre.rowconfigure(1,weight=1)
fenetre.columnconfigure(1,weight=1)


#Images
img_pleinecran=PhotoImage(file="images/pleinecran.png")
img_sortiepleinecran=PhotoImage(file="images/sortiepleinecran.png")
img_corbeille=PhotoImage(file="images/corbeille.png")
img_hasard=PhotoImage(file="images/hasard.png")
img_hasard2=PhotoImage(file="images/hasard2.png")
img_melanger=PhotoImage(file="images/melanger.png")
img_ranger=PhotoImage(file="images/ranger.png")
img_grouper=PhotoImage(file="images/grouper.png")
img_degrouper=PhotoImage(file="images/degrouper.png")
img_couleurs=PhotoImage(file="images/couleurs.png")
img_jaune=PhotoImage(file="images/jaune.png")
img_rouge=PhotoImage(file="images/rouge.png")
img_bleu=PhotoImage(file="images/bleu.png")
img_vert=PhotoImage(file="images/vert.png")
img_violet=PhotoImage(file="images/violet.png")
img_orange=PhotoImage(file="images/orange.png")
img_minicorbeille = PhotoImage(file="images/corbeille2.png")
img_cree_unite = PhotoImage(file="images/cree_unite.png")
img_cree_dizaine = PhotoImage(file="images/cree_dizaine.png")
img_cree_centaine = PhotoImage(file="images/cree_centaine.png")
img_cree_millier = PhotoImage(file="images/cree_millier.png")
img_quitter=PhotoImage(file="images/quitter.png")
img_reduire=PhotoImage(file="images/reduire.png")
img_cadenas_ferme=PhotoImage(file="images/cadenas_ferme.png")
img_cadenas_ouvert=PhotoImage(file="images/cadenas_ouvert.png")
img_oeil=PhotoImage(file="images/oeil.png")
img_mask=PhotoImage(file="images/mask.png")
img_oeil_inactif=PhotoImage(file="images/oeil_inactif.png")
img_unite=PhotoImage(file="images/grandes/unite_jaune.png")
img_dizaine=PhotoImage(file="images/grandes/dizaine_lignes_jaune.png")
img_centaine=PhotoImage(file="images/grandes/centaine_lignes_jaune.png")
img_millier=PhotoImage(file="images/petites/millier_lignes_jaune.png")
if haut>750:
    img_logo=PhotoImage(file="images/logo.png")
else:
    img_logo = PhotoImage(file="images/logo720.png")
img_aide=PhotoImage(file="images/aide.png")
img_info=PhotoImage(file="images/info.png")
img_options=PhotoImage(file="images/options.png")
img_separation=PhotoImage(file="images/separation.png")
img_teacher=PhotoImage(file="images/teacher.png")
img_teacher2=PhotoImage(file="images/teacher2.png")
img_marque=PhotoImage(file="images/marque.png")
img_pointe=PhotoImage(file="images/pointe.png")
img_grab=PhotoImage(file="images/grab.png")


#Création des cadres
zone_haut=Frame(fenetre, height=100, width=larg,background=couleur)
zone_gauche=Frame(fenetre, width=100,height=haut-100,background=couleur)
zone_haut.grid(row=0,column=0, columnspan=2, sticky='nesw')
zone_gauche.grid(row=1,column=0, sticky='nesw')
zone_princ=Canvas(fenetre,borderwidth=0, highlightthickness=0, background=couleur, width=larg-100,height=larg-100)
zone_princ.grid(row=1,column=1)
zone_gauche.columnconfigure(0,minsize=25)
zone_gauche.columnconfigure(1,minsize=25)
zone_gauche.columnconfigure(2,minsize=25)
zone_gauche.columnconfigure(3,minsize=25)
zone_gauche.rowconfigure(9,weight=1)
zone_logo=Canvas(zone_gauche,background=couleur,highlightthickness=0,borderwidth=0,width=95)


#Dimensions du canvas
larg_canvas=larg-100
haut_canvas=haut-100
centre_canvas_y=haut_canvas/2

#Marge extérieure des colonnes
margey=50
margex=10

#Polices
moyen = tkFont.Font(family='Helvetica', size=14)
gros = tkFont.Font(family='Helvetica', size=20, weight='bold')
tres_gros = tkFont.Font(family='Helvetica', size=30, weight='bold')



zone_logo.grid(row=9,column=0,columnspan=4, sticky='nsew')
fenetre.update()
logo=zone_logo.create_image(50.5,zone_logo.winfo_height()-1,anchor='s',image=img_logo)
def standard():
    global nbcolonnes,interg,interu,interd,interc,interm, lock
    choixcol.set(2)
    nbcolonnes = 2
    ordre.set(0)
    lignes.set(1)
    peda.set(1)
    couleurpeda.set(1)
    separations.set(0)
    aff_compteur.set(1)
    couleur_unite.set("jaune")
    couleur_dizaine.set("jaune")
    couleur_centaine.set("jaune")
    couleur_millier.set("jaune")
    max_u.set(9)
    max_d.set(9)
    max_c.set(9)
    max_m.set(9)
    cachecompteur.set(1)
    montrecompteur.set(1)
    limit.set(1)
    razinterro.set(0)
    interrocachecompteur.set(1)
    interg=interu=interd=interc=interm=0
    affichage_compteur(aff_compteur_unite,compteur_unites,interu)
    affichage_compteur(aff_compteur_dizaine, compteur_dizaines, interd)
    affichage_compteur(choix_compteur, compteur, interg)
    if nb>2 or nb==1:
        affichage_compteur(aff_compteur_centaine, compteur_centaines, interc)
    if nb>3 or nb==1:
        affichage_compteur(aff_compteur_millier, compteur_milliers, interm)
    lock=0
    reset("tout")
    nouveau(nb)
    lock=1

marku=[]
markd=[]
markdg=[]
markc=[]
markcg=[]
markm=[]
markmg=[]

rect_rouge=[]
#Variables globales de départ
normal="#fff"
tropde=[]
nombre=0
milliers=centaines=dizaines=unites=0
nbcolonnes=2
fullscreen=IntVar()
fullscreen.set(False)
#Permet la mise à jour du Canvas après un redimensionnement de la fenêtre
ok_maj=1
optionsouverte=IntVar()
aideouverte=IntVar()
aproposouverte=IntVar()
aideouverte.set(False)
aproposouverte.set(False)
optionsouverte.set(False)


ordre=IntVar()
ordre.set(0)
lignes=IntVar()
lignes.set(1)
peda=IntVar()
peda.set(1)
couleurpeda=IntVar()
couleurpeda.set(1)
separations=IntVar()
separations.set(0)
couleurs=IntVar()
couleurs.set(0)
aff_compteur=IntVar()
aff_compteur.set(1)
valcache=IntVar()
valcache.set(0)
choixcache=StringVar()
choixcache.set("deco")
couleur_unite=StringVar()
couleur_unite.set("jaune")
couleur_dizaine=StringVar()
couleur_dizaine.set("jaune")
couleur_centaine=StringVar()
couleur_centaine.set("jaune")
couleur_millier=StringVar()
couleur_millier.set("jaune")
max_u=IntVar()
max_d=IntVar()
max_c=IntVar()
max_m=IntVar()
max_u.set(9)
max_d.set(9)
max_c.set(9)
max_m.set(9)
cachecompteur=IntVar()
cachecompteur.set(1)
montrecompteur=IntVar()
montrecompteur.set(1)
limit=IntVar()
limit.set(1)
razinterro=IntVar()
razinterro.set(0)
interrocachecompteur=IntVar()
interrocachecompteur.set(1)

compteur=Label(zone_haut, text=nombre, font=tres_gros, fg="#f97000",relief=GROOVE, borderwidth=5)
compteur_milliers = Label(zone_haut,background=couleur, text=milliers, font=gros, fg="blue")
compteur_centaines = Label(zone_haut,background=couleur, text=centaines, font=gros, fg="blue")
compteur_dizaines = Label(zone_haut,background=couleur, text=dizaines, font=gros, fg="blue")
compteur_unites = Label(zone_haut,background=couleur, text=unites, font=gros, fg="blue")


def fois_10(event):
    global coords_groupe,dg,unites, cg, dizaines, mg, centaines
    if nombre<10000 and milliers<10 and centaines<20:
        if mg==0 and cg==0 and dg==0:
            if nb>3:
                for i in range (9*milliers):
                    cree("millier",1000,"normal")
                maj()
            if nb>2 and centaines>0:
                for i in range (centaines-10*mg):
                    coords_groupe=zone_princ.coords(objets_centaines[-i])
                    cree("millier",1000,"groupe")
                    zone_princ.delete(objets_centaines[-i])
                objets_centaines.clear()
                mg = mg + centaines
                centaines=mg*10
                maj()
                if nb > 3:
                    gauche("millier", "rien")
            if nb>1 and dizaines>0:
                for i in range (dizaines-10*cg):
                    coords_groupe=zone_princ.coords(objets_dizaines[-i])
                    liste = liste_dizaine
                    if coords_groupe[1] < liste[1] + 10 * larg_unite:
                        coords_groupe[1] = liste[1]+8*larg_unite
                    if coords_groupe[1] > liste[3] - 10 * larg_unite:
                        coords_groupe[1] = liste[3]-10*larg_unite
                    if coords_groupe[0] < liste[0] + larg_dizaine/2:
                        coords_groupe[0] = liste[0]+ larg_dizaine/2
                    if coords_groupe[0] > liste[2] - larg_dizaine/2:
                        coords_groupe[0] = liste[2]-larg_dizaine/2
                    cree("centaine",100,"groupe")
                    zone_princ.delete(objets_dizaines[-i])
                objets_dizaines.clear()
                cg = cg + dizaines
                dizaines=cg*10
                maj()
                if nb>2:
                    gauche("centaine","rien")
            if unites>0:
                for i in range (unites-10*dg):
                    coords_groupe=zone_princ.coords(objets_unites[-i])
                    cree("dizaine",10,"groupe")
                    zone_princ.delete(objets_unites[-i])
                objets_unites.clear()
                dg = dg + unites
                unites=dg*10
                maj()
                gauche("dizaine","rien")
        else:
            message("Déplacer d'abord les groupements\ndans les bonnes colonnes.")
        if nb==1:
            message("Pour multiplier par 10\npasser en mode 2,3 ou 4 colonnes.")
    else:
        message("Trop de blocs pour multiplier.")

def ajustey(objet):
    rectmarqueur = f"r{objet}"
    if objet in zone_princ.find_overlapping(0,centre_canvas_y,larg_canvas,centre_canvas_y):
        if zone_princ.coords(objet)[1] > centre_canvas_y:
            dy = centre_canvas_y - zone_princ.bbox(objet)[1] + larg_unite
        else:
            dy = centre_canvas_y - zone_princ.bbox(objet)[3] - larg_unite
        for i in range(30):
            zone_princ.move(objet, 0, dy / 30)
            zone_princ.move(rectmarqueur, 0, dy / 30)
            zone_princ.update()
            time.sleep(0.01)
def ajuste(objet):
    if nb>1:
        if objet in objets_dizgauche or objet in objets_dizaines:
            distance=larg_dizaine/2
        else:
            distance=60
        if objet in zone_princ.find_overlapping(zone_princ.coords("unites")[0] ,centre_canvas_y - distance,zone_princ.coords("unites")[0] + 70,centre_canvas_y + distance):
            rectmarqueur = f"r{objet}"
            if objet in objets_dizgauche or objet in objets_dizaines:
                dx=(zone_princ.coords("unites")[0] + 100)-zone_princ.bbox(objet)[0]
                if zone_princ.coords(objet)[1]<centre_canvas_y:
                    dy=-larg_unite
                else:
                    dy=larg_unite
                for i in range(30):
                    zone_princ.move(objet,dx/30,dy/30)
                    zone_princ.move(rectmarqueur, dx / 30, dy / 30)
                    zone_princ.update()
                    time.sleep(0.01)
            else:
                dx=(zone_princ.coords("unites")[0] + 100)-zone_princ.coords(objet)[0]
                for i in range(30):
                    zone_princ.move(objet,dx/30,0)
                    zone_princ.move(rectmarqueur, dx / 30, 0)
                    zone_princ.update()
                    time.sleep(0.01)

def update(self):
    val_m.configure(text=max_m.get())
    val_c.configure(text=max_c.get())
    val_d.configure(text=max_d.get())
    val_u.configure(text=max_u.get())

#Mode interroger : action du bouton "?"
def check():
    global ask
    if nombreinterro == nombre:
        modenormal()
        custom.configure(state=NORMAL)
        custom_ok.configure(state=NORMAL)
        choix_verr.configure(state=NORMAL)
        choixcol.configure(state=NORMAL)

    else:
        compteur.configure(background="red")
        zone_haut.after(1000,jaune)

def modenormal():
    global ask
    ask=0
    check_bouton.place_forget()
    cancel.place_forget()
    compteur.configure(text=nombre, background="#bdffd5", anchor=CENTER)

check_bouton=Button(zone_haut, text="ok", command=check, font=moyen, background="#69ff81", padx=2, width=3,height=1)
cancel=Button(zone_haut, text="x", command=modenormal, font=moyen, background="red", padx=2, width=3, height=1)



#Remise à zéro
def nouveau(nb):
    global nbcolonnes,larg_unite,larg_dizaine
    modenormal()
    nbcolonnes=int(nb)
    zone_princ.delete('all')
    for widget in zone_princ.winfo_children():
        widget.place_forget()
    for widget in zone_haut.winfo_children():
        widget.place_forget()
    init()
    reset("tout")
    if 1<nbcolonnes<4:
        max_m.grid_forget()
        val_m.grid_forget()
        titre_m.grid_forget()
    else:
        titre_m.grid(row=8, column=0, sticky='nesw')
        max_m.grid(row=9,column=0, pady=0, padx=0)
        val_m.grid(row=10, column=0, sticky='nesw')
    if 1<nbcolonnes<3:
        max_c.grid_forget()
        val_c.grid_forget()
        titre_c.grid_forget()
    else:
        titre_c.grid(row=8, column=1, sticky='nesw')
        max_c.grid(row=9,column=1, pady=0, padx=0)
        val_c.grid(row=10, column=1, sticky='nesw')
    if nbcolonnes==1:
        for i in liste_compteurs:
            i.place_forget()
        liste_compteurs.clear()


interu=interd=interc=interm=interg=1

choixcol=Scale(zone_gauche, orient='horizontal', borderwidth=0,highlightthickness=0, background=couleur,troughcolor=couleur_bouton, showvalue=0, from_=4, to=1, resolution=1, tickinterval=1, label='Colonnes',command=nouveau)
choixcol.set(2)
bal_choixcol = tix.Balloon(zone_gauche)
bal_choixcol.bind_widget(choixcol, msg='Choisir le nombre de colonnes\n2 : dizaines unités\n3 : centaines dizaines unités\n4 : milliers centaines dizaines unités\n1 : millliers centaines dizaines unités sans séparations')



variables=[1, 1, 0, 0, 1, 1, 1, 1, 1, 9, 9, 9, 9, 2, 2, 'jaune', 'jaune', 'jaune', 'jaune', 1, 1, 1, 1, 0, 1, 'deco']
#Récupération des variables utilisateur
if os.path.isfile(f"{my_datadir}/parametres.txt"):
    fichierSauvegarde = open(f"{my_datadir}/parametres.txt", "rb")
    sauv_variables = pickle.load(fichierSauvegarde)
    fichierSauvegarde.close()
    for i in range(len(sauv_variables)):
        variables[i]=sauv_variables[i]
    lignes.set(variables[0])
    peda.set(variables[1])
    ordre.set(variables[2])
    separations.set(variables[3])
    interg=(variables[4])
    interm=variables[5]
    interc=variables[6]
    interd=variables[7]
    interu=variables[8]
    max_m.set(variables[9])
    max_c.set(variables[10])
    max_d.set(variables[11])
    max_u.set(variables[12])
    choixcol.set(variables[13])
    nbcolonnes=nb=(variables[14])
    couleur_millier.set(variables[15])
    couleur_centaine.set(variables[16])
    couleur_dizaine.set(variables[17])
    couleur_unite.set(variables[18])
    couleurpeda.set(variables[19])
    cachecompteur.set(variables[20])
    montrecompteur.set(variables[21])
    limit.set(variables[22])
    razinterro.set(variables[23])
    interrocachecompteur.set(variables[24])
    choixcache.set(variables[25])
ok=1
l = 45
boutons=[]
maxu=maxd=maxc=maxm=9
larg_unite=45
larg_dizaine=450






#Création des zones milliers, centaines, dizaines, unités
liste_4=("milliers","centaines","dizaines","unites")
liste_3=("centaines","dizaines","unites")
liste_2=("dizaines","unites")

aff_compteur_unite = Button(zone_haut, image=img_oeil, borderwidth=0, highlightthickness=0, background=couleur, activebackground=couleur, command=lambda: affichage_compteur(aff_compteur_unite,compteur_unites,interu))
aff_compteur_dizaine = Button(zone_haut, image=img_oeil, borderwidth=0, highlightthickness=0, background=couleur, activebackground=couleur,command=lambda: affichage_compteur(aff_compteur_dizaine,compteur_dizaines,interd))
aff_compteur_centaine = Button(zone_haut, image=img_oeil, borderwidth=0, highlightthickness=0, background=couleur, activebackground=couleur,command=lambda: affichage_compteur(aff_compteur_centaine,compteur_centaines,interc))
aff_compteur_millier = Button(zone_haut, image=img_oeil, borderwidth=0, highlightthickness=0, background=couleur, activebackground=couleur,command=lambda: affichage_compteur(aff_compteur_millier,compteur_milliers,interm))
if interu==0:
    aff_compteur_unite.configure(image=img_oeil_inactif)
if interd==0:
    aff_compteur_dizaine.configure(image=img_oeil_inactif)
if interc==0:
    aff_compteur_centaine.configure(image=img_oeil_inactif)
if interm==0:
    aff_compteur_millier.configure(image=img_oeil_inactif)

titreu=Label(zone_haut, text="U",background=couleur,font=gros, justify=CENTER)
titred=Label(zone_haut, text="D",background=couleur,font=gros, justify=CENTER)
titrec=Label(zone_haut, text="C",background=couleur,font=gros, justify=CENTER)
titrem=Label(zone_haut, text="M",background=couleur,font=gros, justify=CENTER)


def switch_pleinecran():
    global pleinecran
    if fullscreen.get():
        quitter.place_forget()
        minimiser.place_forget()
        fenetre.attributes("-fullscreen", False)
        fullscreen.set(False)
        pleinecran.configure(image=img_pleinecran)
    else:
        fenetre.attributes("-fullscreen", True)
        fullscreen.set(True)
        pleinecran.configure(image=img_sortiepleinecran)
    maj_canvas()



def fermeture_generale():
    fenetre.destroy()

def annuler():
    boite.place_forget()

boite = Frame(fenetre,padx=20,pady=20,borderwidth=10, relief=RIDGE, background=couleur, highlightthickness=0)
confirmation = Label(boite, text="Quitter Tuxblocs ?", font=gros, background=couleur,pady=10)
confirmation_ok = Button(boite, text="oui", command=fermeture_generale, font=gros, pady=10, background=couleur_bouton)
confirmation_annuler = Button(boite, text="non", command=annuler, font=gros, pady=10, background=couleur_bouton)
logoquit=Label(boite,image=img_logo, pady=10)
#Sauvegarde des variables avant fermeture
def sauvegarde(mode):
    # Enregistrement des variables dans le fichier
    sauv_variables = [lignes.get(),peda.get(),ordre.get(),separations.get(),interg,interm,interc,interd,interu,max_m.get(),max_c.get(),max_d.get(),max_u.get(),choixcol.get(),nb,couleur_millier.get(),couleur_centaine.get(),couleur_dizaine.get(),couleur_unite.get(),couleurpeda.get(),cachecompteur.get(),montrecompteur.get(),limit.get(),razinterro.get(),interrocachecompteur.get(),choixcache.get()]
    fichierSauvegarde = open(f"{my_datadir}/parametres.txt", "wb")
    pickle.dump(sauv_variables, fichierSauvegarde)
    fichierSauvegarde.close()
    fenetre.update()
    if mode==quitter:
        boite.place(x=fenetre.winfo_width()/2,y=fenetre.winfo_height()/2, anchor=CENTER)
        confirmation.grid(row=0,column=0,columnspan=2)
        confirmation_ok.grid(row=1,column=0)
        confirmation_annuler.grid(row=1,column=1)
    else:
        fenetre.iconify()

#Gestion de l'affichage des compteurs
def affichage_compteur(bouton,type_compteur,inter):
    global interu, interd, interc, interm, interg
    if inter==1:
        if not ask==1 or not type_compteur==compteur:
            bouton.configure(image=img_oeil_inactif)
            type_compteur.place_forget()
            if type_compteur==compteur_unites:
                interu=0
            if type_compteur==compteur_dizaines:
                interd=0
            if type_compteur==compteur_centaines:
                interc=0
            if type_compteur==compteur_milliers:
                interm=0
            if type_compteur==compteur:
                interg=0
    else:
        bouton.configure(image=img_oeil)
        if type_compteur==compteur_unites:
            interu=1
            type_compteur.place(x=(liste_unite[0] + liste_unite[2]) / 2 + 100, y=80, anchor=CENTER)
        if type_compteur==compteur_dizaines:
            interd=1
            type_compteur.place(x=(liste_dizaine[0] + liste_dizaine[2]) / 2 + 100, y=80, anchor=CENTER)
        if type_compteur==compteur_centaines:
            interc=1
            type_compteur.place(x=(liste_centaine[0] + liste_centaine[2]) / 2 + 100, y=80, anchor=CENTER)
        if type_compteur==compteur_milliers:
            type_compteur.place(x=(liste_millier[0] + liste_millier[2]) / 2 + 100, y=80, anchor=CENTER)
            interm=1
        if type_compteur==compteur:
            interg=1
            compteur.place(x=5, y=50, anchor=W, width=150, height=80)
lock=0

quitter=Button(zone_haut,image=img_quitter, highlightthickness=0, relief="flat", background=couleur,command=lambda:sauvegarde(quitter))
minimiser=Button(zone_haut,image=img_reduire, highlightthickness=0, relief="flat", background=couleur,command=lambda:sauvegarde(minimiser))
pleinecran=Button(zone_haut,image=img_pleinecran, highlightthickness=0, background=couleur, highlightbackground='#fff',relief="flat",command=switch_pleinecran)
bouton_lock=0

#Gestion du cadenas (verrouillage du nombre)
def verr(self):
    global lock,bouton_lock
    if bouton_lock==0:
        if ask==0:
            lock=1
            for i in (boutons):
                i.configure(state=DISABLED)
        else:
            for i in (custom_ok,custom_interroger,custom,choixcol,cancel):
                i.configure(state=DISABLED)
        choix_verr.config(image=img_cadenas_ferme, background="#ff3649", activebackground="#ffc6cc")
        cancel.config(background="#ffecec")
        bouton_lock=1
    else:
        if ask==0:
            lock=0
            for i in (boutons):
                i.configure(state=NORMAL)
        else:
            for i in (custom_ok,custom_interroger,custom,choixcol,cancel):
                i.configure(state=NORMAL)
        choix_verr.config(image=img_cadenas_ouvert, background=couleur_bouton, activebackground="#ececec")
        cancel.config(background="red")
        bouton_lock=0


def change_compteur_sep(compteur):
    if compteur['image']:
        compteur['image'] = ''
        compteur['width'] = 2
    else:
        compteur['image'] = img_oeil_inactif
        compteur['width'] = 0
choix_verr=Button(zone_gauche, background=couleur_bouton,image=img_cadenas_ouvert, command=lambda: verr("self"))
bal_choix_verr = tix.Balloon(zone_gauche)
bal_choix_verr.bind_widget(choix_verr, msg='Verrouiller / Déverrouiller le nombre')

unites_bas=IntVar()
unites_haut=IntVar()
dizaines_bas=IntVar()
dizaines_haut=IntVar()
centaines_bas=IntVar()
centaines_haut=IntVar()
milliers_bas=IntVar()
milliers_haut=IntVar()
compteur_unites_bas=Button(zone_princ,textvariable=unites_bas, width=0, font=gros, background=couleur_bouton,image=img_oeil_inactif,command=lambda:change_compteur_sep(compteur_unites_bas))
compteur_unites_haut=Button(zone_princ,textvariable=unites_haut, width=0, font=gros, background=couleur_bouton,image=img_oeil_inactif,command=lambda:change_compteur_sep(compteur_unites_haut))
compteur_dizaines_bas=Button(zone_princ,textvariable=dizaines_bas, width=0,  font=gros, background=couleur_bouton,image=img_oeil_inactif,command=lambda:change_compteur_sep(compteur_dizaines_bas))
compteur_dizaines_haut=Button(zone_princ,textvariable=dizaines_haut, width=0,  font=gros, background=couleur_bouton,image=img_oeil_inactif,command=lambda:change_compteur_sep(compteur_dizaines_haut))
compteur_centaines_bas=Button(zone_princ,textvariable=centaines_bas, width=0,  font=gros, background=couleur_bouton,image=img_oeil_inactif,command=lambda:change_compteur_sep(compteur_centaines_bas))
compteur_centaines_haut=Button(zone_princ,textvariable=centaines_haut, width=0,  font=gros, background=couleur_bouton,image=img_oeil_inactif,command=lambda:change_compteur_sep(compteur_centaines_haut))
compteur_milliers_bas=Button(zone_princ,textvariable=milliers_bas, width=0,  font=gros, background=couleur_bouton,image=img_oeil_inactif,command=lambda:change_compteur_sep(compteur_milliers_bas))
compteur_milliers_haut=Button(zone_princ,textvariable=milliers_haut, width=0,  font=gros, background=couleur_bouton,image=img_oeil_inactif,command=lambda:change_compteur_sep(compteur_milliers_haut))

liste_separations=[]
liste_compteurs=[]
#Gestion des séparations horizontales
def change_separations():
    if separations.get()==1:
        posx = margex
        posy = margey
        if nb==2:
            liste=liste_2
        if nb==3:
            liste=liste_3
        if nb==4:
            liste=liste_4
        if nb==1:
            liste=["globale"]
            largeur=larg_canvas-2*margex
        else:
            largeur=larg_colonne
        centre = (larg_canvas/2,haut_canvas/2)
        for i in liste:
            zone_princ.create_polygon(posx, (centre[1]) - 5, posx + largeur - 5, (centre[1]) - 5,posx + largeur, (centre[1]), posx, (centre[1]), fill="#f6f6f6", width=0, tags="separation")
            liste_separations.append(zone_princ.create_polygon(posx, (centre[1]), posx + largeur, (centre[1]),posx + largeur, (centre[1])+5, posx, (centre[1])+5, fill=couleur, width=0, tags="separation"))
            posx = posx + margex + largeur
        if nb>1:
            if nb==2:
                xdiz=zone_princ.coords("dizaines")[2] - 20 - margex
                anchdiz="ne"
            else:
                xdiz=zone_princ.coords("dizaines")[0] + 20
                anchdiz = "nw"
            compteur_unites_bas.place(x=zone_princ.coords("unites")[0] + 20, y=centre[1] + 20)
            compteur_unites_haut.place(x=zone_princ.coords("unites")[0] + 20, y=centre[1] - 60)
            compteur_dizaines_bas.place(x=xdiz, y=centre[1] + 20,anchor=anchdiz)
            compteur_dizaines_haut.place(x=xdiz, y=centre[1] - 60,anchor=anchdiz)
            liste_compteurs.extend([compteur_dizaines_haut,compteur_dizaines_bas,compteur_unites_bas,compteur_unites_haut])
        if nb>=3:
            compteur_centaines_bas.place(x=zone_princ.coords("centaines")[0] + 20, y=centre[1] + 20)
            compteur_centaines_haut.place(x=zone_princ.coords("centaines")[0] + 20, y=centre[1] - 60)
            liste_compteurs.extend([compteur_centaines_bas,compteur_centaines_haut])
        if nb==4:
            compteur_milliers_bas.place(x=zone_princ.coords("milliers")[0] + 20, y=centre[1] + 20)
            compteur_milliers_haut.place(x=zone_princ.coords("milliers")[0] + 20, y=centre[1] - 60)
            liste_compteurs.extend([compteur_milliers_bas,compteur_milliers_haut])
        for i in [*objets_milliers,*objets_millgauche,*objets_centaines,*objets_centgauche,*objets_dizaines,*objets_dizgauche,*objets_unites]:
            ajustey(i)
    else:
        zone_princ.delete("separation")
        for i in liste_compteurs:
            i.place_forget()
        liste_compteurs.clear()


#Création des colonnes
def rectangles(mode):
    global larg_colonne, haut_canvas, haut_colonne
    posx = margex
    posy = margey
    fond1=zone_princ.create_rectangle(0,0,larg_canvas,margey, fill=couleur, width=0,tags="fond")
    fond2=zone_princ.create_rectangle(0,haut_canvas-margey,larg_canvas,haut_canvas, fill=couleur, width=0,tags="fond")
    fond3=zone_princ.create_rectangle(0,margey,margex,haut_canvas-margey, fill=couleur, width=0,tags="fond")
    for i in (mode):
        zone_princ.create_rectangle(posx,posy,larg_colonne+posx,haut_canvas-margey, fill="#fff", width=0,tags=(f"{i}","rectangle"))
        if not nb==1:
            zone_princ.create_rectangle(posx+larg_colonne-5, posy, larg_colonne + posx, haut_canvas - margey, fill="#878787", width=0, tags="deco")
            zone_princ.create_rectangle(posx + larg_colonne, posy, larg_colonne + posx+margex, haut_canvas - margey,fill=couleur, width=0, tags="deco")
            zone_princ.create_polygon(posx, haut_canvas-margey-5,posx+larg_colonne-5,haut_canvas-margey-5,posx+larg_colonne,haut_canvas-margey,posx,haut_canvas-margey, fill="#f6f6f6", width=0, tags="deco")
        posx=posx+margex+larg_colonne
    if nb == 1:
        posx = margex
        zone_princ.create_rectangle(posx, posy, larg_canvas - margex,haut_canvas - margey, fill="#fff", width=0, tags="liste_globale")
        zone_princ.create_rectangle(posx + larg_canvas - margex- 5, posy, larg_canvas-margex, haut_canvas - margey,fill="#878787", width=0, tags="deco")
        zone_princ.create_rectangle(posx + larg_canvas-margex, posy, larg_canvas-margex+5, haut_canvas - margey,fill=couleur, width=0, tags="deco")
        zone_princ.create_polygon(posx, haut_canvas - margey - 5, larg_canvas-margex-5, haut_canvas - margey - 5,larg_canvas-margex, haut_canvas - margey, posx, haut_canvas - margey, fill="#f6f6f6",
                                  width=0, tags="deco")
    for i in (mode):
        zone_princ.tag_lower(i)
    change_separations()
    zone_princ.tag_raise(fond1)
    zone_princ.tag_raise(fond2)
    zone_princ.tag_raise(fond3)

#Gestion des images des blocs selon les variables (couleur, taille, lignes)
def change_images():
    global larg_unite,larg_dizaine
    if int(nbcolonnes)==2:
        if larg_colonne<460 or haut_colonne<800:
            taille="moyennes"
            larg_unite=22.5
            larg_dizaine=225
        else:
            taille="grandes"
            larg_unite=45
            larg_dizaine=450
    elif int(nbcolonnes)==3:
        if larg_colonne<500:
            taille="petites"
            larg_unite=16
            larg_dizaine=150
        else:
            taille="moyennes"
            larg_unite=22.5
            larg_dizaine=225
    elif int(nbcolonnes)==1:
        if larg_colonne<800 or haut_colonne<800:
            taille="moyennes"
            larg_unite=22.5
            larg_dizaine=225
        else:
            taille="grandes"
            larg_unite=45
            larg_dizaine=450
    else:
        taille="petites"
        larg_unite=16
        larg_dizaine=150
    if lignes.get()==0:
        type="muet"
    else:
        type="lignes"
    img_unite.configure(file=f"images/{taille}/unite_{couleur_unite.get()}.png")
    img_dizaine.configure(file=f"images/{taille}/dizaine_{type}_{couleur_dizaine.get()}.png")
    img_centaine.configure(file=f"images/{taille}/centaine_{type}_{couleur_centaine.get()}.png")
    img_millier.configure(file=f"images/{taille}/millier_{type}_{couleur_millier.get()}.png")
    zone_princ.update()

img_cree=[]

select_unite = Button(zone_princ, image=img_grouper, command=lambda: groupe("unite", "bouton"), state=DISABLED)
select_dizaine = Button(zone_princ, image=img_grouper, command=lambda: groupe("dizaine", "bouton"), state=DISABLED)
select_centaine = Button(zone_princ, image=img_grouper, command=lambda: groupe("centaine", "bouton"), state=DISABLED)
degroupe_dizaine = Button(zone_princ, image=img_degrouper, command=lambda: degroupe("dizaine", "bouton"), state=DISABLED)
degroupe_unite = Button(zone_princ, image=img_degrouper, command=lambda: degroupe("unite", "bouton"), state=DISABLED)
degroupe_centaine = Button(zone_princ, image=img_degrouper, command=lambda: degroupe("centaine", "bouton"), state=DISABLED)


#Initialisation des éléments
def init():
    global cree_unite, cree_dizaine, cree_centaine, cree_millier, nb, larg_colonne, liste_millier, liste_centaine, liste_dizaine, liste_unite, haut_colonne, nombrexu, nombreyu, nombrezu, nombrexd, nombreyd, nombrezd, nombrexc, nombreyc, nombrezc, nombrexm, nombreym, nombrezm, centreu, centred, centrec, centrem, liste_globale, lignes, couleurs, ordre, separations, ok_maj_canvas
    nb=int(nbcolonnes)
    if interg==1:
        compteur.place(x=5, y=50, anchor=W, width=150, height=80)
    if fullscreen.get():
        quitter.place(x=larg, y=0, anchor=NE)
        minimiser.place(x=larg, y=42, anchor=NE)
        pleinecran.place(x=larg - 42, y=0, anchor=NE)
    else:
        pleinecran.place(x=larg, y=0, anchor=NE)
    boutons.append(quitter)
    compteur.configure(background="#bdffd5")
    img_cree.clear()
    haut_colonne = haut-100-2*margey
    if nb==1 and limit.get()==1:
        max_u.set(9)
        max_d.set(9)
        max_c.set(0)
        max_m.set(0)
    else:
        if "variables" in dir():
            max_m.set(variables[9])
            max_c.set(variables[10])
            max_d.set(variables[11])
            max_u.set(variables[12])
        else:
            max_c.set(9)
            max_m.set(9)
    if nb==4 or nb==1:
        larg_colonne = (larg_canvas - (5 * margex)) / 4
        rectangles(liste_4)
    if nb==3:
        larg_colonne = (larg_canvas - (4 * margex)) / 3
        rectangles(liste_3)
    if nb==2:
        larg_colonne = (larg_canvas - (3 * margex)) / 2
        rectangles(liste_2)
    change_images()
    nombrexu = 5
    nombreyu = (haut_colonne // (larg_colonne/6))
    nombrezu = nombrexu * nombreyu
    nombrexd = 2
    nombreyd = int((haut_colonne / (larg_colonne/12)))
    nombrezd = nombrexd*nombreyd
    nombrexc = int((larg_colonne / 160))
    nombreyc = int((haut_colonne / 160))
    nombrezc = nombrexc * nombreyc
    nombrexm = int((larg_colonne / 175))
    nombreym = int((haut_colonne / 90))
    nombrezm = (nombrexm * nombreym)-nombrexm
    if nb==4 or nb==1:
        liste_globale= zone_princ.coords("liste_globale")
        liste_millier = zone_princ.coords("milliers")
        liste_centaine = zone_princ.coords("centaines")
        range_milliers = Button(zone_princ, image=img_ranger, background=couleur_bouton, command=lambda: action_range("millier"))
        melange_milliers = Button(zone_princ, image=img_melanger, background=couleur_bouton,command=lambda: action_hasard("millier"))
        casse_millier = Button(zone_princ, text=">>>", background=couleur_bouton,command=lambda: casse("millier", milliers,"bouton"))
        bal_casse_millier = tix.Balloon(zone_princ)
        bal_casse_millier.bind_widget(casse_millier,msg="Casser les milliers marqués en rouge\nSi aucun millier n'est marqué, casser un seul millier")
        suppr_millier = Button(zone_haut, text="-", background=couleur_bouton,command=lambda: man_suppr("millier"))
        add_millier = Button(zone_haut, text="+", background=couleur_bouton,command=lambda: new("millier", 1000, "normal"))
        reset_millier = Button(zone_haut, image=img_minicorbeille, borderwidth=0, highlightthickness=0,background=couleur, activebackground=couleur, command=lambda: reset("millier"))
        groupe_centaines = Button(zone_princ, text="<<<", background=couleur_bouton,command=lambda: gauche("millier", centaines))
        bal_groupe_centaines = tix.Balloon(zone_princ)
        bal_groupe_centaines.bind_widget(groupe_centaines, msg="Faire passer les milliers marqués en rouge dans la colonne de gauche\nSi aucun millier n'est marqué, faire passer tous les milliers")
        reset_millier.place(x=(liste_millier[0] + liste_millier[2]) / 2 + 80, y=35, anchor=E)
        bal_reset_millier = tix.Balloon(zone_haut)
        bal_reset_millier.bind_widget(reset_millier, msg='Vider la colonne')
        aff_compteur_millier.place(x=(liste_millier[0] + liste_millier[2]) / 2 + 120, y=35, anchor=W)
        bal_aff_compteur_millier = tix.Balloon(zone_haut)
        bal_aff_compteur_millier.bind_widget(aff_compteur_millier, msg='Afficher / masquer le compteur des milliers')
        if interm==1:
            compteur_milliers.place(x = (liste_millier[0]+liste_millier[2])/2+100, y = 80, anchor=CENTER)
        if not nb==1:
            casse_millier.place(x=l+(liste_millier[0]+liste_millier[2])/2,y=haut_canvas-margey/2, anchor=W)
            groupe_centaines.place(x=((liste_centaine[0] + liste_centaine[2]) / 2)-l, y=haut_canvas - margey / 2, anchor=E)
        range_milliers.place(x=0.5*l+(liste_millier[0] + liste_millier[2]) / 2, y=(margey/2)+3, anchor=W)
        melange_milliers.place(x=1.5*l+(liste_millier[0] + liste_millier[2]) / 2, y=(margey/2)+3, anchor=W)
        add_millier.place(x=l+(liste_millier[0] + liste_millier[2]) / 2 + 100, y=75, anchor=CENTER)
        suppr_millier.place(x=((liste_millier[0] + liste_millier[2]) / 2)-l + 100, y=75, anchor=CENTER)
        cree_millier=zone_princ.create_image((liste_millier[0]+liste_millier[2])/2,margey / 2+3,image=img_cree_millier, activeimage=img_grab, tags="bouton_cree")
        img_cree.append(cree_millier)
        titrem.place(x=(liste_millier[0] + liste_millier[2]) / 2 + 100, y=40, anchor=CENTER)
        boutons.extend([add_millier,suppr_millier,reset_millier])
        centrem=(liste_millier[0]+larg_colonne/2,liste_millier[1]+haut_colonne/2)
        couleur_milliers = Menubutton(zone_princ, image=img_couleurs, direction='above')
        bal_couleur_milliers = tix.Balloon(zone_princ)
        bal_couleur_milliers.bind_widget(couleur_milliers, msg='Choisir la couleur des blocs milliers')
        couleur_milliers.place(x=((liste_millier[0] + liste_millier[2]) / 2), y=haut_canvas - margey / 2 - 3, anchor=CENTER)
        couleur_milliers.menu_couleur_milliers = Menu(couleur_milliers, tearoff=0)
        couleur_milliers["menu"] = couleur_milliers.menu_couleur_milliers
        couleur_milliers.menu_couleur_milliers.add_radiobutton(value="bleu", image=img_bleu, variable=couleur_millier, command=change_images, indicatoron=0, hidemargin=True)
        couleur_milliers.menu_couleur_milliers.add_radiobutton(value="jaune", image=img_jaune, variable=couleur_millier, command=change_images, indicatoron=0, hidemargin=True)
        couleur_milliers.menu_couleur_milliers.add_radiobutton(value="rouge", image=img_rouge, variable=couleur_millier, command=change_images, indicatoron=0, hidemargin=True)
        couleur_milliers.menu_couleur_milliers.add_radiobutton(value="vert", image=img_vert, variable=couleur_millier, command=change_images, indicatoron=0, hidemargin=True)
        couleur_milliers.menu_couleur_milliers.add_radiobutton(value="violet", image=img_violet, variable=couleur_millier,command=change_images, indicatoron=0, hidemargin=True)
        couleur_milliers.menu_couleur_milliers.add_radiobutton(value="orange", image=img_orange, variable=couleur_millier,command=change_images, indicatoron=0, hidemargin=True)
    if nb>=3 or nb==1:
        liste_centaine = zone_princ.coords("centaines")
        liste_dizaine = zone_princ.coords("dizaines")
        range_centaines = Button(zone_princ, image=img_ranger, background=couleur_bouton,command=lambda: action_range("centaine"))
        reset_centaine = Button(zone_haut, image=img_minicorbeille, borderwidth=0, highlightthickness=0, background=couleur, activebackground=couleur, command=lambda: reset("centaine"))
        bal_reset_centaine = tix.Balloon(zone_haut)
        bal_reset_centaine.bind_widget(reset_centaine, msg='Vider la colonne')
        casse_centaine = Button(zone_princ, text=">>>", background=couleur_bouton,command=lambda: casse("centaine", centaines,"bouton"))
        bal_casse_centaine = tix.Balloon(zone_princ)
        bal_casse_centaine.bind_widget(casse_centaine,msg="Casser les centaines marquées en rouge\nSi aucune centaine n'est marquée, casser une seule centaine")
        add_centaine = Button(zone_haut, text="+", background=couleur_bouton,command=lambda: new("centaine", 100, "normal"))
        suppr_centaine = Button(zone_haut, text="-", background=couleur_bouton,command=lambda: man_suppr("centaine"))
        if interc==1:
            compteur_centaines.place(x=(liste_centaine[0] + liste_centaine[2]) / 2 + 100, y=80, anchor=CENTER)
        suppr_centaine.place(x=((liste_centaine[0] + liste_centaine[2]) / 2)-l + 100, y=75, anchor=CENTER)
        melange_centaines = Button(zone_princ, image=img_melanger, background=couleur_bouton,command=lambda: action_hasard("centaine"))
        add_centaine.place(x=l+(liste_centaine[0] + liste_centaine[2]) / 2 + 100, y=75, anchor=CENTER)
        range_centaines.place(x=0.5*l+(liste_centaine[0] + liste_centaine[2]) / 2, y=(margey/2)+3, anchor=W)
        melange_centaines.place(x=1.5*l+(liste_centaine[0] + liste_centaine[2]) / 2, y=(margey/2)+3, anchor=W)
        groupe_dizaines = Button(zone_princ, text="<<<", background=couleur_bouton,command=lambda: gauche("centaine", dizaines))
        bal_groupe_dizaines = tix.Balloon(zone_princ)
        bal_groupe_dizaines.bind_widget(groupe_dizaines,msg="Faire passer les centaines marquées en rouge dans la colonne de gauche\nSi aucune centaine n'est marquée, faire passer toutes les centaines")
        cree_centaine=zone_princ.create_image((liste_centaine[0] + liste_centaine[2]) / 2, margey / 2+3,image=img_cree_centaine, activeimage=img_grab, tags="bouton_cree")
        img_cree.append(cree_centaine)
        couleur_centaines = Menubutton(zone_princ, image=img_couleurs, direction='above')
        bal_couleur_centaines = tix.Balloon(zone_princ)
        bal_couleur_centaines.bind_widget(couleur_centaines,msg='Choisir la couleur des blocs centaines')
        couleur_centaines.place(x=((liste_centaine[0] + liste_centaine[2]) / 2), y=haut_canvas - margey / 2 - 3, anchor=CENTER)
        couleur_centaines.menu_couleur_centaines = Menu(couleur_centaines, tearoff=0)
        couleur_centaines["menu"] = couleur_centaines.menu_couleur_centaines
        couleur_centaines.menu_couleur_centaines.add_radiobutton(value="bleu", image=img_bleu, variable=couleur_centaine, command=change_images, indicatoron=0, hidemargin=True)
        couleur_centaines.menu_couleur_centaines.add_radiobutton(value="jaune", image=img_jaune, variable=couleur_centaine, command=change_images, indicatoron=0, hidemargin=True)
        couleur_centaines.menu_couleur_centaines.add_radiobutton(value="rouge", image=img_rouge, variable=couleur_centaine, command=change_images, indicatoron=0, hidemargin=True)
        couleur_centaines.menu_couleur_centaines.add_radiobutton(value="vert", image=img_vert, variable=couleur_centaine, command=change_images, indicatoron=0, hidemargin=True)
        couleur_centaines.menu_couleur_centaines.add_radiobutton(value="violet", image=img_violet,variable=couleur_centaine, command=change_images,indicatoron=0, hidemargin=True)
        couleur_centaines.menu_couleur_centaines.add_radiobutton(value="orange", image=img_orange,variable=couleur_centaine, command=change_images,indicatoron=0, hidemargin=True)
        if not nb == 1:
            casse_centaine.place(x=l+(liste_centaine[0] + liste_centaine[2]) / 2, y=haut_canvas - margey / 2, anchor=W)
            groupe_dizaines.place(x=((liste_dizaine[0] + liste_dizaine[2]) / 2)-l, y=haut_canvas - margey / 2, anchor=E)
            degroupe_centaine.place(x=((liste_centaine[0] + liste_centaine[2]) / 2) - 0.5*l, y=margey / 2+3, anchor=E)
            select_centaine.place(x=(liste_centaine[0] + liste_centaine[2]) / 2 -1.5*l, y=margey / 2+3, anchor=E)
        reset_centaine.place(x=(liste_centaine[0] + liste_centaine[2]) / 2 + 80, y=35, anchor=E)
        aff_compteur_centaine.place(x=(liste_centaine[0] + liste_centaine[2]) / 2 + 120, y=35, anchor=W)
        bal_aff_compteur_centaine = tix.Balloon(zone_haut)
        bal_aff_compteur_centaine.bind_widget(aff_compteur_centaine, msg='Afficher / masquer le compteur des centaines')
        titrec.place(x=(liste_centaine[0] + liste_centaine[2]) / 2 + 100, y=40, anchor=CENTER)
        boutons.extend([add_centaine,suppr_centaine,reset_centaine,])
        centrec = [liste_centaine[0] + larg_colonne/2, liste_centaine[1] + haut_colonne / 2]

    #Dans tous les cas création des boutons dizaines et unités
    #Les positions
    liste_dizaine = zone_princ.coords("dizaines")
    liste_unite = zone_princ.coords("unites")
    centreu = (liste_unite[0] + larg_colonne/2, liste_unite[1] + haut_colonne / 2)
    centred = (liste_dizaine[0] + larg_colonne/2, liste_dizaine[1] + haut_colonne / 2)
    #Les boutons et les compteurs
    range_dizaines = Button(zone_princ, image=img_ranger, background=couleur_bouton,command=lambda: action_range("dizaine"))
    range_unites = Button(zone_princ, image=img_ranger, background=couleur_bouton,command=lambda: action_range("unite"))
    melange_dizaines = Button(zone_princ, image=img_melanger, background=couleur_bouton,command=lambda: action_hasard("dizaine"))
    melange_unites = Button(zone_princ, image=img_melanger, background=couleur_bouton,command=lambda: action_hasard("unite"))
    casse_dizaine = Button(zone_princ, text=">>>", background=couleur_bouton,command=lambda: casse("dizaine", dizaines,"bouton"))
    bal_casse_dizaine = tix.Balloon(zone_princ)
    bal_casse_dizaine.bind_widget(casse_dizaine,msg="Casser les dizaines marquées en rouge\nSi aucune dizaine n'est marquée, casser une seule dizaine")
    reset_unite = Button(zone_haut, image=img_minicorbeille, borderwidth=0, highlightthickness=0, background=couleur, activebackground=couleur, command=lambda: reset("unite"))
    groupe_unites = Button(zone_princ,text="<<<", background=couleur_bouton, command=lambda: gauche("dizaine", unites))
    bal_groupe_unites = tix.Balloon(zone_princ)
    bal_groupe_unites.bind_widget(groupe_unites,msg="Faire passer les dizaines marquées en rouge dans la colonne de gauche\nSi aucune dizaine n'est marquée, faire passer toutes les dizaines")
    suppr_unite = Button(zone_haut, text="-", background=couleur_bouton,command=lambda: man_suppr("unite"))
    suppr_dizaine = Button(zone_haut, text="-", background=couleur_bouton,command=lambda: man_suppr("dizaine"))
    reset_dizaine = Button(zone_haut, image=img_minicorbeille, highlightthickness=0, borderwidth=0, background=couleur, activebackground=couleur, command=lambda: reset("dizaine"))
    add_unite = Button(zone_haut, text="+", background=couleur_bouton,command=lambda: new("unite",  1, "normal"))
    add_dizaine = Button(zone_haut, text="+", background=couleur_bouton,command=lambda: new("dizaine", 10, "normal"))

    range_unites.place(x=l*0.5+(liste_unite[0] + liste_unite[2])/2, y=(margey/2)+3, anchor=W)
    range_dizaines.place(x=l*0.5+(liste_dizaine[0] + liste_dizaine[2]) / 2, y=(margey/2)+3, anchor=W)
    melange_unites.place(x=l*1.5+(liste_unite[0] + liste_unite[2])/2, y=(margey/2)+3, anchor=W)
    melange_dizaines.place(x=1.5*l+(liste_dizaine[0] + liste_dizaine[2]) / 2 , y=(margey/2)+3, anchor=W)
    add_unite.place(x=l+(liste_unite[0] + liste_unite[2]) / 2 + 100, y=75, anchor=CENTER)
    add_dizaine.place(x=l+(liste_dizaine[0] + liste_dizaine[2]) / 2 + 100, y=75, anchor=CENTER)
    suppr_unite.place(x=((liste_unite[0] + liste_unite[2]) / 2)-l + 100, y=75, anchor=CENTER)
    suppr_dizaine.place(x=((liste_dizaine[0] + liste_dizaine[2]) / 2)-l + 100, y=75, anchor=CENTER)
    reset_dizaine.place(x=(liste_dizaine[0] + liste_dizaine[2]) / 2 + 80, y=35, anchor=E)
    reset_unite.place(x=(liste_unite[0] + liste_unite[2]) / 2 + 80, y=35, anchor=E)
    bal_reset_dizaine = tix.Balloon(zone_haut)
    bal_reset_dizaine.bind_widget(reset_dizaine, msg='Vider la colonne')
    bal_reset_unite = tix.Balloon(zone_haut)
    bal_reset_unite.bind_widget(reset_unite, msg='Vider la colonne')
    aff_compteur_unite.place(x=(liste_unite[0] + liste_unite[2]) / 2 + 120, y=35, anchor=W)
    aff_compteur_dizaine.place(x=(liste_dizaine[0] + liste_dizaine[2]) / 2 + 120, y=35, anchor=W)
    bal_aff_compteur_unite = tix.Balloon(zone_haut)
    bal_aff_compteur_unite.bind_widget(aff_compteur_unite, msg='Afficher / masquer le compteur des unités')
    bal_aff_compteur_dizaine = tix.Balloon(zone_haut)
    bal_aff_compteur_dizaine.bind_widget(aff_compteur_dizaine, msg='Afficher / masquer le compteur des dizaines')
    if interd==1:
        compteur_dizaines.place(x=(liste_dizaine[0] + liste_dizaine[2]) / 2 + 100, y=80, anchor=CENTER)
    if interu==1:
        compteur_unites.place(x=(liste_unite[0] + liste_unite[2]) / 2 + 100, y=80, anchor=CENTER)
    titred.place(x=(liste_dizaine[0] + liste_dizaine[2]) / 2 + 100, y=40, anchor=CENTER)
    titreu.place(x=(liste_unite[0] + liste_unite[2]) / 2 + 100, y=40, anchor=CENTER)
    boutons.extend([add_unite,add_dizaine,suppr_unite,suppr_dizaine,reset_unite,reset_dizaine])
    couleur_unites=Menubutton(zone_princ, image=img_couleurs, direction='above')
    couleur_dizaines = Menubutton(zone_princ, image=img_couleurs, direction='above')
    bal_couleur_unites = tix.Balloon(zone_princ)
    bal_couleur_unites.bind_widget(couleur_unites, msg='Choisir la couleur des blocs unités')
    bal_couleur_dizaines = tix.Balloon(zone_princ)
    bal_couleur_dizaines.bind_widget(couleur_dizaines, msg='Choisir la couleur des blocs dizaines')
    couleur_unites.place(x=((liste_unite[0] + liste_unite[2]) / 2), y=haut_canvas - margey / 2 - 3, anchor=CENTER)
    couleur_dizaines.place(x=((liste_dizaine[0] + liste_dizaine[2]) / 2), y=haut_canvas - margey / 2 - 3, anchor=CENTER)
    masquer = Button(zone_princ, image=img_mask, highlightthickness=0, relief="flat", background=couleur,command=lambda: cache(1))
    masquer.place(x=larg_canvas-5, y=haut_canvas-5, anchor=SE)
    bal_masquer = tix.Balloon(zone_princ)
    bal_masquer.bind_widget(masquer, msg='Masquer / Dévoiler les blocs')
    couleur_unites.menu_couleur_unites = Menu(couleur_unites, tearoff=0)
    couleur_unites["menu"] = couleur_unites.menu_couleur_unites
    couleur_unites.menu_couleur_unites.add_radiobutton(value="bleu", image=img_bleu, variable=couleur_unite, command=change_images, indicatoron=0, hidemargin=True)
    couleur_unites.menu_couleur_unites.add_radiobutton(value="jaune", image=img_jaune, variable=couleur_unite, command=change_images, indicatoron=0, hidemargin=True)
    couleur_unites.menu_couleur_unites.add_radiobutton(value="rouge", image=img_rouge, variable=couleur_unite, command=change_images, indicatoron=0, hidemargin=True)
    couleur_unites.menu_couleur_unites.add_radiobutton(value="vert", image=img_vert, variable=couleur_unite, command=change_images, indicatoron=0, hidemargin=True)
    couleur_unites.menu_couleur_unites.add_radiobutton(value="violet", image=img_violet, variable=couleur_unite,command=change_images, indicatoron=0, hidemargin=True)
    couleur_unites.menu_couleur_unites.add_radiobutton(value="orange", image=img_orange, variable=couleur_unite,command=change_images, indicatoron=0, hidemargin=True)
    couleur_dizaines.menu_couleur_dizaines = Menu(couleur_dizaines, tearoff=0)
    couleur_dizaines["menu"] = couleur_dizaines.menu_couleur_dizaines
    couleur_dizaines.menu_couleur_dizaines.add_radiobutton(value="bleu", image=img_bleu, variable=couleur_dizaine, command=change_images, indicatoron=0, hidemargin=True)
    couleur_dizaines.menu_couleur_dizaines.add_radiobutton(value="jaune", image=img_jaune, variable=couleur_dizaine, command=change_images, indicatoron=0, hidemargin=True)
    couleur_dizaines.menu_couleur_dizaines.add_radiobutton(value="rouge", image=img_rouge, variable=couleur_dizaine, command=change_images, indicatoron=0, hidemargin=True)
    couleur_dizaines.menu_couleur_dizaines.add_radiobutton(value="vert", image=img_vert, variable=couleur_dizaine, command=change_images, indicatoron=0, hidemargin=True)
    couleur_dizaines.menu_couleur_dizaines.add_radiobutton(value="violet", image=img_violet, variable=couleur_dizaine,command=change_images, indicatoron=0, hidemargin=True)
    couleur_dizaines.menu_couleur_dizaines.add_radiobutton(value="orange", image=img_orange, variable=couleur_dizaine,command=change_images, indicatoron=0, hidemargin=True)
    if not nb==1:
        casse_dizaine.place(x=((liste_dizaine[0] + liste_dizaine[2]) / 2)+l, y=haut_canvas - margey / 2, anchor=W)
        groupe_unites.place(x=((liste_unite[0] + liste_unite[2]) / 2)-l, y=haut_canvas - margey /2, anchor=E)
        degroupe_unite.place(x=((liste_unite[0] + liste_unite[2]) / 2) -0.5*l, y=margey / 2+3, anchor=E)
        select_unite.place(x=(liste_unite[0] + liste_unite[2]) / 2 - 1.5*l, y=margey / 2+3, anchor=E)
        select_dizaine.place(x=(liste_dizaine[0] + liste_dizaine[2]) / 2 -1.5*l, y=margey / 2+3, anchor=E)
        degroupe_dizaine.place(x=((liste_dizaine[0] + liste_dizaine[2]) / 2) - 0.5*l, y=margey / 2+3, anchor=E)
    cree_dizaine=zone_princ.create_image((liste_dizaine[0] + liste_dizaine[2]) / 2, margey / 2+3,image=img_cree_dizaine, activeimage=img_grab, tags="bouton_cree")
    cree_unite=zone_princ.create_image((liste_unite[0] + liste_unite[2]) / 2, margey / 2+3,image=img_cree_unite, activeimage=img_grab, tags="bouton_cree")
    img_cree.append(cree_dizaine)
    img_cree.append(cree_unite)


def jaune():
    compteur.configure(background="yellow")


ask=0

#Mise à jour des affichages des compteurs
def maj():
    global tropde, nombre, ask, unites_bas
    nb=int(nbcolonnes)
    nombre=(1000*milliers)+(100*centaines)+(10*dizaines)+unites
    if unites>9 or (dizaines>9 and not nb==2) or (centaines>9 and not nb==3):
        if unites>9:
            if couleurpeda.get()==1:
                zone_princ.itemconfigure("unites", fill="#feb7b7")
            else:
                zone_princ.itemconfigure("unites", fill=normal)
            if peda.get()==1 and ask==0:
                compteur.configure(text="")
            elif ask==0:
                compteur.configure(text=nombre)
        else:
            zone_princ.itemconfigure("unites",  fill=normal)
        if dizaines>9 and (nb>2 or nb==1):
            if couleurpeda.get() == 1:
                zone_princ.itemconfigure("dizaines",  fill="#feb7b7")
            else:
                zone_princ.itemconfigure("dizaines", fill=normal)
            if peda.get() == 1 and ask==0:
                compteur.configure(text="")
            elif ask==0:
                compteur.configure(text=nombre)
        else:
            zone_princ.itemconfigure("dizaines",  fill=normal)
        if centaines>9 and (nb>3 or nb==1):
            if couleurpeda.get() == 1:
                zone_princ.itemconfigure("centaines",  fill="#feb7b7")
            else:
                zone_princ.itemconfigure("centaines", fill=normal)
            if peda.get() == 1 and ask==0:
                compteur.configure(text="")
            elif ask==0:
                compteur.configure(text=nombre)
        else:
            zone_princ.itemconfigure("centaines",  fill=normal)
    else:
        if unites<10:
            zone_princ.itemconfigure("unites",  fill=normal)
        if dizaines<10:
            zone_princ.itemconfigure("dizaines", fill=normal)
        if centaines<10:
            zone_princ.itemconfigure("centaines", width=0,  fill=normal)
        if ask==0:
            compteur.configure(text=nombre)

    if nb == 4 or nb == 1:
        compteur_milliers.configure(text=milliers)
    if nb >= 3 or nb == 1:
        compteur_centaines.configure(text=centaines)
    compteur_dizaines.configure(text=dizaines)
    compteur_unites.configure(text=unites)
    if len(objets_unites)>9:
        select_unite.configure(state=NORMAL)
    else:
        select_unite.configure(state=DISABLED)
    if len(objets_dizaines)>9:
        select_dizaine.configure(state=NORMAL)
    else:
        select_dizaine.configure(state=DISABLED)
    if len(objets_centaines)>9:
        select_centaine.configure(state=NORMAL)
    else:
        select_centaine.configure(state=DISABLED)
    if dg>0:
        degroupe_unite.configure(state=NORMAL)
    else:
        degroupe_unite.configure(state=DISABLED)
    if cg>0:
        degroupe_dizaine.configure(state=NORMAL)
    else:
        degroupe_dizaine.configure(state=DISABLED)
    if mg>0:
        degroupe_centaine.configure(state=NORMAL)
    else:
        degroupe_centaine.configure(state=DISABLED)
    maj_compteurs_sep()

def maj_compteurs_sep():
    if separations.get()==1 and nb>=1:
        objets_zone_unites_bas=list(zone_princ.find_enclosed(liste_unite[0], centre_canvas_y-larg_unite/2, liste_unite[2],liste_unite[3]))
        unites_bas.set(len([value for value in objets_unites if value in objets_zone_unites_bas])+len([value for value in objets_dizgauche if value in objets_zone_unites_bas])*10)
        unites_haut.set(unites-unites_bas.get())
        objets_zone_dizaines_bas = list(zone_princ.find_enclosed(liste_dizaine[0], centre_canvas_y-larg_unite/2, liste_dizaine[2], liste_dizaine[3]))
        dizaines_bas.set(len([value for value in objets_dizaines if value in objets_zone_dizaines_bas]) + len([value for value in objets_centgauche if value in objets_zone_dizaines_bas]) * 10)
        dizaines_haut.set(dizaines - dizaines_bas.get())
        if nb>=3:
            objets_zone_centaines_bas = list(zone_princ.find_enclosed(liste_centaine[0], centre_canvas_y - larg_dizaine/ 2, liste_centaine[2],liste_centaine[3]))
            centaines_bas.set(len([value for value in objets_centaines if value in objets_zone_centaines_bas]) + len([value for value in objets_millgauche if value in objets_zone_centaines_bas]) * 10)
            centaines_haut.set(centaines - centaines_bas.get())
        if nb==4:
            objets_zone_milliers_bas = list(zone_princ.find_enclosed(liste_millier[0], centre_canvas_y - larg_dizaine, liste_millier[2],liste_millier[3]))
            milliers_bas.set(len([value for value in objets_milliers if value in objets_zone_milliers_bas]))
            milliers_haut.set(milliers - milliers_bas.get())

#Suppression de tous les objets et remise à zéro
def reset(objet):
    global nombre, milliers, centaines, dizaines, unites, objets_milliers, objets_centaines, objets_dizaines, objets_unites, dg,cg,mg
    if lock==0:
        if objet=="millier":
            for i in markm:
                milliers = milliers - 1
                nombre = nombre - 1000
                objets_milliers.remove(i)
                name = f"r{i}"
                zone_princ.delete(name)
                zone_princ.delete(i)
            markm.clear()
            zone_princ.delete("millier")
            objets_milliers.clear()
            milliers=0
        if objet=="centaine":
            for i in markc:
                centaines = centaines - 1
                nombre = nombre - 100
                objets_centaines.remove(i)
                name = f"r{i}"
                zone_princ.delete(name)
                zone_princ.delete(i)
            for i in markmg:
                name=f"r{i}"
                zone_princ.delete(name)
            markc.clear()
            zone_princ.delete("centaine")
            zone_princ.delete("millgauche")
            objets_centaines.clear()
            objets_millgauche.clear()
            centaines=0
            mg=0
        if objet=="dizaine":
            for i in markd:
                dizaines = dizaines - 1
                nombre = nombre - 10
                objets_dizaines.remove(i)
                name = f"r{i}"
                zone_princ.delete(name)
                zone_princ.delete(i)
            for i in markcg:
                name=f"r{i}"
                zone_princ.delete(name)
            markd.clear()
            zone_princ.delete("dizaine")
            zone_princ.delete("centgauche")
            objets_dizaines.clear()
            objets_centgauche.clear()
            dizaines=0
            cg=0
        if objet=="unite":
            for i in marku:
                unites = unites - 1
                nombre = nombre - 1
                objets_unites.remove(i)
                name = f"r{i}"
                zone_princ.delete(name)
                zone_princ.delete(i)
            for i in markdg:
                name=f"r{i}"
                zone_princ.delete(name)
            marku.clear()
            zone_princ.delete("unite")
            zone_princ.delete("dizgauche")
            objets_unites.clear()
            objets_dizgauche.clear()
            unites = 0
            dg = 0

        if objet=="tout":
            zone_princ.delete("millier")
            zone_princ.delete("centaine")
            zone_princ.delete("centgauche")
            zone_princ.delete("dizaine")
            zone_princ.delete("dizgauche")
            zone_princ.delete("unite")
            zone_princ.delete("millgauche")
            objets_milliers.clear()
            objets_centaines.clear()
            objets_dizaines.clear()
            objets_unites.clear()
            objets_dizgauche.clear()
            objets_centgauche.clear()
            objets_millgauche.clear()
            marku.clear()
            for i in rect_rouge:
                zone_princ.delete(i)
            rect_rouge.clear()
            milliers=centaines=dizaines=unites=0
            mg=cg=dg=0
        nombre=1000*milliers+100*centaines+10*dizaines+unites
        maj()

#Fenêtre à propos
def apropos():
    if not aproposouverte.get():
        aproposouverte.set(True)
        fen_apropos = Toplevel(fenetre)
        fen_apropos.title('À propos')
        if fullscreen.get():
            fen_apropos.attributes("-fullscreen", 1)
        else:
            if sys.platform == "linux":
                fen_apropos.attributes("-zoomed", 1)
            else:
                fen_apropos.state('zoomed')
        fen_apropos.configure(background=couleur)
        global lock
        lock = 1
        def fermeture():
            global lock
            lock = 0
            fenetre.bind_all('<Escape>', lambda event: sauvegarde(quitter))
            fen_apropos.destroy()

        def libere(event=None):
            aproposouverte.set(False)
        logo = Label(fen_apropos, background=couleur, image=img_logo)
        logo.place(x=50, y=haut, anchor=S)
        fen_apropos.bind_all('<Escape>', lambda event: fermeture())
        quitter = Button(fen_apropos, background=couleur, highlightthickness=0, image=img_quitter, relief="flat", command=fermeture)
        quitter.place(x=larg - 15, y=0, anchor=NE)
        titre_aide = Label(fen_apropos, background=couleur, text="À propos", font=tres_gros, pady=20)
        titre_aide.pack()
        barre = Scrollbar(fen_apropos)
        texte_manuel = Text(fen_apropos, height=300, width=600, background='#fff')
        barre.pack(side=RIGHT, fill=Y)
        texte_manuel.pack(side=LEFT, fill=Y, padx=50, pady=120)
        barre.config(command=texte_manuel.yview)
        texte_manuel.config(yscrollcommand=barre.set, wrap=WORD,tabs=('2c', '4.5c', 'right', '9c', 'center', '13c', 'numeric'), padx=20, pady=4)
        quote = """
    Tuxblocs, anciennement "Numération" est un logiciel qui permet de représenter les milliers, centaines, dizaines et unités sous fomes de blocs de base, et d'effectuer des conversions entre colonnes.
    
    Il ne s'agit pas d'un exerciseur autonome pour l'élève, mais d'un outil polyvalent de maniupulation d'objets pour l'enseignant(e), comme on le ferait avec des vrais blocs de numération, avec comptage automatique et affichage des valeurs numériques. Les différents modes et options permettent d'adapter le comportement du logiciel selon le scénario de séance souhaité.
    
    Il est développé  par Arnaud Champollion et partagé sous licence libre GNU/GPL.
    
    Ceci est la version 4.0
    
    Le code source est hébergé sur la forge des Communs Numériques : https://forge.apps.education.fr/
    
    Une forge est un outil facilitant l'édition et le suivi de projets collaboratifs. Il est possible depuis la page du projet de télécharger les versions éxécutables de Tuxblocs, mais également :
    - de consulter et télécharger le code source (la "recette" du logiciel).
    - de participer à son amélioration
    
    Il n'est pas nécessaire de savoir coder pour participer. Le développement d'un logiciel nécessite bien d'autres choses : relectures, traductions, documentation, tests, distribution, graphismes...
    
    Sur https://forge.apps.education.fr/ vous pouvez rédiger des "issues", ou "tickets" pour décrire des bugs rencontrés, ou bien encore des idées de nouvelles fonctionnalités.
    """
        texte_manuel.insert(END, quote)
        texte_manuel.config(state=DISABLED)
        fen_apropos.bind_all('<Destroy>', libere)
        fen_apropos.mainloop()
def change_choixcache():
    if choixcache.get()=="deco":
        zone_princ.dtag("rideau","rideaucache")
    else:
        zone_princ.dtag("rideau", "deco")
    zone_princ.addtag_withtag(choixcache.get(),"rideau")

def options():
    if not optionsouverte.get():
        optionsouverte.set(True)
    global lock
    lock=1
    fen_options = Toplevel(fenetre)
    if fullscreen.get():
        fen_options.attributes("-fullscreen", 1)
    else:
        if sys.platform == "linux":
            fen_options.attributes("-zoomed", 1)
        else:
            fen_options.state('zoomed')
    fen_options.title('Options')
    fen_options.configure(background=couleur)
    def fermeture():
        global lock
        lock = 0
        maj()
        fenetre.bind_all('<Escape>', lambda event: sauvegarde(quitter))
        fen_options.destroy()

    def libere(event=None):
        optionsouverte.set(False)

    logo = Label(fen_options, background=couleur, image=img_logo)
    logo.place(x=50, y=haut, anchor=S)
    fen_options.bind_all('<Escape>', lambda event: fermeture())
    titre_options=Label(fen_options,text="Options",font=tres_gros,background=couleur, pady=15)
    titre_options.pack()
    zone_options=Frame(fen_options,background=couleur)
    zone_options.pack()
    options_generales=LabelFrame(zone_options, text="Options générales", background=couleur,font=moyen)
    options_generales.grid(row=0,column=0)
    choixlignes=Checkbutton(options_generales, background=couleur, variable=lignes, highlightthickness=0,onvalue = 1, offvalue = 0, font=moyen, text='Afficher les détails des unités dans les dizaines, les détails des dizaines dans les centaines...', command=change_images)
    choixlignes.grid(row=5,column=0, sticky='w', pady=2, columnspan=4)
    choixrange=Checkbutton(options_generales, background=couleur, variable=ordre, highlightthickness=0, onvalue = 1, offvalue = 0, font=moyen, text='Ranger les blocs à mesure de leur apparition')
    choixrange.grid(row=7,column=0, sticky='w', pady=2, columnspan=4)
    choixcompteurpeda=Checkbutton(options_generales, background=couleur, highlightthickness=0, variable=peda, onvalue = 1, offvalue = 0, font=moyen, text='Masquer le compteur général si une colonne dépasse 9')
    choixcompteurpeda.grid(row=9,column=0, sticky='w', pady=2, columnspan=4)
    choixcouleurpeda=Checkbutton(options_generales, background=couleur, variable=couleurpeda, highlightthickness=0, onvalue = 1, offvalue = 0, font=moyen, text='Signaler en rose les colonnes dont la valeur dépasse 9')
    choixcouleurpeda.grid(row=11,column=0, sticky='w', pady=2, columnspan=4)
    choixblocsrideau = Checkbutton(options_generales, background=couleur, variable=choixcache, highlightthickness=0, onvalue="rideaucache", offvalue="deco",font=moyen, text='Masquer uniquement les blocs déjà présents avec le cache', command=change_choixcache)
    choixblocsrideau.grid(row=13, column=0, sticky='w', pady=2, columnspan=4)
    w = options_generales.winfo_width()

    options_tirage=LabelFrame(zone_options, background=couleur, text="Affichage aléatoire de blocs", font=moyen, width=w)
    options_tirage.grid(row=1,column=0,sticky='nsew',pady=10)

    illustration_options_tirage = Label(options_tirage, background=couleur,image=img_hasard)
    illustration_options_tirage.grid(row=0,column=0,rowspan=2)
    choixcachecompteur=Checkbutton(options_tirage, background=couleur, variable=cachecompteur, highlightthickness=0, onvalue = 1, offvalue = 0, font=moyen, text="Masquer automatiquement tous les compteurs")
    choixcachecompteur.grid(row=0,column=1, sticky='w', pady=5, columnspan=4)
    choixlimit = Checkbutton(options_tirage, background=couleur, highlightthickness=0, variable=limit, onvalue=1, offvalue=0, font=moyen,text='Limiter automatiquement à 99 en mode "une colonne"')
    choixlimit.grid(row=1, column=1, sticky='w', pady=5, columnspan=4)

    options_choix=LabelFrame(zone_options, highlightthickness=0,background=couleur, text="Affichage d'un nombre choisi de blocs", font=moyen, width=w)
    options_choix.grid(row=2,column=0,sticky='nsew',pady=10)

    illustration_options_choix = Label(options_choix, background=couleur, highlightthickness=0, image=img_teacher)
    illustration_options_choix.grid(row=0, column=0)
    choixcachecompteur = Checkbutton(options_choix, background=couleur, highlightthickness=0, variable=montrecompteur, onvalue=1, offvalue=0, font=moyen,text="Montrer automatiquement tous les compteurs")
    choixcachecompteur.grid(row=0, column=1, sticky='w', pady=5, columnspan=4)

    options_interro = LabelFrame(zone_options, background=couleur, highlightthickness=0, text="Interrogation sur un nombre (choisi ou aléatoire)", font=moyen, width=w)
    options_interro.grid(row=3, column=0, sticky='nsew', pady=10)

    illustration_options_interro = Label(options_interro, background=couleur, highlightthickness=0, image=img_teacher2)
    illustration_options_interro.grid(row=0, column=0)
    illustration_options_interro2 = Label(options_interro, background=couleur, highlightthickness=0, image=img_hasard2)
    illustration_options_interro2.grid(row=1, column=0)
    choixinit = Checkbutton(options_interro, background=couleur, variable=razinterro, highlightthickness=0, onvalue=1, offvalue=0, font=moyen,text="Supprimer les blocs déjà présents et mettre les compteurs à zéro")
    choixinit.grid(row=0, column=1, sticky='w', pady=5, columnspan=4)
    choixinterrocachecompteur = Checkbutton(options_interro, background=couleur,  highlightthickness=0,variable=interrocachecompteur, onvalue=1, offvalue=0, font=moyen,text="Masquer automatiquement les compteurs des colonnes")
    choixinterrocachecompteur.grid(row=1, column=1, sticky='w', pady=5, columnspan=4)

    fen_options.update()

    raz=LabelFrame(zone_options, background=couleur, highlightthickness=0, text="Paramètres standard", font=moyen, width=w)
    raz.grid(row=4,column=0,sticky='nsew',pady=10)
    raz_usine=Button(raz, background=couleur, highlightthickness=0, font=moyen, text='Restaurer les paramètres',command=standard)
    raz_usine.grid(row=5,column=0, sticky='w', pady=5, padx=5, columnspan=4)
    raz_usine_warning=Label(raz, background=couleur, highlightthickness=0,text="Réinitialise toutes les options en configuration d'usine et vide toutes les colonnes", font=moyen)
    raz_usine_warning.grid(row=6,column=0, sticky='w', pady=5, padx=5, columnspan=4)

    quitter = Button(fen_options, image=img_quitter, relief="flat",  background=couleur, highlightthickness=0, command=fermeture)
    quitter.place(x=larg, y=0, anchor=NE)
    fen_options.bind_all('<Destroy>', libere)
    fen_options.mainloop()


#Fenêtre d'aide
def aide():
    if not aideouverte.get():
        aideouverte.set(True)
        fen_aide = Toplevel(fenetre)
        fen_aide.title('Aide')
        if fullscreen.get():
            fen_aide.attributes("-fullscreen", 1)
        else:
            if sys.platform == "linux":
                fen_aide.attributes("-zoomed", 1)
            else:
                fen_aide.state('zoomed')
        fen_aide.configure(background=couleur)
        global lock
        lock=1
        def fermeture():
            global lock
            lock = 0
            fenetre.bind_all('<Escape>', lambda event: sauvegarde(quitter))
            fen_aide.destroy()
        def libere(event=None):
            aideouverte.set(False)

        logo = Label(fen_aide, background=couleur, image=img_logo)
        logo.place(x=50, y=haut, anchor=S)
        fen_aide.bind_all('<Escape>', lambda event: fermeture())
        quitter = Button(fen_aide, background=couleur,highlightthickness=0, image=img_quitter, relief="flat", command=fermeture)
        quitter.place(x=larg-15,y=0, anchor=NE)
        titre_aide=Label(fen_aide, background=couleur, text="Manuel", font=tres_gros, pady=20)
        titre_aide.pack()
        barre=Scrollbar(fen_aide)
        texte_manuel=Text(fen_aide, height=300, width=600, background='#fff')
        barre.pack(side=RIGHT, fill=Y)
        texte_manuel.pack(side=LEFT, fill=Y, padx=50, pady=120)
        barre.config(command=texte_manuel.yview)
        texte_manuel.config(yscrollcommand=barre.set, wrap=WORD,tabs=('2c', '4.5c', 'right', '9c', 'center', '13c', 'numeric'), padx=20, pady=4)
        quote = """Pour afficher rapidement cette aide, utilisez la touche F1 de votre clavier.
        
    Le compteur général affichera le nombre total de cubes, du moment que chaque colonne ne contient pas plus de 9 objets. En cas de dépassement, il n'affichera à nouveau le nombre que lorsque les groupements et déplacements auront été effectués.
        
    Pour ajouter un millier, une centaine, une dizaine, une unité :
    - cliquer sur le bouton + de la colonne correspondante
    - ou bien utiliser la molette de la souris en se plaçant dans la colonne souhaitée
    - ou bien utiliser les raccourcis clavier : "m,c,d,u"
    - ou encore faire glisser un nouvel objet depuis le bouton correspondant (étoile rouge)
    
    Pour supprimer un millier, une centaine, une dizaine, une unité (ou un groupe, si marqué - voir plus bas) :
    - cliquer sur le bouton - de la colonne correspondante
    - ou bien utiliser la molette de la souris en se plaçant dans la colonne souhaitée
    - ou bien utiliser les raccourcis clavier : "ctrl m,, ctr c, ctrl d,ctrl u"
    - ou encore faire glisser l'objet en dehors de la zone de travail
    
    NB : si des objets sont marqués, l'utilisation du bouton "-", de la molette de la souris ou du raccourci clavier correspondant aura pour effet de supprimer tous les objets marqués de la colonne.
    Par exemple si 3 unités sont marquées, un clic sur le bouton "-" de la colonne des unités les supprimera d'un seul coup.
    
    Pour grouper des unités, dizaines ou centaines :
    - cliquer sur le bouton "grouper" situé en haut de la colonne.
    NB : si des objets sont marqués, ils ne seront groupés qu'à condition d'être 10.
    - ou bien dessiner un rectangle englobant au moins 10 objets
    
    Pour dégrouper des milliers, centaines ou dizaines :
    - cliquer sur le bouton "dégrouper" situé en haut de la colonne.
    - ou bien double-cliquer sur l'objet.
    
    Pour déplacer un groupe vers la colonne de gauche :
    - utiliser le bouton <<< situé en bas.
    - ou bien le faire glisser dans la colonne de gauche
    
    Pour casser un millier, une centaine ou une dizaine :
    - cliquer sur le bouton >>> en bas de la colonne correspondante.
    - ou bien double-cliquer sur l'objet.
    - ou encore le faire glisser dans la colonne de droite.
    
    Pour déplacer un objet, il suffit de cliquer dessus, de maintenir le bouton de la souris enfoncé et de déplacer le pointeur, en mode "déposer - glisser". Ce fonctionnement est inhibé en mode "marqueur" (voir plus bas).
    
    Pour marquer des objets, maintenir la touche "Maj" et cliquer sur un objet ou dessiner un rectangle autour d'un groupe d'objets.
    Il est possible également de basculer en mode "marqueur" via le bouton dédié (représentant une unité encadrée de rouge) ou encore par le raccourci clavier "S". La touche "Maj" fonctionnera alors dans l'autre sens, permettant de réaliser ponctuellement les actions du mode "normal".
    Les objets marqués peuvent être supprimés au moyen du bouton "-" (moins) de la colonne correspondante, ou bien via le raccourci clavier "Suppr".
    
    Pour masquer un compteur particulier ou le compteur général, cliquer sur le bouton en forme d'oeil. Il n'est pas possible de masquer le compteur général en mode "interrogation".
    Pour masquer ou montrer tous les compteurs, utiliser la touche "V" (voir) du clavier.
    
    Pour remettre à zéro une colonne ou l'ensemble, utiliser les boutons corbeille. Raccourci clavier : touche Espace pour la corbeille générale.
    
    Pour verrouiller la somme, cliquer sur le bouton "cadenas" à gauche. Cela a pour effet d'empêcher toute création ou suppression ayant pour effet de modifier le nombre total. Les remises à zéro (corbeille), modifications du nombre de colonnes, tirage aléatoire et bouton "quitter" sont également désactivés.
    En mode "interrogation", le verrouillage n'empêche pas de modifier le nombre :  seulement de changer de mode ou de tirer un nouveau nombre.
    
    Le bouton "Au hasard" affiche un nombre aléatoire de milliers, centaines, dizaines, unités (selon le nombre de colonnes actives). Les curseurs verticaux permettent de définir un nombre maximum pour chacune.
    
    Pour modifier les couleurs des blocs, cliquer sur le sélecteur situé en bas de chaque colonne.
    
    Pour afficher une séparation horizontale, cliquer sur le bouton "séparations".
    
    Il est possible d'entrer directement un nombre (maximum 9999) dans la zone de saisie située tout à gauche.
    - le bouton "afficher" créera les objets correspondants et mettra les compteurs à jour,
    - le bouton "interroger" affichera le nombre saisi dans le compteur, (selon options, sans mettre à jour les blocs). L'élève devra alors réaliser les modifications nécessaires puis cliquer suer le point d'interrogation situé sur le compteur pour valider.
    
    Pour quitter le mode interroger :
    - placer la bonne quantité de blocs et valider avec "OK"
    - ou utiliser le bouton rouge "x" (désactivé lors du verrouillage)
    - ou effectuer un changement de mode (colonnes ou blocs aléatoires) (désactivé lors du verrouillage)
    
    Raccourcis clavier :
        
    u : ajouter une unité
    d : ajouter une dizaine
    c: ajouter une centaine
    m : ajouter un millier
    Ctrl u : supprimer une unité
    Ctrl d : supprimer une dizaine
    Ctrl c: supprimer une centaine
    Ctrl m : supprimer un millier
    
    Barre espace : supprimer tout
    Suppr : supprimer les blocs marqués
    
    v : voir / cacher tous les compteurs (sauf compteur principal en mode "interroger")
    b : voir / masquer les blocs
    r : ranger tous les blocs
    t : tirer un nombre au hasard (cache les compteurs)
    l : verrouiller / déverrouiller le nombre (empêche d'ajouter ou de supprimer des blocs, désactive les boutons corbeille, hasard et colonnes). En mode "interrogation", le verrouillage empêche seulement de changer de mode ou de tirer un nouveau nombre.
    s : basculer le fonctionnement de la souris (mode marqueur / mode normal)
    x : multiplier par 10 (hors mode "1 colonne")
    Page Down : afficher une quantité de blocs choisie (si la zone de saisie comporte un nombre accepté) ou aléatoire (si la zone de saisie est vide)
    Page up : interroger sur le nombre choisi (si la zone de saisie comporte un nombre accepté) ou aléatoire (si la zone de saisie est vide)
    Échap : quitter
    F1 : aide
    """
        texte_manuel.insert(END, quote)
        texte_manuel.config(state=DISABLED)
        fen_aide.bind_all('<Destroy>', libere)
        fen_aide.mainloop()


#Bouton du choix du nombre de colonnes
choixcol.grid(row=3,column=0, sticky='we', pady=4, columnspan=4)
boutons.append(choixcol)

zone_hasard=LabelFrame(zone_gauche, text="max. blocs", background=couleur)
zone_hasard.grid(row=6,column=0,columnspan=4,sticky='nesw', pady=10)
bal_zone_hasard = tix.Balloon(zone_gauche)
bal_zone_hasard.bind_widget(zone_hasard, msg='Régler les valeurs maximales pour les tirages aléatoires)')
zone_hasard.columnconfigure(0,minsize=25)
zone_hasard.columnconfigure(1,minsize=25)
zone_hasard.columnconfigure(2,minsize=25)
zone_hasard.columnconfigure(3,minsize=25)
#Curseurs d'échelles pour le mode tirage au hasard
titre_m=Label(zone_hasard,text="m",background=couleur)
titre_c=Label(zone_hasard,text="c",background=couleur)
titre_d=Label(zone_hasard,text="d",background=couleur)
titre_u=Label(zone_hasard,text="u",background=couleur)
titre_m.grid(row=8,column=0,sticky='nesw')
titre_c.grid(row=8,column=1,sticky='nesw')
titre_d.grid(row=8,column=2,sticky='nesw')
titre_u.grid(row=8,column=3,sticky='nesw')
max_m=Scale(zone_hasard, orient='vertical', background=couleur, troughcolor=couleur_bouton, borderwidth=0, showvalue=0, from_=10, to=0, resolution=1, tickinterval=0, length=75, width=15, bd=0, command=update)
max_c=Scale(zone_hasard, orient='vertical', background=couleur, troughcolor=couleur_bouton,borderwidth=0, showvalue=0, from_=20, to=0, resolution=1, tickinterval=0, length=75, width=15, bd=0, command=update)
max_d=Scale(zone_hasard, orient='vertical', background=couleur, troughcolor=couleur_bouton,borderwidth=0, showvalue=0, from_=20, to=0, resolution=1, tickinterval=0, length=75, width=15, bd=0, command=update)
max_u=Scale(zone_hasard, orient='vertical', background=couleur, troughcolor=couleur_bouton,borderwidth=0, showvalue=0, from_=99, to=9, resolution=10, tickinterval=0, length=75, width=15, bd=0, command=update)
max_u.set(9)
max_d.set(9)
max_c.set(9)
max_m.set(9)
if "variables" in dir():
    max_m.set(variables[9])
    max_c.set(variables[10])
    max_d.set(variables[11])
    max_u.set(variables[12])
max_m.grid(row=9,column=0,pady=0, padx=0)
max_c.grid(row=9,column=1, pady=0, padx=0)
max_d.grid(row=9,column=2, pady=0, padx=0)
max_u.grid(row=9,column=3, pady=0, padx=0)
val_m=Label(zone_hasard,background=couleur,text=max_m.get())
val_c=Label(zone_hasard,background=couleur,text=max_c.get())
val_d=Label(zone_hasard,background=couleur,text=max_d.get())
val_u=Label(zone_hasard,background=couleur,text=max_u.get())
val_m.grid(row=10,column=0,sticky='nesw')
val_c.grid(row=10,column=1,sticky='nesw')
val_d.grid(row=10,column=2,sticky='nesw')
val_u.grid(row=10,column=3,sticky='nesw')


#Bouton à propos
bouton_apropos=Button(zone_gauche, background=couleur_bouton,image=img_info, command=apropos)
bouton_apropos.grid(row=8, column=2,pady=4, columnspan=2)
bal_bouton_apropos = tix.Balloon(zone_gauche)
bal_bouton_apropos.bind_widget(bouton_apropos, msg='À propos de Tuxblocs...')
bouton_aide=Button(zone_gauche, background=couleur_bouton,image=img_aide, command=aide)
bouton_aide.grid(row=8, column=0,pady=4, columnspan=2)
bal_bouton_aide = tix.Balloon(zone_gauche)
bal_bouton_aide.bind_widget(bouton_aide, msg='Aide')


corbeille=Button(zone_gauche, background=couleur_bouton,image=img_minicorbeille, command=lambda : reset("tout"))
corbeille.grid(row=0,column=0,columnspan=2)
bal_corbeille = tix.Balloon(zone_gauche)
bal_corbeille.bind_widget(corbeille, msg='Supprimer tous les blocs et remettre les compteurs à zéro')
boutons.append(corbeille)
bouton_ranger=Button(zone_gauche,background=couleur_bouton,image=img_ranger, command=lambda : action_range("tout"))
bouton_ranger.grid(row=1,column=0,columnspan=2)
bal_bouton_ranger = tix.Balloon(zone_gauche)
bal_bouton_ranger.bind_widget(bouton_ranger, msg='Ranger tous les blocs')

choix_compteur=Button(zone_gauche, background=couleur_bouton,image=img_oeil, command=lambda: affichage_compteur(choix_compteur,compteur,interg))
if interg==0:
    choix_compteur.configure(image=img_oeil_inactif)

bouton_hasard=Button(zone_gauche, background=couleur_bouton,image=img_melanger, command=lambda : action_hasard("tout"))
bouton_hasard.grid(row=1,column=2,columnspan=2, padx=0,pady=0)
bal_bouton_hasard = tix.Balloon(zone_gauche)
bal_bouton_hasard.bind_widget(bouton_hasard, msg='Mélanger tous les blocs')

choix_compteur.grid(row=0,column=2,columnspan=2)
choix_verr.grid(row=2,column=0,columnspan=2)

bal_choix_compteur = tix.Balloon(zone_gauche)
bal_choix_compteur.bind_widget(choix_compteur, msg='Afficher / Masquer le compteur principal')

#Listes des coordonnées des coins des rectangles
objets_milliers=[]
objets_centaines=[]
objets_dizaines=[]
objets_unites=[]
objets_dizgauche=[]
objets_centgauche=[]
objets_millgauche=[]

#Lancement du début
#init()
def man_suppr(objet):
    if lock==0:
        suppr(objet)

def new(objet,valeur,mode):
    if lock==0:
        if objet=="unite" or objet=="dizaine" or (objet=="centaine" and int(nbcolonnes)>2) or (objet=="millier" and int(nbcolonnes)>3) or nb==1:
            cree(objet, valeur, mode)

def coordshasard(objet,mode):
    if nb>1 or mode=="range":
        if objet == "unite":
            liste_coords = liste_unite
        if objet == "dizaine":
            liste_coords=liste_dizaine
        if objet == "centaine":
            liste_coords = liste_centaine
        if objet == "millier":
            liste_coords = liste_millier
    else:
        liste_coords = liste_globale
    if objet == "unite":
        x1 = int(liste_coords[0] + larg_unite)
        x2 = int(liste_coords[2] - larg_unite)
        y1 = int(liste_coords[1] + larg_unite)
        y2 = int(liste_coords[3] - larg_unite)
    if objet == "dizaine":
        x1 = int(liste_coords[0] + larg_dizaine / 2 + larg_unite)
        x2 = int(liste_coords[2] - larg_dizaine / 2 - larg_unite)
        y1 = int(liste_coords[1] + larg_unite)
        y2 = int(liste_coords[3] - larg_unite)
    if objet == "centaine":
        x1 = int(liste_coords[0] + larg_dizaine / 2 + larg_unite)
        x2 = int(liste_coords[2] - larg_dizaine / 2 - larg_unite)
        y1 = int(liste_coords[1] + larg_dizaine / 2 + larg_unite)
        y2 = int(liste_coords[3] - larg_dizaine / 2 - larg_unite)
    if objet == "millier":
        x1 = int(liste_coords[0] + larg_dizaine / 2 + 3*larg_unite)
        x2 = int(liste_coords[2] - larg_dizaine / 2 - 3*larg_unite)
        y1 = int(liste_coords[1] + larg_dizaine / 2 + 3*larg_unite)
        y2 = int(liste_coords[3] - larg_dizaine / 2 - 3*larg_unite)
    if x1>x2:
        x1=x2=mean((x1,x2))
    return x1,x2,y1,y2



#Boucle de création d'une image
def cree(objet,valeur,mode):
    global nombre, milliers, centaines, dizaines, unites,x1,x2,y1,y2,coords_bouge
    #On incrémente les compteurs
    nombre=nombre+valeur
    #On récupère les coordonnées de la colonne correspondante et on incrémente le nombre de chaque
    if not mode=="groupe" and not mode=="degroupe":
        if objet=="millier":
            milliers=milliers+1
            img=img_millier
        if objet=="centaine":
            centaines=centaines+1
            img=img_centaine
        if objet=="dizaine":
            dizaines=dizaines+1
            img=img_dizaine
        if objet=="unite":
            unites=unites+1
            img=img_unite
        x1,x2,y1,y2=coordshasard(objet,"normal")
        xobjet = randint(x1, x2)
        yobjet = randint(y1, y2)
        if objet == "unite" or objet == "dizaine":
            if separations.get()==1 and centre_canvas_y-larg_unite<yobjet<centre_canvas_y:
                yobjet=yobjet-larg_unite
            if separations.get()==1 and centre_canvas_y+larg_unite>yobjet>=centre_canvas_y:
                yobjet=yobjet+larg_unite
        if objet == "centaine" or objet == "millier":
            if separations.get()==1 and centre_canvas_y-larg_dizaine<yobjet<centre_canvas_y:
                yobjet=yobjet-larg_dizaine*0.75
            if separations.get()==1 and centre_canvas_y+larg_dizaine>yobjet>=centre_canvas_y:
                yobjet=yobjet+larg_dizaine*0.75
    if objet=="millier":
        img = img_millier
        if mode == "groupe":
            if nb==1:
                objets_milliers.append(zone_princ.create_image(coords_groupe[0], coords_groupe[1], image=img, tags=objet))
                milliers=milliers+1
                centaines=centaines-10
                maj()
            else:
                objets_millgauche.append(zone_princ.create_image(coords_groupe[0]-0.5*larg_unite,coords_groupe[1]+0.5*larg_unite, image=img, tags="millgauche"))
        elif mode=="clic":
            objets_milliers.append(zone_princ.create_image(objetx,objety, image=img,tags=objet))
        else:
            if ordre.get() == 0:
                objets_milliers.append(zone_princ.create_image(xobjet, yobjet, image=img,tags=objet))
            else:
                cible = rangement(objet, milliers - 1)
                objets_milliers.append(zone_princ.create_image(cible, image=img,tags=objet))
        if separations.get() == 1 and not mode=="groupe":
            ajustey(objets_milliers[-1])
    if objet=="centaine":
        img = img_centaine
        c=centaines-10*mg
        if mode=="groupe":
            if nb==1:
                objets_centaines.append(zone_princ.create_image(coords_groupe[0], coords_groupe[1], image=img, tags=objet))
                centaines=centaines+1
                dizaines=dizaines-10
                maj()
            else:
                objets_centgauche.append(zone_princ.create_image(coords_groupe[0],coords_groupe[1], image=img, tags="centgauche"))
        elif mode=="bouge" or mode=="degroupe":
            liste=liste_centaine
            objets_centaines.append(zone_princ.create_image(coords_bouge[0]-((rang_casse-5)*larg_unite),coords_bouge[1]+((rang_casse-5)*larg_unite), image=img, tags=objet))
        elif mode=="clic":
            objets_centaines.append(zone_princ.create_image(objetx,objety, image=img,tags=objet))
        else:
            if ordre.get() == 1:
                cible = rangement(objet, c - 1)
                objets_centaines.append(zone_princ.create_image(cible, image=img, tags=objet))
            else:
                objets_centaines.append(zone_princ.create_image(xobjet, yobjet, image=img,tags=objet))
        if separations.get() == 1 and not mode=="groupe" and not mode=="degroupe":
            ajustey(objets_centaines[-1])
    if objet=="dizaine":
        img = img_dizaine
        d=dizaines-10*cg
        if mode=="groupe":
            if nb==1:
                objets_dizaines.append(zone_princ.create_image(coords_groupe[0] + larg_dizaine / 2 - larg_unite / 2, coords_groupe[1],image=img, tags=objet))
                dizaines=dizaines+1
                unites=unites-10
                maj()
            else:
                objets_dizgauche.append(zone_princ.create_image(coords_groupe[0]+larg_dizaine/2-larg_unite/2,coords_groupe[1], image=img, tags="dizgauche"))
        elif mode=="bouge" or mode=="degroupe":
            objets_dizaines.append(zone_princ.create_image(coords_bouge[0],coords_bouge[1]+larg_unite+larg_unite*1.5*(rang_casse-5), image=img, tags=objet))
        elif mode=="clic":
            objets_dizaines.append(zone_princ.create_image(objetx,objety, image=img,tags=objet))
        else:
            if ordre.get() == 0:
                objets_dizaines.append(zone_princ.create_image(xobjet, yobjet, image=img, tags=objet))
            else:
                cible = rangement(objet, d - 1)
                objets_dizaines.append(zone_princ.create_image(cible, image=img, tags=objet))
        if separations.get() == 1 and not mode=="groupe" and not mode=="degroupe":
            ajustey(objets_dizaines[-1])
    if objet=="unite":
        img = img_unite
        u=unites-10*dg
        if mode=="bouge" or mode=="degroupe":
            objets_unites.append(zone_princ.create_image(coords_bouge[0]+larg_unite*(rang_casse-5.5),coords_bouge[1], image=img, tags=objet))
        elif mode=="clic":
            objets_unites.append(zone_princ.create_image(objetx,objety, image=img,tags=objet))
        else:
            if ordre.get()==0:
                objets_unites.append(zone_princ.create_image(xobjet,yobjet, image=img, tags=objet))
            else:
                cible=rangement(objet,u-1)
                objets_unites.append(zone_princ.create_image(cible, image=img,tags=objet))
        if separations.get() == 1 and not mode == "degroupe":
            ajustey(objets_unites[-1])
        if separations.get() == 1:
            ajuste(objets_unites[-1])
    if not mode=="clic":
        zone_princ.tag_lower(zone_princ.find_all()[-1],"deco")
    else:
        zone_princ.tag_raise(zone_princ.find_all()[-1])
    maj()


def rangement(objet,position):
    if objet == "unite":
        nombremax=2*nombrezu
    if objet == "dizaine":
        nombrexd = (larg_colonne - 4 * larg_unite) // larg_dizaine
        nombreyd = (haut_colonne - larg_unite) // (2*larg_unite)
        nombrezd = nombrexd * nombreyd
        if int(nbcolonnes)==2:
            nombreyd=10
        else:
            nombreyd=2
        nombremax=2*nombrezd
    if objet == "centaine":
        nombrexc=(larg_colonne - 4 * larg_unite) // larg_dizaine
        nombreyc=(haut_colonne - 4 * larg_unite) // larg_dizaine
        nombrezc=nombrexc*nombreyc
        nombremax=2*nombrezc
    if objet == "millier":
        nombrexm=(larg_colonne - 4 * larg_unite) // larg_dizaine
        nombreym=(haut_colonne - 4 * larg_unite) // 100
        nombrezm=nombrexm*nombreym
        nombremax=2*nombrezm-nombrexm
    if position < nombremax:
        if objet=="unite":
            return [(larg_colonne/6)+liste_unite[0] + (position - nombrexu * (int(position / nombrexu))) * (larg_colonne/6)+(int(position/nombrezu))*(larg_colonne/12),larg_unite*2 + liste_unite[1] + ((int(position/nombrexu))-nombreyu*(int(position/nombrezu)))*(larg_colonne/6) + (larg_colonne/12)*int(position / nombrezu)]
        if objet == "dizaine":
            if int(nbcolonnes)==2:
                return [((liste_dizaine[0])+(liste_dizaine[2]))/2-((position//nombreyd)*(larg_unite/3)),liste_dizaine[1] + (haut_colonne/11) + (position-(nombreyd*int(position/nombreyd)))*(haut_colonne/11)+((position//nombreyd)*(larg_unite/3))]
            else:
                return [liste_dizaine[0]+larg_dizaine/2+2*larg_unite+(larg_dizaine+2*larg_unite)*(position%nombrexd)-(position//nombrezd)*(larg_unite/3),liste_dizaine[1]+(2*larg_unite)+(2*larg_unite)*((position-((position//nombrezd)*nombrezd))//nombrexd)+(position//nombrezd)*(larg_unite/3)]
        if objet == "centaine":
            return [larg_dizaine/2+2*larg_unite + liste_centaine[0] + (position - nombrexc * (int(position / nombrexc))) * (larg_dizaine+2*larg_unite)+(int(position/nombrezc))*40,(larg_dizaine/2+larg_unite) + liste_centaine[1] + ((int(position/nombrexc))-nombreyc*(int(position/nombrezc)))*(larg_dizaine+larg_unite) + 80*int(position / nombrezc)]
        if objet == "millier":
            return [larg_dizaine*0.75+ liste_millier[0] + (position - nombrexm * (int(position / nombrexm))) * 160+(int(position/nombrezm))*20,120 + liste_millier[1] + ((int(position/nombrexm))-nombreym*(int(position/nombrezm)))*80 + 90*int(position / nombrezm)]
    else:
        if objet=="unite":
            aleau=Label(zone_princ,text="Rangement impossible\nPlacement aléatoire")
            aleau.place(x=liste_unite[0]+larg_colonne/2,y=liste_unite[1]+haut_colonne/2,anchor=CENTER, width=150)
            zone_princ.after(1000,lambda:aleau.place_forget())
        if objet=="dizaine":
            alead=Label(zone_princ,text="Rangement impossible\nPlacement aléatoire")
            alead.place(x=liste_dizaine[0]+larg_colonne/2,y=liste_dizaine[1]+haut_colonne/2,anchor=CENTER, width=200)
            zone_princ.after(1000,lambda:alead.place_forget())
        if objet=="centaine":
            aleac=Label(zone_princ,text="Rangement impossible\nPlacement aléatoire")
            aleac.place(x=liste_centaine[0]+larg_colonne/2,y=liste_centaine[1]+haut_colonne/2,anchor=CENTER, width=200)
            zone_princ.after(1000,lambda:aleac.place_forget())
        if objet=="millier":
            aleam=Label(zone_princ,text="Rangement impossible\nPlacement aléatoire")
            aleam.place(x=liste_millier[0]+larg_colonne/2,y=liste_millier[1]+haut_colonne/2,anchor=CENTER, width=200)
            zone_princ.after(1000,lambda:aleam.place_forget())
        x1, x2, y1, y2 = coordshasard(objet,"range")
        return (randint(x1, x2), randint(y1, y2))

def action_range(objet):
    global ok
    if ok==1:
        rangu = rangd = rangc = rangm = 0
        ok=0
        if objet=="unite" or objet=="tout":
            for i in marku:
                name=f"r{i}"
                zone_princ.delete(name)
            trajectoirex = []
            trajectoirey = []
            for i in (objets_unites):
                cible=rangement("unite",rangu)
                trajectoirex.append(cible[0]-(zone_princ.coords(i)[0]))
                trajectoirey.append(cible[1]-(zone_princ.coords(i)[1]))
                rangu = rangu + 1
            if unites>=50:
                rang=0
                for j in (objets_unites):
                    zone_princ.move(j,trajectoirex[rang],trajectoirey[rang])
                    rang=rang+1
            if unites<50:
                for j in range (30):
                    rang=0
                    for k in (objets_unites):
                        zone_princ.move(k,trajectoirex[rang]/30,trajectoirey[rang]/30)
                        rang=rang+1
                        zone_princ.update()
            if separations.get() == 1:
                for i in objets_unites:
                    ajuste(i)
        if objet=="dizaine" or objet=="tout":
            for i in markd:
                name=f"r{i}"
                zone_princ.delete(name)
            trajectoirex = []
            trajectoirey = []
            for i in (objets_dizaines):
                cible=rangement("dizaine",rangd)
                trajectoirex.append(cible[0] - (zone_princ.coords(i)[0]))
                trajectoirey.append(cible[1] - (zone_princ.coords(i)[1]))
                rangd = rangd + 1
            for j in range (30):
                rang=0
                for k in (objets_dizaines):
                    zone_princ.move(k,trajectoirex[rang]/30,trajectoirey[rang]/30)
                    rang=rang+1
                    zone_princ.update()
        if objet=="centaine" or objet=="tout":
            for i in markc:
                name=f"r{i}"
                zone_princ.delete(name)
            trajectoirex = []
            trajectoirex = []
            trajectoirey = []
            for i in (objets_centaines):
                cible=rangement("centaine",rangc)
                trajectoirex.append(cible[0] - (zone_princ.coords(i)[0]))
                trajectoirey.append(cible[1] - (zone_princ.coords(i)[1]))
                rangc=rangc+1
            for j in range (30):
                rang=0
                for k in (objets_centaines):
                    zone_princ.move(k,trajectoirex[rang]/30,trajectoirey[rang]/30)
                    rang=rang+1
                    zone_princ.update()
        if objet=="millier" or objet=="tout":
            for i in markm:
                name=f"r{i}"
                zone_princ.delete(name)
            trajectoirex = []
            trajectoirex = []
            trajectoirey = []
            for i in (objets_milliers):
                cible=rangement("millier",rangm)
                trajectoirex.append(cible[0] - (zone_princ.coords(i)[0]))
                trajectoirey.append(cible[1] - (zone_princ.coords(i)[1]))
                rangm=rangm+1
            for j in range (30):
                rang=0
                for k in (objets_milliers):
                    zone_princ.move(k,trajectoirex[rang]/30,trajectoirey[rang]/30)
                    rang=rang+1
                    zone_princ.update()
        if separations.get()==1:
            for i in [*objets_milliers,*objets_millgauche,*objets_centaines,*objets_centgauche,*objets_dizaines,*objets_dizgauche,*objets_unites]:
                ajustey(i)
        maj_compteurs_sep()
        ok=1
def action_hasard(objet):
    global ok
    if ok==1:
        ok=0
        if objet=="unite" or objet=="tout":
            for i in marku:
                name=f"r{i}"
                zone_princ.delete(name)
            trajectoirex = []
            x1, x2, y1, y2 = coordshasard("unite","normal")
            trajectoirexu = []
            trajectoireyu = []
            for i in (objets_unites):
                xobjet = randint(x1, x2)
                yobjet = randint(y1, y2)
                cible=xobjet,yobjet
                trajectoirexu.append(cible[0]-(zone_princ.coords(i)[0]))
                trajectoireyu.append(cible[1]-(zone_princ.coords(i)[1]))
            if unites>=50:
                rang=0
                for j in (objets_unites):
                    zone_princ.move(j,trajectoirexu[rang],trajectoireyu[rang])
                    rang=rang+1
            if unites<50:
                for j in range (30):
                    rang=0
                    for k in (objets_unites):
                        zone_princ.move(k,trajectoirexu[rang]/30,trajectoireyu[rang]/30)
                        rang=rang+1
                        zone_princ.update()
            if separations.get() == 1:
                for i in objets_unites:
                    ajuste(i)
        if objet=="dizaine" or objet=="tout":
            for i in markd:
                name=f"r{i}"
                zone_princ.delete(name)
            trajectoirex = []
            x1, x2, y1, y2 = coordshasard("dizaine","normal")
            trajectoirexd = []
            trajectoireyd = []
            for i in (objets_dizaines):
                xobjet = randint(x1, x2)
                yobjet = randint(y1, y2)
                cible=xobjet,yobjet
                trajectoirexd.append(cible[0]-(zone_princ.coords(i)[0]))
                trajectoireyd.append(cible[1]-(zone_princ.coords(i)[1]))
            if dizaines>=25:
                rang=0
                for j in (objets_dizaines):
                    zone_princ.move(j,trajectoirexd[rang],trajectoireyd[rang])
                    rang=rang+1
            if dizaines<25:
                for j in range (30):
                    rang=0
                    for k in (objets_dizaines):
                        zone_princ.move(k,trajectoirexd[rang]/30,trajectoireyd[rang]/30)
                        rang=rang+1
                        zone_princ.update()
        if objet=="centaine" or (objet=="tout"and (int(nbcolonnes)>2)or nb==1):
            for i in markc:
                name=f"r{i}"
                zone_princ.delete(name)
            trajectoirex = []
            x1, x2, y1, y2 = coordshasard("centaine","normal")
            trajectoirexc = []
            trajectoireyc = []
            for i in (objets_centaines):
                xobjet = randint(x1, x2)
                yobjet = randint(y1, y2)
                cible=xobjet,yobjet
                trajectoirexc.append(cible[0]-(zone_princ.coords(i)[0]))
                trajectoireyc.append(cible[1]-(zone_princ.coords(i)[1]))
            if centaines>=20:
                rang=0
                for j in (objets_centaines):
                    zone_princ.move(j,trajectoirexc[rang],trajectoireyc[rang])
                    rang=rang+1
            if centaines<20:
                for j in range (30):
                    rang=0
                    for k in (objets_centaines):
                        zone_princ.move(k,trajectoirexc[rang]/30,trajectoireyc[rang]/30)
                        rang=rang+1
                        zone_princ.update()
        if objet=="millier" or (objet=="tout" and (int(nbcolonnes)>3 or nb==1)):
            for i in markm:
                name=f"r{i}"
                zone_princ.delete(name)
            trajectoirex = []
            x1, x2, y1, y2 = coordshasard("millier","normal")
            trajectoirexm = []
            trajectoireym = []
            for i in (objets_milliers):
                xobjet = randint(x1, x2)
                yobjet = randint(y1, y2)
                cible=xobjet,yobjet
                trajectoirexm.append(cible[0]-(zone_princ.coords(i)[0]))
                trajectoireym.append(cible[1]-(zone_princ.coords(i)[1]))
            if milliers>=20:
                rang=0
                for j in (objets_milliers):
                    zone_princ.move(j,trajectoirexm[rang],trajectoireym[rang])
                    rang=rang+1
            if milliers<20:
                for j in range (30):
                    rang=0
                    for k in (objets_milliers):
                        zone_princ.move(k,trajectoirexm[rang]/30,trajectoireym[rang]/30)
                        rang=rang+1
                        zone_princ.update()
        for i in objets_milliers:
            zone_princ.tag_lower(i, "deco")
        for i in objets_centaines:
            zone_princ.tag_lower(i, "deco")
        for i in objets_dizaines:
            zone_princ.tag_lower(i, "deco")
        for i in objets_unites:
            zone_princ.tag_lower(i, "deco")
        if separations.get()==1:
            for i in [*objets_milliers,*objets_millgauche,*objets_centaines,*objets_centgauche,*objets_dizaines,*objets_dizgauche,*objets_unites]:
                ajustey(i)
        maj_compteurs_sep()
        ok=1
def cache_tous_compteurs():
    global interg, interu, interd, interc, interm, ask_montre
    interg = interd = interd = interc = interm = interu = 0
    if ask==1:
        interg=1
        ask_montre=0
        liste_compteurs=(compteur_unites, compteur_dizaines, compteur_centaines, compteur_milliers)
        liste_aff=(aff_compteur_unite, aff_compteur_dizaine, aff_compteur_millier, aff_compteur_centaine)
    else:
        liste_compteurs=(compteur_unites, compteur_dizaines, compteur_centaines, compteur_milliers, compteur)
        liste_aff=(choix_compteur, aff_compteur_unite, aff_compteur_dizaine, aff_compteur_millier, aff_compteur_centaine)
    for i in liste_compteurs:
        i.place_forget()
    for i in liste_aff:
        i.configure(image=img_oeil_inactif)
def montre_tous_compteurs():
    global interg, interu, interd, interc, interm, ask_montre
    interg = interd = interd = interc = interm = interu = 1
    if ask==1:
        ask_montre = 1
    compteur.place(x=5, y=50, anchor=W, width=150, height=80)
    compteur_unites.place(x=(liste_unite[0] + liste_unite[2]) / 2 + 100, y=80, anchor=CENTER)
    compteur_dizaines.place(x=(liste_dizaine[0] + liste_dizaine[2]) / 2 + 100, y=80, anchor=CENTER)
    if nb>2 or nb==1:
        compteur_centaines.place(x=(liste_centaine[0] + liste_centaine[2]) / 2 + 100, y=80, anchor=CENTER)
    if nb>3 or nb==1:
        compteur_milliers.place(x=(liste_millier[0] + liste_millier[2]) / 2 + 100, y=80, anchor=CENTER)
    for i in (choix_compteur, aff_compteur_unite, aff_compteur_dizaine, aff_compteur_millier, aff_compteur_centaine):
        i.configure(image=img_oeil)

def cache_tous_petits_compteurs():
    global interu, interd, interc, interm
    interd = interd = interc = interm = interu = 0
    for i in (compteur_unites, compteur_dizaines, compteur_centaines, compteur_milliers):
        i.place_forget()
    for i in (aff_compteur_unite, aff_compteur_dizaine, aff_compteur_millier, aff_compteur_centaine):
        i.configure(image=img_oeil_inactif)

def tirage(self):
    global ok
    if bouton_lock==0 and ok==1:
        ok=0
        if cachecompteur.get()==1:
            cache_tous_compteurs()
        reset("tout")
        for i in range(randint(0,max_u.get())):
            cree("unite",1,"normal")
        for i in range(randint(0,max_d.get())):
            cree("dizaine",10,"normal")
        if nb>2 or nb==1:
            for i in range(randint(0,max_c.get())):
                cree("centaine",100,"normal")
        if nb>3 or nb==1:
            for i in range(randint(0,max_m.get())):
                cree("millier",1000,"normal")
        if nb==1:
           for i in objets_milliers:
                zone_princ.tag_lower(i,"deco")
           for i in objets_centaines:
                zone_princ.tag_lower(i,"deco")
           for i in objets_dizaines:
                zone_princ.tag_lower(i,"deco")
           for i in objets_unites:
                zone_princ.tag_lower(i,"deco")
        compteur.configure(text=nombre, background="#bdffd5", anchor=CENTER)
        ok=1

#Suppression d'un objet
def suppr(objet):
    global nombre, milliers, centaines, dizaines, unites, u,d,c,m
    if objet=="millier" and milliers>0 and len(objets_milliers)>0:
        if len(markm)>0:
            for i in markm:
                milliers = milliers - 1
                nombre = nombre - 1000
                objets_milliers.remove(i)
                name = f"r{i}"
                zone_princ.delete(name)
                zone_princ.delete(i)
            markm.clear()
        else:
            milliers= milliers - 1
            nombre = nombre - 1000
            zone_princ.delete(objets_milliers[-1])
            objets_milliers.pop()
    if objet=="centaine" and centaines>0 and len(objets_centaines)>0:
        if len(markc)>0:
            for i in markc:
                centaines = centaines - 1
                nombre = nombre - 100
                objets_centaines.remove(i)
                name = f"r{i}"
                zone_princ.delete(name)
                zone_princ.delete(i)
            markc.clear()
        else:
            centaines= centaines - 1
            nombre = nombre - 100
            zone_princ.delete(objets_centaines[-1])
            objets_centaines.pop()
    if objet=="dizaine" and dizaines>0 and len(objets_dizaines)>0:
        if len(markd)>0:
            for i in markd:
                dizaines = dizaines - 1
                nombre = nombre - 10
                objets_dizaines.remove(i)
                name = f"r{i}"
                zone_princ.delete(name)
                zone_princ.delete(i)
            markd.clear()
        else:
            dizaines= dizaines - 1
            nombre = nombre - 10
            zone_princ.delete(objets_dizaines[-1])
            objets_dizaines.pop()
    if objet=="unite" and unites>0 and len(objets_unites)>0:
        if len(marku)>0:
            for i in marku:
                unites = unites - 1
                nombre = nombre - 1
                objets_unites.remove(i)
                name = f"r{i}"
                zone_princ.delete(name)
                zone_princ.delete(i)
            marku.clear()
        else:
            unites= unites - 1
            nombre = nombre - 1
            zone_princ.delete(objets_unites[-1])
            objets_unites.pop()
    maj()

def suppr_marku(event):
    global unites, dizaines, centaines, milliers, nombre,dg,cg,mg
    if len(marku) > 0:
        for i in marku:
            unites = unites - 1
            nombre = nombre - 1
            objets_unites.remove(i)
            name = f"r{i}"
            zone_princ.delete(name)
            zone_princ.delete(i)
        marku.clear()
    if len(markd) > 0:
        for i in markd:
            dizaines = dizaines - 1
            nombre = nombre - 10
            objets_dizaines.remove(i)
            name = f"r{i}"
            zone_princ.delete(name)
            zone_princ.delete(i)
        markd.clear()
    if len(markdg) > 0:
        for i in markdg:
            unites = unites - 10
            nombre = nombre - 10
            dg=dg-1
            objets_dizgauche.remove(i)
            name = f"r{i}"
            zone_princ.delete(name)
            zone_princ.delete(i)
        markdg.clear()
    if len(markc) > 0:
        for i in markc:
            centaines = centaines - 1
            nombre = nombre - 100
            objets_centaines.remove(i)
            name = f"r{i}"
            zone_princ.delete(name)
            zone_princ.delete(i)
        markc.clear()
    if len(markcg) > 0:
        for i in markcg:
            dizaines = dizaines - 10
            nombre = nombre - 100
            cg=cg-1
            objets_centgauche.remove(i)
            name = f"r{i}"
            zone_princ.delete(name)
            zone_princ.delete(i)
        markcg.clear()
    if len(markm) > 0:
        for i in markm:
            milliers = milliers - 1
            nombre = nombre - 1000
            objets_milliers.remove(i)
            name = f"r{i}"
            zone_princ.delete(name)
            zone_princ.delete(i)
        markm.clear()
    if len(markmg) > 0:
        for i in markmg:
            centaines = centaines - 10
            nombre = nombre - 1000
            mg=mg-1
            objets_millgauche.remove(i)
            name = f"r{i}"
            zone_princ.delete(name)
            zone_princ.delete(i)
        markmg.clear()
    maj()

#Déplacement d'un objet
def deplacement(objet,nb,dx,temps):
    if zone_princ.coords(objet)[1]<500:
        dy=2
    else:
        dy=-2
    for i in range(nb):
        zone_princ.move(objet, dx, dy)
        zone_princ.update()
        time.sleep(temps)

#Calcul d'un trajet particulier
def rel(type,id,rang,mode):
    coords=zone_princ.coords(id)
    return [(arrivee(type,rang,mode)[0])-coords[0],(arrivee(type,rang,mode)[1])-coords[1]]

#Calcul de coordonnées cibles
def arrivee(objet,rang,mode):
    global unites, dizaine, centaine, millier
    corr=0
    if objet=="millier":
        return [mean(positionsx) + (14 * (rang - 4)), mean(positionsy) - (14 * (rang - 4))]
    if objet=="centaine":
        return [mean(positionsx)-((larg_unite/3)*(rang-4)),mean(positionsy)+ ((larg_unite/3) * (rang - 4))]
    if objet=="dizaine":
         return moyx,moyy+(rang-5)*larg_unite
    if objet=="unite":
        #if coords_bouge[1] > liste[3] - 2 * larg_unite:
        #    coords_bouge[1] = liste[3] - 2 * larg_unite
        if mode=="casse":
            return  coords_bouge[0]+2*larg_unite*((rang-2)-5*(rang//5)),coords_bouge[1]-larg_unite/2+larg_unite*2*int((rang)/5)
        else:
            return moyx+(rang-5)*larg_unite,moyy
#Cassage (dégroupage d'un objet) et déplacement
def casse(type,compteur,mode):

    global milliers,centaines,dizaines,unites, objets_milliers, nombre, m,c,d,u,ok, coords_bouge, rang_casse
    if compteur>0 and ok==1:
        compteur=compteur-1
        rang_casse=0
        positionsx = []
        positionsy = []
        trajectoirex= []
        trajectoirey= []
        if type=="millier" and len(objets_milliers)>0:
            ok=0
            milliers=milliers-1
            if mode=="doubleclic":
                objet=objetbouge
            elif len(markm)>0:
                objet=markm[-1]
                name=f"r{objet}"
                zone_princ.delete(name)
                markm.remove(objet)
            else:
                objet=objets_milliers[-1]
            zone_princ.tag_lower(objet,"deco")
            dx=(centrec[0]-zone_princ.coords(objet)[0])/30
            deplacement(objet,30,dx,0.02)
            nombre=nombre-1000
            coords_bouge = zone_princ.coords(objet)
            zone_princ.delete(objet)
            objets_milliers.remove(objet)
            for i in range(10):
                rang_casse = rang_casse + 1
                cree("centaine", 100,"bouge")
            if ordre.get()==1:
                ok=1
                action_range("centaine")
            ok = 1
            if len(markm)>0:
                casse(type,compteur,mode)
        if type=="centaine" and len(objets_centaines)>0:
            ok=0
            centaines=centaines-1
            if mode=="doubleclic":
                objet=objetbouge
            elif len(markc)>0:
                objet=markc[-1]
                name=f"r{objet}"
                zone_princ.delete(name)
                markc.remove(objet)
            else:
                objet=objets_centaines[-1]
            zone_princ.tag_lower(objet,"deco")
            dx = (centred[0] - zone_princ.coords(objet)[0]) / 30
            deplacement(objet,30,dx,0.02)
            nombre=nombre-100
            coords_bouge = zone_princ.coords(objet)
            zone_princ.delete(objet)
            objets_centaines.remove(objet)
            for i in range(10):
                rang_casse = rang_casse + 1
                cree("dizaine", 10,"bouge")
            if ordre.get()==1:
                ok=1
                action_range("dizaine")
            ok = 1
            if len(markc) > 0:
                casse(type, compteur, mode)

        if type=="dizaine" and len(objets_dizaines)>0:
            ok=0
            dizaines=dizaines-1
            if mode=="doubleclic":
                objet=objetbouge
            elif len(markd)>0:
                objet=markd[-1]
                name=f"r{objet}"
                zone_princ.delete(name)
                markd.remove(objet)
            else:
                objet=objets_dizaines[-1]
            zone_princ.tag_lower(objet,"deco")
            dx = (centreu[0] - zone_princ.coords(objet)[0]) / 30
            deplacement(objet,30,dx,0.02)
            nombre=nombre-10
            coords_bouge = zone_princ.coords(objet)
            zone_princ.delete(objet)
            objets_dizaines.remove(objet)
            for i in range(10):
                rang_casse=rang_casse+1
                cree("unite", 1,"bouge")
            rang = 0
            for i in (objets_unites[-10:]):
                positionsx.append(zone_princ.coords(i)[0])
                positionsy.append(zone_princ.coords(i)[1])
            for i in (objets_unites[-10:]):
                trajectoirex.append(rel("unite", i, rang, "casse")[0])
                trajectoirey.append(rel("unite", i, rang, "casse")[1])
                rang = rang + 1
            for i in range(30):
                rang = 0
                for i in (objets_unites[-10:]):
                    zone_princ.move(i, trajectoirex[rang] / 30, trajectoirey[rang] / 30)
                    rang = rang + 1
                zone_princ.update()
                time.sleep(0.02)
            if ordre.get()==1:
                ok=1
                action_range("unite")
            ok=1
            if len(markd)>0:
                casse(type,compteur,mode)
        ok=1
    else:
        message(f"Pas de {type} à casser")

objets=[]
def gauche(objet,compteur):
    global unites, dizaines, centaines, milliers, dg, cg, mg, ok
    if ok==1:
        ok=0
        rangd=dizaines
        rangc=centaines
        rangm=milliers
        x1,x2,y1,y2=coordshasard(objet,"normal")
        trajectoirex = []
        trajectoirey = []
        if objet=="dizaine":
            if len(markdg)>0:
                objets=markdg
            else:
                objets=objets_dizgauche.copy()
            if len(objets)==0:
                message("Grouper d'abord 10 unités.")
            for i in (objets):
                name = f"r{i}"
                zone_princ.delete(name)
                if ordre.get()==1:
                    cible=rangement("dizaine",rangd)
                else:
                    cible=randint(x1,x2), randint(y1,y2)
                trajectoirex.append(cible[0]-(zone_princ.coords(i)[0]))
                trajectoirey.append(cible[1]-(zone_princ.coords(i)[1]))
                rangd = rangd + 1
            if dizaines>=50:
                rang=0
                for j in (objets):
                    zone_princ.move(j,trajectoirex[rang],trajectoirey[rang])
                    zone_princ.update()
                    time.sleep(0.01)
                    rang=rang+1
            if dizaines<50:
                for j in range (30):
                    rang=0
                    for k in (objets):
                        zone_princ.move(k,trajectoirex[rang]/30,trajectoirey[rang]/30)
                        rang=rang+1
                        zone_princ.update()
                        time.sleep(0.01)
            dizaines=dizaines+dg
            unites=unites-(10*dg)
            dg=0
            maj()
            zone_princ.itemconfigure('dizgauche',tags="dizaine")
            objets_dizaines.extend(objets)

            for i in objets:
                zone_princ.dtag(i,"dizgauche")
                objets_dizgauche.remove(i)

            markdg.clear()
        if objet=="centaine":
            if len(markcg)>0:
                objets=markcg
            else:
                objets=objets_centgauche.copy()
            if len(objets)==0:
                message("Grouper d'abord 10 dizaines.")
            for i in (objets):
                name = f"r{i}"
                zone_princ.delete(name)
                if ordre.get()==1:
                    cible=rangement("centaine",rangc)
                else:
                    cible=randint(x1,x2), randint(y1,y2)
                trajectoirex.append(cible[0]-(zone_princ.coords(i)[0]))
                trajectoirey.append(cible[1]-(zone_princ.coords(i)[1]))
                rangc = rangc + 1
            if centaines>=50:
                rang=0
                for j in (objets):
                    zone_princ.move(j,trajectoirex[rang],trajectoirey[rang])
                    rang=rang+1
            if centaines<50:
                for j in range (30):
                    rang=0
                    for k in (objets):
                        zone_princ.move(k,trajectoirex[rang]/30,trajectoirey[rang]/30)
                        rang=rang+1
                        zone_princ.update()
            centaines=centaines+cg
            dizaines=dizaines-(10*cg)
            cg=0
            maj()
            zone_princ.itemconfigure('centgauche',tags="centaine")
            objets_centaines.extend(objets)
            for i in objets:
                zone_princ.dtag(i,"centgauche")
                objets_centgauche.remove(i)
            markcg.clear()
        if objet=="millier":
            if len(markmg)>0:
                objets=markmg
            else:
                objets=objets_millgauche.copy()
            if len(objets)==0:
                message("Grouper d'abord 10 centaines.")
            for i in (objets):
                name = f"r{i}"
                zone_princ.delete(name)
                if ordre.get()==1:
                    cible=rangement("millier",rangm)
                else:
                    cible=randint(x1,x2), randint(y1,y2)
                trajectoirex.append(cible[0]-(zone_princ.coords(i)[0]))
                trajectoirey.append(cible[1]-(zone_princ.coords(i)[1]))
                rangm = rangm + 1
            if milliers>=50:
                rang=0
                for j in (objets):
                    zone_princ.move(j,trajectoirex[rang],trajectoirey[rang])
                    rang=rang+1
            if milliers<50:
                for j in range (30):
                    rang=0
                    for k in (objets):
                        zone_princ.move(k,trajectoirex[rang]/30,trajectoirey[rang]/30)
                        rang=rang+1
                        zone_princ.update()
            milliers=milliers+mg
            centaines=centaines-(10*mg)
            mg=0
            maj()
            zone_princ.itemconfigure('millgauche',tags="millier")
            objets_milliers.extend(objets)
            for i in objets:
                zone_princ.dtag(i,"millgauche")
                objets_millgauche.remove(i)
            markmg.clear()
    ok=1
dg=cg=mg=0

positionsx= []
positionsy = []
def groupe(objet,mode):
    global ok
    if ok==1:
        ok=0
        global unites,dizaines,centaines,milliers, dg,cg,mg, coords_groupe, positionsx, positionsy,moyx,moyy,objets,objets_unites
        trajectoirex = []
        trajectoirey = []
        positionsx= []
        positionsy = []
        if objet=="unite" and unites-10*dg>9:
            if (len(marku)==0 or len(marku)==10):
                rang = 0
                if mode=="souris":
                    for i in marku:
                        if i in uagrouper:
                            uagrouper.remove(i)
                            uagrouper.append(i)
                    objets=uagrouper[-10:]
                    for n in uagrouper[-10:]:
                        name = f"r{n}"
                        zone_princ.delete(name)
                else:
                    if len(marku)>=10:
                        objets=marku[-10:]
                        for n in objets:
                            name = f"r{n}"
                            zone_princ.delete(name)
                            marku.remove(n)
                    else:
                        objets=objets_unites[-10:]
                for i in objets:
                    positionsx.append(zone_princ.coords(i)[0])
                    positionsy.append(zone_princ.coords(i)[1])
                moyx = mean(positionsx)
                moyy = mean(positionsy)
                for i in objets:
                    zone_princ.tag_lower(i,"deco")
                    trajectoirex.append(rel("unite", i, rang,"groupe")[0])
                    trajectoirey.append(rel("unite", i, rang,"groupe")[1])
                    rang = rang + 1
                for i in range(30):
                    rang = 0
                    for i in objets:
                        zone_princ.move(i, trajectoirex[rang] / 30, trajectoirey[rang] / 30)
                        rang = rang + 1
                    zone_princ.update()
                    time.sleep(0.02)
                zone_princ.update()
                time.sleep(0.02)
                coords_groupe = (zone_princ.coords(objets[-10]))[0], (zone_princ.coords(objets[-10]))[1]
                cree("dizaine", 10, "groupe")
                trajectoirey.clear()
                trajectoirey.clear()
                for i in objets:
                    objets_unites.remove(i)
                    if i in marku:
                        marku.remove(i)
                    zone_princ.delete(i)
                objets.clear()
                if not nb==1:
                    dg = dg + 1
                if separations.get()==1:
                    if nb==1:
                        ajustey(objets_dizaines[-1])
                    else:
                        ajustey(objets_dizgauche[-1])
            else:
                if len(marku)==1:
                    message("Une unité est marquée.\nPour créer une dizaine\nmarquer 10 unités exactement ou aucune.")
                else:
                    message(f"{len(marku)} unités sont marquées.\nPour créer une dizaine\nmarquer 10 unités exactement ou aucune.")
        if objet=="dizaine" and dizaines-10*cg>9:
            if (len(markd)==0 or len(markd)==10):
                rang = 0
                if mode=="souris":
                    for i in markd:
                        if i in dagrouper:
                            dagrouper.remove(i)
                            dagrouper.append(i)
                    objets=dagrouper[-10:]
                    for n in dagrouper[-10:]:
                        name = f"r{n}"
                        zone_princ.delete(name)
                else:
                    if len(markd)>=10:
                        objets=markd[-10:]
                        for n in objets:
                            name = f"r{n}"
                            zone_princ.delete(name)
                            markd.remove(n)
                    else:
                        objets=objets_dizaines[-10:]
                for i in (objets):
                    positionsx.append(zone_princ.coords(i)[0])
                    positionsy.append(zone_princ.coords(i)[1])
                moyx = mean(positionsx)
                moyy = mean(positionsy)
                for i in reversed(objets_dizaines[-10:]):
                    zone_princ.tag_lower(i,"deco")
                for i in (objets):
                    trajectoirex.append(rel("dizaine", i, rang,"groupe")[0])
                    trajectoirey.append(rel("dizaine", i, rang,"groupe")[1])
                    rang = rang + 1
                for i in range(30):
                    rang = 0
                    for i in (objets):
                        zone_princ.move(i, (trajectoirex[rang]/30), ((trajectoirey[rang]+(30*cg)) / 30))
                        rang = rang + 1
                    zone_princ.update()
                    time.sleep(0.02)
                zone_princ.update()
                time.sleep(0.3)
                coords_groupe = (zone_princ.coords(objets[-10]))[0], (zone_princ.coords(objets[-5]))[1]
                cree("centaine", 100, "groupe")
                for i in objets:
                    objets_dizaines.remove(i)
                    if i in markd:
                        markd.remove(i)
                    zone_princ.delete(i)
                if not nb == 1:
                    cg = cg + 1
                if separations.get()==1:
                    if nb==1:
                        ajustey(objets_centaines[-1])
                    else:
                        ajustey(objets_centgauche[-1])
            else :
                if len(markd)==1:
                    message("Une dizaine est marquée.\nPour créer une centaine\nmarquer 10 dizaines exactement ou aucune.")
                else:
                    message(f"{len(markd)} dizaines sont marquées.\nPour créer une centaine\nmarquer 10 dizaines exactement ou aucune.")
        if objet == "centaine" and centaines-10*mg > 9:
            if (len(markc)==0 or len(markc)==10):
                rang = 0
                if mode=="souris":
                    for i in markc:
                        if i in cagrouper:
                            cagrouper.remove(i)
                            cagrouper.append(i)
                    objets=cagrouper[-10:]
                    for n in cagrouper[-10:]:
                        name = f"r{n}"
                        zone_princ.delete(name)
                else:
                    if len(markc)>=10:
                        objets=markc[-10:]
                        for n in objets:
                            name = f"r{n}"
                            zone_princ.delete(name)
                            markc.remove(n)
                    else:
                        objets=objets_centaines[-10:]
                for i in (objets):
                    positionsx.append(zone_princ.coords(i)[0])
                    positionsy.append(zone_princ.coords(i)[1])
                    moyx = mean(positionsx)
                    moyy = mean(positionsy)
                for i in (objets):
                    zone_princ.tag_lower(i,"deco")
                    trajectoirex.append(rel("centaine", i, rang,"groupe")[0])
                    trajectoirey.append(rel("centaine", i, rang,"groupe")[1])
                    rang = rang + 1
                for i in range(30):
                    rang = 0
                    for i in (objets):
                        zone_princ.move(i, (trajectoirex[rang]/30), ((trajectoirey[rang]+(30*cg)) / 30))
                        rang = rang + 1
                    zone_princ.update()
                    time.sleep(0.001)
                zone_princ.update()
                time.sleep(0.3)
                coords_groupe = (zone_princ.coords(objets[-7]))[0], (zone_princ.coords(objets[-7]))[1]
                cree("millier", 1000, "groupe")
                for i in objets:
                    objets_centaines.remove(i)
                    if i in markc:
                        markc.remove(i)
                    zone_princ.delete(i)
                objets.clear()
                if not nb == 1:
                    mg = mg + 1
                if separations.get()==1:
                    if nb==1:
                        ajustey(objets_milliers[-1])
                    else:
                        ajustey(objets_millgauche[-1])
            else:
                if len(markc)==1:
                    message("Une centaine est marquée.\nPour créer un millier\nmarquer 10 centaines exactement ou aucune.")
                else:
                    message(f"{len(markc)} centaines sont marquées.\nPour créer un millier\nmarquer 10 centaines exactement ou aucune.")

    positionsy.clear()
    positionsx.clear()
    maj()
    ok=1
def degroupe(objet,mode):
    global coords_bouge,rang_casse,dg,cg,mg,objets_dizaines,ok,lock
    if ok==1:
        ok=0
        lock=1
        rang_casse=0
        trajectoirex=[]
        trajectoirey=[]
        if objet=="centaine" and (len(objets_millgauche)>0 or mode=="souris" or mode=="1colonne"):
            liste=liste_centaine
            if mode=="souris":
                suppr=objetbouge
                objets_milliers.remove(objetbouge)
            elif mode=="doubleclic":
                suppr=objetbouge
                objets_millgauche.remove(objetbouge)
            elif mode=="1colonne":
                suppr=objetbouge
                objets_milliers.remove(objetbouge)
                liste=liste_globale
            else:
                suppr = objets_millgauche[-1]
                objets_millgauche.pop()
            coords_bouge=zone_princ.coords(suppr)
            if coords_bouge[1] < liste[1] + larg_dizaine/2:
                coords_bouge[1] = liste[1] + larg_dizaine
            if coords_bouge[1] > liste[3] - larg_dizaine/2:
                coords_bouge[1] = liste[3] - larg_dizaine
            if coords_bouge[0] < liste[0] + larg_dizaine:
                coords_bouge[0] = liste[0]+ larg_dizaine*1.2
            if coords_bouge[0] > liste[2] - larg_dizaine/2:
                coords_bouge[0] = liste[2]-larg_dizaine*1.1
            if suppr in markm:
                name = f"r{suppr}"
                zone_princ.delete(name)
                markm.remove(suppr)
            if suppr in markmg:
                name = f"r{suppr}"
                zone_princ.delete(name)
                markmg.remove(suppr)
            zone_princ.delete(suppr)
            if not mode=="souris" and not mode=="1colonne":
                mg=mg-1
            for i in range(10):
                rang_casse = rang_casse + 1
                cree("centaine", 0,"degroupe")
            if separations.get()==1:
                for i in objets_centaines[-10:]:
                    ajustey(i)
        if objet=="dizaine" and (len(objets_centgauche)>0 or mode=="souris" or mode=="1colonne"):
            liste=liste_dizaine
            if mode=="souris":
                suppr=objetbouge
                objets_centaines.remove(objetbouge)
            elif mode=="doubleclic":
                suppr=objetbouge
                objets_centgauche.remove(objetbouge)
            elif mode=="1colonne":
                suppr=objetbouge
                objets_centaines.remove(objetbouge)
                liste=liste_globale
            else:
                suppr = objets_centgauche[-1]
                objets_centgauche.pop()
            coords_bouge=zone_princ.coords(suppr)
            if coords_bouge[1] < liste[1] + 10 * larg_unite:
                coords_bouge[1] = liste[1]+8*larg_unite
            if coords_bouge[1] > liste[3] - 10 * larg_unite:
                coords_bouge[1] = liste[3]-10*larg_unite
            if coords_bouge[0] < liste[0] + larg_dizaine/2:
                coords_bouge[0] = liste[0]+ larg_dizaine/2
            if coords_bouge[0] > liste[2] - larg_dizaine/2:
                coords_bouge[0] = liste[2]-larg_dizaine/2
            if suppr in markc:
                name = f"r{suppr}"
                zone_princ.delete(name)
                markc.remove(suppr)
            if suppr in markcg:
                name = f"r{suppr}"
                zone_princ.delete(name)
                markcg.remove(suppr)
            zone_princ.delete(suppr)
            if not mode == "souris" and not mode=="1colonne":
                cg=cg-1
            for i in range(10):
                rang_casse = rang_casse + 1
                cree("dizaine", 0,"degroupe")
            if separations.get()==1:
                for i in objets_dizaines[-10:]:
                    ajustey(i)
        if objet=="unite" and (len(objets_dizgauche)>0 or mode=="souris" or mode=="1colonne"):
            liste=liste_unite
            if mode=="souris":
                suppr=objetbouge
                if separations.get() == 1:
                    ajuste(suppr)
                objets_dizaines.remove(objetbouge)
            elif mode=="doubleclic":
                suppr=objetbouge
                if separations.get() == 1:
                    ajuste(suppr)
                objets_dizgauche.remove(objetbouge)
                dg = dg - 1
            elif mode=="1colonne":
                suppr=objetbouge
                if separations.get() == 1:
                    ajuste(suppr)
                objets_dizaines.remove(objetbouge)
                liste=liste_globale
            else:
                suppr=objets_dizgauche[-1]
                ajuste(suppr)
                objets_dizgauche.pop()
                dg = dg - 1
            coords_bouge = zone_princ.coords(suppr)
            if suppr in markd:
                name = f"r{suppr}"
                zone_princ.delete(name)
                markd.remove(suppr)
            if suppr in markdg:
                name = f"r{suppr}"
                zone_princ.delete(name)
                markdg.remove(suppr)
            zone_princ.delete(suppr)
            for i in range(10):
                rang_casse = rang_casse + 1
                cree("unite", 0,"degroupe")
            rang = 0
            if coords_bouge[1] > liste_unite[3] - 2*larg_unite:
                coords_bouge[1] = liste_unite[3] - 2*larg_unite
            if coords_bouge[1] < liste_unite[1] + 2*larg_unite:
                coords_bouge[1] = liste_unite[1]+ 2*larg_unite
            if coords_bouge[0] < liste[0] + larg_dizaine/2:
                coords_bouge[0] = liste[0]+ larg_dizaine/2
            if coords_bouge[0] > liste[2] - larg_dizaine/2:
                coords_bouge[0] = liste[2]-larg_dizaine/2
            for i in (objets_unites[-10:]):
                positionsx.append(zone_princ.coords(i)[0])
                positionsy.append(zone_princ.coords(i)[1])
            for i in (objets_unites[-10:]):
                trajectoirex.append(rel("unite", i, rang, "casse")[0])
                trajectoirey.append(rel("unite", i, rang, "casse")[1])
                rang = rang + 1
            for i in range(30):
                rang = 0
                for i in (objets_unites[-10:]):
                    zone_princ.move(i, trajectoirex[rang] / 30, trajectoirey[rang] / 30)
                    rang = rang + 1
                zone_princ.update()
                time.sleep(0.02)
            if separations.get()==1:
                for i in objets_unites[-10:]:
                    ajustey(i)

    maj()
    ok=1
    lock=0
		


#Spécial pour Windows
def souris(event):
    if event.delta == -120:
        actionsouris(0)
    if event.delta == 120:
        actionsouris(1)

#Action de la molette de la souris
def actionsouris(mode):
    x = fenetre.winfo_pointerx() - fenetre.winfo_rootx() -105
    y = fenetre.winfo_pointery() - fenetre.winfo_rooty() -105
    if liste_unite[1]<y<liste_unite[3]:
        if liste_unite[0]<x<liste_unite[2]:
            if mode==1:
                new("unite", 1, "normal")
            else:
                man_suppr("unite")
        if liste_dizaine[0]<x<liste_dizaine[2]:
            if mode==1:
                new("dizaine", 10, "normal")
            else:
                man_suppr("dizaine")
        if nb>2 or nb==1:
            if liste_centaine[0]<x<liste_centaine[2]:
                if mode==1:
                    new("centaine", 10, "normal")
                else:
                    man_suppr("centaine")
        if nb>3 or nb==1:
            if liste_millier[0]<x<liste_millier[2]:
                if mode==1:
                    new("millier", 1000, "normal")
                else:
                    man_suppr("millier")
def retour(objet):
    if objet in rect_rouge:
        zone_princ.moveto(objet, objetx-8, objety-8)
    else:
        zone_princ.moveto(objet,objetx,objety)

marqueur=0
permission=1

def marque(event):
    global permission,marqueur
    if permission==1 or event=="relache":
        if marqueur==0:
            fenetre.configure(cursor="pencil")
            bouton_marque.configure(image=img_pointe)
            marqueur=1
            zone_princ.itemconfigure("bouton_cree",state=DISABLED)
            img_cree_unite.configure(file="images/cree_unite_inactif.png")
            img_cree_dizaine.configure(file="images/cree_dizaine_inactif.png")
            img_cree_centaine.configure(file="images/cree_centaine_inactif.png")
            img_cree_millier.configure(file="images/cree_millier_inactif.png")
        else:
            fenetre.configure(cursor="arrow")
            bouton_marque.configure(image=img_marque)
            marqueur=0
            zone_princ.itemconfigure("bouton_cree",state=NORMAL)
            img_cree_unite.configure(file="images/cree_unite.png")
            img_cree_dizaine.configure(file="images/cree_dizaine.png")
            img_cree_centaine.configure(file="images/cree_centaine.png")
            img_cree_millier.configure(file="images/cree_millier.png")
        if event=="enfonce":
            permission=0
        else:
            permission=1
texte="texte"
etiquette=Label(fenetre,text=texte,font=gros,height=3, pady=10, padx=10, borderwidth=5, relief=GROOVE, background=couleur)
def efface_message():
    global etiquette
    etiquette.place_forget()
def message(texte):
    global etiquette
    fenetre.update()
    etiquette.configure(text=texte)
    etiquette.place(x=fenetre.winfo_width()/2,y=fenetre.winfo_height()/2,anchor=CENTER)
    zone_princ.after(2000,efface_message)


bouton_marque=Button(zone_gauche,background=couleur_bouton,image=img_marque, command=lambda:marque("relache"))
bouton_marque.grid(row=2, column=2, columnspan=2)
bal_bouton_marque = tix.Balloon(zone_gauche)
bal_bouton_marque.bind_widget(bouton_marque, msg='Mode marqueur (encadrer en rouge) / Mode normal (déplacer les blocs)')
options=Button(zone_gauche, background=couleur_bouton,image=img_options, command=options)
options.grid(row=7,column=2,columnspan=2)
bal_options = tix.Balloon(zone_gauche)
bal_options.bind_widget(options, msg='Options')
boutons.append(options)
choixseparations=Checkbutton(zone_gauche, background=couleur_bouton,variable=separations, onvalue = 1, offvalue = 0, image=img_separation,command=change_separations, indicatoron=0)
choixseparations.grid(row=7,column=0, pady=0, columnspan=2)
bal_choixseparations = tix.Balloon(zone_gauche)
bal_choixseparations.bind_widget(choixseparations, msg='Activer / Désactiver la séparation horizontale\net les compteurs par zones')


def estdans(objet,zone):
    if zone[0]-margex/2<zone_princ.coords(objet)[0]<zone[2]+margex/2 and zone[1]<zone_princ.coords(objet)[1]<zone[3]:
        return True
    else:
        return False

DETECTION_CLIC_SUR_OBJET=False
DETECTION_DOUBLE_CLIC_SUR_OBJET=0
def doubleclic(event):
    global DETECTION_DOUBLE_CLIC_SUR_OBJET, diffx, diffy, objetbouge, select, rectx, recty,objetx,objety, unites, dizaines, centaines, milliers
    if ok==1 and marqueur==0:
        # position du pointeur de la souris
        X = event.x
        Y = event.y
        # coordonnées du rectangle qui encadre l'objet
        for i in [*objets_unites,*objets_dizaines,*objets_centaines,*objets_milliers,*objets_dizgauche,*objets_centgauche,*objets_millgauche]:
            [x1,y1,x2,y2] = zone_princ.bbox(i)
            if x1 < X < x2 and y1 < Y < y2:
                DETECTION_DOUBLE_CLIC_SUR_OBJET = 1
                objetbouge=i
                zone_princ.tag_lower(objetbouge,"deco")
                objetx=x1
                objety=y1
                #calcul de la position relative du pointeur au moment du clic
                diffx=X-x1
                diffy=Y-y1
    if DETECTION_DOUBLE_CLIC_SUR_OBJET==1:
        if nb==1:
            if objetbouge in objets_dizaines:
                unites=unites+10
                dizaines=dizaines-1
                degroupe("unite", "1colonne")
            if objetbouge in objets_centaines:
                degroupe("dizaine", "1colonne")
                dizaines=dizaines+10
                centaines=centaines-1
            if objetbouge in objets_milliers:
                degroupe("centaine", "1colonne")
                centaines=centaines+10
                milliers=milliers-1
            maj()
        else:
            if objetbouge in objets_dizaines:
                casse("dizaine",dizaines,"doubleclic")
            if objetbouge in objets_centaines:
                casse("centaine",centaines,"doubleclic")
            if objetbouge in objets_milliers:
                casse("millier",milliers,"doubleclic")
        if objetbouge in objets_dizgauche:
            degroupe("unite","doubleclic")
        if objetbouge in objets_centgauche:
            degroupe("dizaine","doubleclic")
        if objetbouge in objets_millgauche:
            degroupe("centaine","doubleclic")
        DETECTION_DOUBLE_CLIC_SUR_OBJET=0

clicnouveau=0
def Clic(event):
    global DETECTION_CLIC_SUR_OBJET, diffx, diffy, objetbouge, select, rectx, recty,objetx,objety,boutoncree,clicnouveau
    DETECTION_CLIC_SUR_OBJET=0
    if ok==1:
        # position du pointeur de la souris
        X = event.x
        Y = event.y
        # coordonnées du rectangle qui encadre l'objet
        trouve=0
        for i in zone_princ.find_all():
            [x1,y1,x2,y2] = zone_princ.bbox(i)
            if x1 < X < x2 and y1 < Y < y2 and i in [*objets_milliers,*objets_millgauche,*objets_centaines,*objets_centgauche,*objets_dizaines,*objets_dizgauche,*objets_unites]:
                DETECTION_CLIC_SUR_OBJET = 1
                objetbouge=i
                trouve=1
                objetx=x1
                objety=y1
                #calcul de la position relative du pointeur au moment du clic
                diffx=X-x1
                diffy=Y-y1
        if trouve==1:
            zone_princ.tag_lower(objetbouge,"deco")
            if objetbouge in [*marku, *markc, *markd, *markm, *markdg, *markcg, *markmg]:
                name = f"r{objetbouge}"
                zone_princ.tag_lower(name,objetbouge)
            if marqueur==1:
                name = f"r{objetbouge}"
                if objetbouge in objets_unites:
                    if not objetbouge in marku:
                        rect_rouge.append(zone_princ.create_rectangle(zone_princ.bbox(objetbouge)[0]-4,zone_princ.bbox(objetbouge)[1]-4,zone_princ.bbox(objetbouge)[2],zone_princ.bbox(objetbouge)[3],width=8, outline="red", tags=name))
                        zone_princ.tag_lower(name,objetbouge)
                        marku.append(objetbouge)
                    else:
                        zone_princ.delete(name)
                        marku.remove(objetbouge)
                if objetbouge in objets_dizaines:
                    if not objetbouge in markd:
                        rect_rouge.append(zone_princ.create_rectangle(zone_princ.bbox(objetbouge)[0]-4,zone_princ.bbox(objetbouge)[1]-4,zone_princ.bbox(objetbouge)[2],zone_princ.bbox(objetbouge)[3],width=8, outline="red", tags=name))
                        zone_princ.tag_lower(name,objetbouge)
                        markd.append(objetbouge)
                    else:
                        zone_princ.delete(name)
                        markd.remove(objetbouge)
                if objetbouge in objets_dizgauche:
                    if not objetbouge in markdg:
                        rect_rouge.append(zone_princ.create_rectangle(zone_princ.bbox(objetbouge)[0]-4,zone_princ.bbox(objetbouge)[1]-4,zone_princ.bbox(objetbouge)[2],zone_princ.bbox(objetbouge)[3],width=8, outline="red", tags=name))
                        zone_princ.tag_lower(name,objetbouge)
                        markdg.append(objetbouge)
                    else:
                        zone_princ.delete(name)
                        markd.remove(objetbouge)
                if objetbouge in objets_centaines:
                    if not objetbouge in markc:
                        rect_rouge.append(zone_princ.create_rectangle(zone_princ.bbox(objetbouge)[0]-4,zone_princ.bbox(objetbouge)[1]-4,zone_princ.bbox(objetbouge)[2],zone_princ.bbox(objetbouge)[3],width=8, outline="red", tags=name))
                        zone_princ.tag_lower(name,objetbouge)
                        markc.append(objetbouge)
                    else:
                        zone_princ.delete(name)
                        markc.remove(objetbouge)
                if objetbouge in objets_centgauche:
                    if not objetbouge in markcg:
                        rect_rouge.append(zone_princ.create_rectangle(zone_princ.bbox(objetbouge)[0]-4,zone_princ.bbox(objetbouge)[1]-4,zone_princ.bbox(objetbouge)[2],zone_princ.bbox(objetbouge)[3],width=8, outline="red", tags=name))
                        zone_princ.tag_lower(name,objetbouge)
                        markcg.append(objetbouge)
                    else:
                        zone_princ.delete(name)
                        markc.remove(objetbouge)
                if objetbouge in objets_milliers:
                    if not objetbouge in markm:
                        rect_rouge.append(zone_princ.create_rectangle(zone_princ.bbox(objetbouge)[0]-4,zone_princ.bbox(objetbouge)[1]-4,zone_princ.bbox(objetbouge)[2],zone_princ.bbox(objetbouge)[3],width=8, outline="red", tags=name))
                        zone_princ.tag_lower(name,objetbouge)
                        markm.append(objetbouge)
                    else:
                        zone_princ.delete(name)
                        markm.remove(objetbouge)
                if objetbouge in objets_millgauche:
                    if not objetbouge in markmg:
                        rect_rouge.append(zone_princ.create_rectangle(zone_princ.bbox(objetbouge)[0]-4,zone_princ.bbox(objetbouge)[1]-4,zone_princ.bbox(objetbouge)[2],zone_princ.bbox(objetbouge)[3],width=8, outline="red", tags=name))
                        zone_princ.tag_lower(name,objetbouge)
                        markmg.append(objetbouge)
                    else:
                        zone_princ.delete(name)
                        markm.remove(objetbouge)
        if lock==0 and marqueur==0 and valcache.get()==0:
            for i in img_cree:
                [x1, y1, x2, y2] = zone_princ.bbox(i)
                if x1 < X < x2 and y1 < Y < y2:
                    boutoncree = i
                    clicnouveau = 1
                    objetx = zone_princ.coords(boutoncree)[0]
                    objety = zone_princ.coords(boutoncree)[1]
            if clicnouveau==1:
                if boutoncree == cree_unite:
                    cree("unite",1,"clic")
                    objetbouge=objets_unites[-1]
                    [x1, y1,x2,y2]=zone_princ.bbox(objetbouge)
                    diffx = X - x1
                    diffy = Y - y1
                if boutoncree == cree_dizaine:
                    cree("dizaine", 10, "clic")
                    objetbouge = objets_dizaines[-1]
                    [x1, y1, x2, y2] = zone_princ.bbox(objetbouge)
                    diffx = X - x1
                    diffy = Y - y1
                if nb>2 or nb==1:
                    if boutoncree == cree_centaine:
                        cree("centaine", 100, "clic")
                        objetbouge = objets_centaines[-1]
                        [x1, y1, x2, y2] = zone_princ.bbox(objetbouge)
                        diffx = X - x1
                        diffy = Y - y1
                if nb > 3 or nb == 1:
                    if boutoncree == cree_millier:
                        cree("millier", 1000, "clic")
                        objetbouge = objets_milliers[-1]
                        [x1, y1, x2, y2] = zone_princ.bbox(objetbouge)
                        diffx = X - x1
                        diffy = Y - y1
                clicnouveau=0
                DETECTION_CLIC_SUR_OBJET = 1
        if DETECTION_CLIC_SUR_OBJET==0:
            if marqueur==0:
                select=zone_princ.create_rectangle(X,Y,X,Y,outline="blue", width=5)
            else:
                select = zone_princ.create_rectangle(X, Y, X, Y, outline="red", width=5)
            rectx=X
            recty=Y
            DETECTION_CLIC_SUR_OBJET = 2

def Drag(event):
    global select, ok
    """ Gestion de l'événement bouton gauche enfoncé """
    if DETECTION_CLIC_SUR_OBJET==1 and ok==1 and marqueur==0:
        ok=0
        X = event.x
        Y = event.y
        # mise à jour de la position de l'objet
        zone_princ.moveto(objetbouge, X-diffx,Y-diffy)
        rectmarqueur=f"r{objetbouge}"
        zone_princ.moveto(rectmarqueur,(X-diffx)-8,(Y-diffy)-8)
        ok=1
    elif DETECTION_CLIC_SUR_OBJET == 2 and ok==1:
        ok=0
        X = event.x
        Y = event.y
        zone_princ.coords(select,rectx,recty,X,Y)
        ok=1

uagrouper=[]
dagrouper=[]
cagrouper=[]
def End(event):

    global DETECTION_CLIC_SUR_OBJET, objetbouge, dizaines, unites, centaines, milliers, select, agrouper,dg,cg,mg
    if DETECTION_CLIC_SUR_OBJET==1:
        zone_princ.tag_lower(objetbouge,"deco")
        if estdans(objetbouge,liste_unite) and not nb==1:
            if objetbouge in objets_dizaines:
                dizaines=dizaines-1
                unites=unites+10
                degroupe("unite","souris")
                if ordre.get()==1 and not nb==1:
                    action_range("unite")
            elif objetbouge in objets_unites and zone_princ.coords(objetbouge)[0]>(larg_canvas-larg_unite-margex):
                zone_princ.move(objetbouge,-larg_unite,0)
                if objetbouge in marku:
                    name=f'r{objetbouge}'
                    zone_princ.move(name, -larg_unite, 0)
            elif objetbouge not in objets_unites and objetbouge not in objets_dizgauche:
                if objetbouge in objets_millgauche or objetbouge in objets_milliers:
                    message("Casser d'abord le millier en centaines.")
                if objetbouge in objets_centgauche or objetbouge in objets_centaines:
                    message("Casser d'abord la centaine en dizaines.")
                retour(objetbouge)
                if objetbouge in [*marku, *markc, *markd, *markm, *markdg, *markcg, *markmg]:
                    name = f"r{objetbouge}"
                    zone_princ.moveto(name, zone_princ.bbox(objetbouge)[0] - 8, zone_princ.bbox(objetbouge)[1] - 8)
        elif estdans(objetbouge,liste_dizaine) and not nb==1:
            if objetbouge in objets_dizgauche:
                dizaines = dizaines + 1
                unites = unites - 10
                dg = dg - 1
                objets_dizaines.append(objetbouge)
                objets_dizgauche.remove(objetbouge)
                zone_princ.dtag(objetbouge,"dizgauche")
                zone_princ.addtag_withtag("dizaine",objetbouge)
                maj()
            elif objetbouge in objets_centaines:
                centaines = centaines - 1
                dizaines = dizaines + 10
                degroupe("dizaine", "souris")
                if ordre.get() == 1 and not nb==1:
                    zone_princ.update()
                    time.sleep(0.6)
                    action_range("dizaine")
            elif objetbouge not in objets_dizaines and objetbouge not in objets_centgauche:
                if objetbouge in objets_millgauche or objetbouge in objets_milliers:
                    message("Casser d'abord le millier en centaines.")
                if objetbouge in objets_unites:
                    message("Grouper d'abord 10 unités pour créer une dizaine.")
                retour(objetbouge)
                if objetbouge in [*marku,*markc,*markd,*markm,*markdg,*markcg,*markmg]:
                    name = f"r{objetbouge}"
                    zone_princ.moveto(name,zone_princ.bbox(objetbouge)[0]-8,zone_princ.bbox(objetbouge)[1]-8)

        elif int(nbcolonnes)>2 and estdans(objetbouge, liste_centaine) and not nb==1:
            if objetbouge in objets_centgauche:
                centaines = centaines + 1
                dizaines = dizaines - 10
                cg = cg - 1
                objets_centaines.append(objetbouge)
                objets_centgauche.remove(objetbouge)
                zone_princ.dtag(objetbouge,"centgauche")
                zone_princ.addtag_withtag("centaine",objetbouge)
                maj()
            elif objetbouge in objets_milliers:
                milliers = milliers - 1
                centaines = centaines + 10
                degroupe("centaine", "souris")
                if ordre.get() == 1 and not nb==1:
                    zone_princ.update()
                    time.sleep(0.6)
                    action_range("centaine")
            elif objetbouge not in objets_centaines and objetbouge not in objets_millgauche:
                if objetbouge in objets_unites:
                    message("Il faut 100 unités pour une centaine.\nPasser d'abord par la colonne des dizaines.")
                if objetbouge in objets_dizgauche:
                    message("Il faut 10 dizaines pour une centaine.\nPasser d'abord par la colonne des dizaines.")
                if objetbouge in objets_dizaines:
                    message("Il faut 10 dizaines pour une centaine.\nGrouper d'abord 10 dizaines.")
                retour(objetbouge)
                if objetbouge in [*marku,*markc,*markd,*markm,*markdg,*markcg,*markmg]:
                    name = f"r{objetbouge}"
                    zone_princ.moveto(name,zone_princ.bbox(objetbouge)[0]-8,zone_princ.bbox(objetbouge)[1]-8)
        elif int(nbcolonnes)>3 and estdans(objetbouge, liste_millier) and not nb==1:
            if objetbouge in objets_millgauche:
                milliers = milliers + 1
                centaines = centaines - 10
                mg = mg - 1
                objets_milliers.append(objetbouge)
                objets_millgauche.remove(objetbouge)
                zone_princ.dtag(objetbouge,"millgauche")
                zone_princ.addtag_withtag("millier",objetbouge)
                maj()
            elif objetbouge not in objets_milliers and not nb==1:
                if objetbouge in objets_unites:
                    message("Il faut 1000 unités pour un millier.\nPasser d'abord par les colonnes des dizaines\npuis des centaines.")
                if objetbouge in objets_dizaines:
                    message("Il faut 100 dizaines pour une millier.\nPasser d'abord par la colonne des centaines.")
                if objetbouge in objets_dizgauche:
                    message("Il faut 100 dizaines pour un millier.\nPasser d'abord par la colonne des centaines.")
                if objetbouge in objets_centgauche:
                    message("Il faut 10 centaines pour un millier.\nPasser d'abord par la colonne des centaines.")
                if objetbouge in objets_centaines:
                    message("Grouper d'abord 10 centaines pour créer un millier.")
                retour(objetbouge)
                if objetbouge in [*marku,*markc,*markd,*markm,*markdg,*markcg,*markmg]:
                    name = f"r{objetbouge}"
                    zone_princ.moveto(name,zone_princ.bbox(objetbouge)[0]-8,zone_princ.bbox(objetbouge)[1]-8)
        elif lock==0 and (not margey<zone_princ.coords(objetbouge)[1]<haut_canvas-margey or not 0<zone_princ.coords(objetbouge)[0]<larg_canvas-margex):
            if objetbouge in objets_unites:
                if objetbouge in marku:
                    name = f"r{objetbouge}"
                    zone_princ.delete(name)
                    marku.remove(objetbouge)
                objets_unites.remove(objetbouge)
                unites=unites-1
            if objetbouge in objets_dizaines:
                if objetbouge in markd:
                    name = f"r{objetbouge}"
                    zone_princ.delete(name)
                    markd.remove(objetbouge)
                objets_dizaines.remove(objetbouge)
                dizaines=dizaines-1
            if objetbouge in objets_centaines:
                if objetbouge in markc:
                    name = f"r{objetbouge}"
                    zone_princ.delete(name)
                    markc.remove(objetbouge)
                objets_centaines.remove(objetbouge)
                centaines=centaines-1
            if objetbouge in objets_milliers:
                if objetbouge in markm:
                    name = f"r{objetbouge}"
                    zone_princ.delete(name)
                    markm.remove(objetbouge)
                objets_milliers.remove(objetbouge)
                milliers=milliers-1
            if objetbouge in objets_dizgauche:
                if objetbouge in markdg:
                    name = f"r{objetbouge}"
                    zone_princ.delete(name)
                    markdg.remove(objetbouge)
                objets_dizgauche.remove(objetbouge)
                unites=unites-10
                dg=dg-1
            if objetbouge in objets_centgauche:
                if objetbouge in markcg:
                    name = f"r{objetbouge}"
                    zone_princ.delete(name)
                    markcg.remove(objetbouge)
                objets_centgauche.remove(objetbouge)
                dizaines=dizaines-10
                cg=cg-1
            if objetbouge in objets_millgauche:
                if objetbouge in markmg:
                    name = f"r{objetbouge}"
                    zone_princ.delete(name)
                    markmg.remove(objetbouge)
                objets_millgauche.remove(objetbouge)
                centaines=centaines-10
                mg=mg-1
            maj()
            zone_princ.delete(objetbouge)
        elif not nb==1:
            retour(objetbouge)
            if objetbouge in [*marku, *markc, *markd, *markm, *markdg, *markcg, *markmg]:
                name = f"r{objetbouge}"
                zone_princ.moveto(name, zone_princ.bbox(objetbouge)[0] - 8, zone_princ.bbox(objetbouge)[1] - 8)
        maj_compteurs_sep()
        if objetbouge in objets_unites and separations.get()==1:
            ajuste(objetbouge)
        if separations.get()==1:
            ajustey(objetbouge)
        DETECTION_CLIC_SUR_OBJET=0

    if DETECTION_CLIC_SUR_OBJET == 2 and ok==1:
        if marqueur==0:
            for i in objets_unites:
                if zone_princ.coords(select)[0]<zone_princ.coords(i)[0]<zone_princ.coords(select)[2] and zone_princ.coords(select)[1]<zone_princ.coords(i)[1]<zone_princ.coords(select)[3]:
                    uagrouper.append(i)
            for j in objets_dizaines:
                if zone_princ.coords(select)[0]<zone_princ.coords(j)[0]<zone_princ.coords(select)[2] and zone_princ.coords(select)[1]<zone_princ.coords(j)[1]<zone_princ.coords(select)[3]:
                    dagrouper.append(j)
            for k in objets_centaines:
                if zone_princ.coords(select)[0]<zone_princ.coords(k)[0]<zone_princ.coords(select)[2] and zone_princ.coords(select)[1]<zone_princ.coords(k)[1]<zone_princ.coords(select)[3]:
                    cagrouper.append(k)
            zone_princ.delete(select)
            if len(uagrouper)>=10:
                groupe("unite","souris")
                uagrouper.clear()
                if ordre.get()==1 and not nb==1:
                    action_range("unite")
            if len(dagrouper)>=10:
                groupe("dizaine","souris")
                dagrouper.clear()
                if ordre.get()==1 and not nb==1:
                    action_range("dizaine")
            if len(cagrouper)>=10:
                groupe("centaine","souris")
                cagrouper.clear()
                if ordre.get()==1 and not nb==1:
                    action_range("centaine")
            uagrouper.clear()
            dagrouper.clear()
            cagrouper.clear()
        else:
            for i in objets_unites:
                if zone_princ.coords(select)[0]<zone_princ.coords(i)[0]<zone_princ.coords(select)[2] and zone_princ.coords(select)[1]<zone_princ.coords(i)[1]<zone_princ.coords(select)[3]:
                    name = f"r{i}"
                    if not i in marku:
                        rect_rouge.append(zone_princ.create_rectangle(zone_princ.bbox(i)[0]-4,zone_princ.bbox(i)[1]-4,zone_princ.bbox(i)[2],zone_princ.bbox(i)[3], width=8, outline="red", tags=name))
                        zone_princ.tag_lower(name,i)
                        marku.append(i)
                    else:
                        zone_princ.delete(name)
                        marku.remove(i)
            for i in objets_dizaines:
                if zone_princ.coords(select)[0]<zone_princ.coords(i)[0]<zone_princ.coords(select)[2] and zone_princ.coords(select)[1]<zone_princ.coords(i)[1]<zone_princ.coords(select)[3]:
                    name = f"r{i}"
                    if not i in markd:
                        rect_rouge.append(zone_princ.create_rectangle(zone_princ.bbox(i)[0]-4,zone_princ.bbox(i)[1]-4,zone_princ.bbox(i)[2],zone_princ.bbox(i)[3], width=8, outline="red", tags=name))
                        zone_princ.tag_lower(name,i)
                        markd.append(i)
                    else:
                        zone_princ.delete(name)
                        markd.remove(i)
            for i in objets_dizgauche:
                if zone_princ.coords(select)[0]<zone_princ.coords(i)[0]<zone_princ.coords(select)[2] and zone_princ.coords(select)[1]<zone_princ.coords(i)[1]<zone_princ.coords(select)[3]:
                    name = f"r{i}"
                    if not i in markdg:
                        rect_rouge.append(zone_princ.create_rectangle(zone_princ.bbox(i)[0]-4,zone_princ.bbox(i)[1]-4,zone_princ.bbox(i)[2],zone_princ.bbox(i)[3], width=8, outline="red", tags=name))
                        zone_princ.tag_lower(name,i)
                        markdg.append(i)
                    else:
                        zone_princ.delete(name)
                        markdg.remove(i)
            for i in objets_centaines:
                if zone_princ.coords(select)[0]<zone_princ.coords(i)[0]<zone_princ.coords(select)[2] and zone_princ.coords(select)[1]<zone_princ.coords(i)[1]<zone_princ.coords(select)[3]:
                    name = f"r{i}"
                    if not i in markc:
                        rect_rouge.append(zone_princ.create_rectangle(zone_princ.bbox(i)[0]-4,zone_princ.bbox(i)[1]-4,zone_princ.bbox(i)[2],zone_princ.bbox(i)[3], width=8, outline="red", tags=name))
                        zone_princ.tag_lower(name,i)
                        markc.append(i)
                    else:
                        zone_princ.delete(name)
                        markc.remove(i)
            for i in objets_centgauche:
                if zone_princ.coords(select)[0]<zone_princ.coords(i)[0]<zone_princ.coords(select)[2] and zone_princ.coords(select)[1]<zone_princ.coords(i)[1]<zone_princ.coords(select)[3]:
                    name = f"r{i}"
                    if not i in markcg:
                        rect_rouge.append(zone_princ.create_rectangle(zone_princ.bbox(i)[0]-4,zone_princ.bbox(i)[1]-4,zone_princ.bbox(i)[2],zone_princ.bbox(i)[3], width=8, outline="red", tags=name))
                        zone_princ.tag_lower(name,i)
                        markcg.append(i)
                    else:
                        zone_princ.delete(name)
                        markcg.remove(i)
            for i in objets_milliers:
                if zone_princ.coords(select)[0]<zone_princ.coords(i)[0]<zone_princ.coords(select)[2] and zone_princ.coords(select)[1]<zone_princ.coords(i)[1]<zone_princ.coords(select)[3]:
                    name = f"r{i}"
                    if not i in markm:
                        rect_rouge.append(zone_princ.create_rectangle(zone_princ.bbox(i)[0]-4,zone_princ.bbox(i)[1]-4,zone_princ.bbox(i)[2],zone_princ.bbox(i)[3], width=8, outline="red", tags=name))
                        zone_princ.tag_lower(name,i)
                        markm.append(i)
                    else:
                        zone_princ.delete(name)
                        markm.remove(i)
            for i in objets_millgauche:
                if zone_princ.coords(select)[0]<zone_princ.coords(i)[0]<zone_princ.coords(select)[2] and zone_princ.coords(select)[1]<zone_princ.coords(i)[1]<zone_princ.coords(select)[3]:
                    name = f"r{i}"
                    if not i in markmg:
                        rect_rouge.append(zone_princ.create_rectangle(zone_princ.bbox(i)[0]-4,zone_princ.bbox(i)[1]-4,zone_princ.bbox(i)[2],zone_princ.bbox(i)[3], width=8, outline="red", tags=name))
                        zone_princ.tag_lower(name,i)
                        markmg.append(i)
                    else:
                        zone_princ.delete(name)
                        markmg.remove(i)
        zone_princ.delete(select)
        DETECTION_CLIC_SUR_OBJET =0

def choix_nombre(self):
    global ask
    modenormal()
    if custom.get().isdigit():
        nombreacreer = int(custom.get())
        custom.delete(0, END)
        reset("tout")
        if montrecompteur.get()==1:
            montre_tous_compteurs()
        zone_princ.focus_set()
        if nb > 3 or nb==1:
            for i in range(nombreacreer//1000):
                cree("millier", 1000, "normal")
        if nb > 2 or nb==1:
            for i in range((nombreacreer-milliers*1000)//100):
                cree("centaine", 100, "normal")
        for i in range((nombreacreer-(milliers*1000)-(centaines*100))//10):
            cree("dizaine", 10, "normal")
        for i in range(nombreacreer-milliers*1000-centaines*100-dizaines*10):
            cree("unite", 1, "normal")
        compteur.configure(text=nombre, background="#bdffd5",anchor=CENTER)
        custom_ok.configure(image=img_hasard)
        custom_interroger.configure(image=img_hasard2)
    else:
        tirage(1)

ask_montre=0
def interro(self):
    global nombreinterro,ask, check, interg, ask_montre
    if bouton_lock==0:
        montre_tous_compteurs()
        if custom.get().isdigit():
            nombreinterro=int(custom.get())
            custom.delete(0, END)
        else:
            if nb==1:
                nombreinterro = randint(1,max_u.get()+max_d.get()*10+max_c.get()*100+max_m.get()*1000)
            else:
                nombreinterro=randint(1,(10**nb)-1)
        custom_ok.configure(image=img_hasard)
        custom_interroger.configure(image=img_hasard2)
        zone_princ.focus_set()
        ask=1
        interg=0
        affichage_compteur(choix_compteur, compteur, interg)
        compteur.configure(text=nombreinterro, background="yellow", anchor=W, height=1)
        check_bouton.place(x=147, y=50,anchor=SE)
        cancel.place(x=147, y=50, anchor=NE)
        if razinterro.get()==1:
            reset("tout")
        if interrocachecompteur.get()==1:
            cache_tous_petits_compteurs()
        message(f"Mode exercice\nRéaliser le nombre {nombreinterro} à l'aide des blocs puis\ncliquer sur OK au niveau du compteur.")


def change_bouton(event):
    if custom.get().isdigit() and (int(custom.get())<10**nb or (nb==1 and int(custom.get())<10000)):
        custom_ok.configure(image=img_teacher)
        custom_interroger.configure(image=img_teacher2)
    else:
        custom.delete(0,END)
        custom_ok.configure(image=img_hasard)
        custom_interroger.configure(image=img_hasard2)


def cache(self):
    global normal,rideau, ok
    if ok==1:
        ok=0
        if valcache.get()==0:
            x0=margex
            x1=larg_canvas-margex
            y0=margey
            y1=margey
            rideau=zone_princ.create_rectangle(x0,y0,x1,y1,fill="#000",tags=("rideau",choixcache.get()))
            zone_princ.tag_lower(rideau,"deco")
            n=(haut_canvas-2*margey)/30
            for i in range (30):
                y1=y1+n
                zone_princ.coords(rideau,x0,y0,x1,y1)
                zone_princ.update()
                time.sleep(0.01)
            valcache.set(1)
            zone_princ.itemconfigure("bouton_cree",state=DISABLED)
            img_cree_unite.configure(file="images/cree_unite_inactif.png")
            img_cree_dizaine.configure(file="images/cree_dizaine_inactif.png")
            img_cree_centaine.configure(file="images/cree_centaine_inactif.png")
            img_cree_millier.configure(file="images/cree_millier_inactif.png")
        else:
            x0 = margex
            x1 = larg_canvas - margex
            y0 = margey
            y1 = haut_canvas-margey
            n = (haut_canvas - 2 * margey) / 30
            for i in range(30):
                y1 = y1 - n
                zone_princ.coords(rideau, x0, y0, x1, y1)
                zone_princ.update()
                time.sleep(0.01)
            zone_princ.delete(rideau)
            valcache.set(0)
            zone_princ.itemconfigure("bouton_cree", state=NORMAL)
            img_cree_unite.configure(file="images/cree_unite.png")
            img_cree_dizaine.configure(file="images/cree_dizaine.png")
            img_cree_centaine.configure(file="images/cree_centaine.png")
            img_cree_millier.configure(file="images/cree_millier.png")
        ok=1

custom=Entry(zone_gauche,width=7, justify=CENTER,font='arial 16')
custom.grid(row=4,column=0,columnspan=4, pady=4)
bal_custom = tix.Balloon(zone_gauche)
bal_custom.bind_widget(custom, msg='Saisir un nombre entier pour afficher une quantité de blocs ou un nombre à atteindre')
custom_ok=Button(zone_gauche,background=couleur_bouton,image=img_hasard,padx=2,pady=4,command=lambda : choix_nombre(1))
custom_ok.grid(row=5,column=0,columnspan=2)
bal_cutsom_ok = tix.Balloon(zone_gauche)
bal_cutsom_ok.bind_widget(custom_ok, msg='Afficher une quantité de blocs définie (aléatoire si non renseignée)')
custom_interroger=Button(zone_gauche,background=couleur_bouton,image=img_hasard2,padx=2,pady=4,command=lambda : interro(1))
custom_interroger.grid(row=5,column=2,columnspan=2)
bal_cutsom_interroger = tix.Balloon(zone_gauche)
bal_cutsom_interroger.bind_widget(custom_interroger, msg='Interroger sur un nombre défini (aléatoire si non renseigné) que les élèves devront réaliser avec les blocs')
boutons.extend([custom_ok,custom_interroger,custom])

def maj_canvas():
    global larg, haut, larg_canvas, haut_canvas, centre_canvas_y
    zone_princ.delete("deco")
    zone_princ.delete("rectangle")
    zone_princ.delete("fond")
    for widget in zone_princ.winfo_children():
        widget.place_forget()
    for widget in zone_haut.winfo_children():
        widget.place_forget()
    fenetre.update()
    larg = fenetre.winfo_width()
    haut = fenetre.winfo_height()
    larg_canvas=larg-100
    haut_canvas=haut-100
    centre_canvas_y = haut_canvas / 2
    zone_princ.configure(width = larg_canvas, height = haut_canvas)
    zone_logo.update()
    zone_logo.coords(logo,50, zone_logo.winfo_height() - 1)

    ancienne_larg_colonne=larg_colonne
    ancienne_haut_colonne=haut_colonne

    init()
    x_diff=larg_colonne-ancienne_larg_colonne
    x_variation =x_diff/ancienne_larg_colonne
    y_diff = haut_colonne - ancienne_haut_colonne
    y_variation = y_diff / ancienne_haut_colonne

    for i in [*objets_unites,*objets_dizgauche]:
        zone_princ.move(i,x_diff*3,y_diff)
    for i in [*objets_dizaines,*objets_centgauche]:
        zone_princ.move(i,x_diff*2,y_diff)
    for i in [*objets_centaines,*objets_millgauche]:
        zone_princ.move(i,x_diff*2,y_diff)
    for i in [*objets_centaines,*objets_millgauche]:
        zone_princ.move(i,x_diff,y_diff)

    if separations.get():
        separations.set(0)
        change_separations()
        separations.set(1)
        change_separations()

def switch_tous_compteurs(event):
    if interg==0 or (ask==1 and ask_montre==0):
        montre_tous_compteurs()
    elif ask==1 and ask_montre==1:
        cache_tous_compteurs()
    else:
        cache_tous_compteurs()


def taille_fenetre(event):
    global ok_maj_canvas
    if linux==1:
        if fenetre.attributes("-zoomed")==1 and ok_maj_canvas==1:
            ok_maj_canvas=0
            maj_canvas()
        elif not fenetre.attributes("-zoomed")==1:
            ok_maj_canvas=1
    else:
        if fenetre.state=='zoomed' and ok_maj_canvas==1:
            ok_maj_canvas=0
            maj_canvas()
        elif not fenetre.state=='zoomed':
            ok_maj_canvas=1





#Appuis sur les touches
fenetre.bind_all('<u>', lambda event: new("unite", 1,"normal"))
fenetre.bind_all('<U>', lambda event: new("unite", 1,"normal"))
fenetre.bind_all('<Control-u>', lambda event: suppr("unite"))
fenetre.bind_all('<Control-U>', lambda event: suppr("unite"))
fenetre.bind_all('<d>', lambda event: new("dizaine", 10,"normal"))
fenetre.bind_all('<Control-d>', lambda event: suppr("dizaine"))
fenetre.bind_all('<D>', lambda event: new("dizaine", 10,"normal"))
fenetre.bind_all('<Control-D>', lambda event: suppr("dizaine"))
fenetre.bind_all('<c>', lambda event: new("centaine", 100,"normal"))
fenetre.bind_all('<Control-c>', lambda event: suppr("centaine"))
fenetre.bind_all('<C>', lambda event: new("centaine", 100,"normal"))
fenetre.bind_all('<Control-C>', lambda event: suppr("centaine"))
fenetre.bind_all('<m>', lambda event: new("millier", 1000,"normal"))
fenetre.bind_all('<Control-m>', lambda event: suppr("millier"))
fenetre.bind_all('<M>', lambda event: new("millier", 1000,"normal"))
fenetre.bind_all('<Control-M>', lambda event: suppr("millier"))
fenetre.bind_all('<r>', lambda event: action_range("tout"))
fenetre.bind_all('<t>',tirage)
fenetre.bind_all('<v>', switch_tous_compteurs)
fenetre.bind_all('<R>', lambda event: action_range("tout"))
fenetre.bind_all('<T>',tirage)
fenetre.bind_all('<V>', lambda event: affichage_compteur(choix_compteur,compteur,interg))
fenetre.bind_all('<space>', lambda event: reset("tout"))
fenetre.bind_all('<Return>', lambda event:choix_nombre(1))
fenetre.bind_all('<KP_Enter>', lambda event:choix_nombre(1))
fenetre.bind_all('<l>',verr)
fenetre.bind_all('<L>',verr)
fenetre.bind_all('<Delete>',suppr_marku)
fenetre.bind_all('<s>',marque)
fenetre.bind_all('<S>',marque)
fenetre.bind_all('<KeyPress-Shift_L>',lambda event:marque("enfonce"))
fenetre.bind_all('<KeyPress-Shift_R>',lambda event:marque("enfonce"))
fenetre.bind_all('<KeyRelease-Shift_L>',lambda event:marque("relache"))
fenetre.bind_all('<KeyRelease-Shift_R>',lambda event:marque("relache"))
fenetre.bind_all('<i>',interro)
fenetre.bind_all('<I>',interro)
fenetre.bind_all('<b>',cache)
fenetre.bind_all('<B>',cache)
fenetre.bind_all('<Button-4>',lambda event: actionsouris(1))
fenetre.bind_all('<Button-5>',lambda event: actionsouris(0))
fenetre.bind_all('<Escape>',lambda event:sauvegarde(quitter))
fenetre.protocol("WM_DELETE_WINDOW",partial(sauvegarde,quitter))
fenetre.bind('<F1>',lambda event:aide())
fenetre.bind('<F11>',lambda event:switch_pleinecran())

fenetre.bind_all('<Next>', lambda event:interro(1))
fenetre.bind_all('<Prior>', lambda event:choix_nombre(1))
custom.bind('<KeyRelease>',change_bouton)
fenetre.bind_all('<x>',fois_10)

#événements souris
zone_princ.bind('<Button-1>',Clic) # évévement clic gauche (press)
zone_princ.bind('<Button-3>',Clic) # évévement clic gauche (press)

zone_princ.bind('<B1-Motion>',Drag) # événement bouton gauche enfoncé (hold down)
zone_princ.bind('<B3-Motion>',Drag) # événement bouton gauche enfoncé (hold down)

zone_princ.bind('<ButtonRelease-1>',End) # événement bouton gauche relâché (hold down)
zone_princ.bind('<ButtonRelease-3>',End) # événement bouton gauche relâché (hold down)

zone_princ.bind('<Double-Button-1>',doubleclic) # événement bouton gauche double clic
zone_princ.bind('<Double-Button-3>',doubleclic) # événement bouton gauche double clic

fenetre.bind_all('<MouseWheel>',souris)

fenetre.bind_all('<Configure>',taille_fenetre)




#Boucle principale
fenetre.mainloop()




