let interface_complete () = 
        let c_ici = ref 4 in
        let n_ici = ref 2 in
        let m_ici = ref 2 in
                
                (** On utilise trois paramètres courant pour n, m, et c. *)

        let instance_ici = ref (Resolution.creer_instance_random ~m:!m_ici ~n:!n_ici ~c:!c_ici ()) in
        let plateau_ici = ref (Resolution.plateau_of_instance !instance_ici) in
                
                (** Et deux paramètres courant pour l'instance locale et le plateau local. *)

                let trait_char c = (match c with
                        
                        (** Pour afficher l'aide. *)

                        | 'h'  -> aide_ic ()
                        
                        (** Pour quitter. *)

                        | '\027' -> raise Fin
                        
                        (** Pour effacer l'écran. *)

                        | '\n' | 'e'-> Graphics.clear_graph ()
                        
                        (** Pour changer le nombre de couleurs. *)

                        | 'u'  -> (c_ici := new_c_ic ();
                                        change_echelle_globale !c_ici ();
                                        actualise_taille ~s:taille_piece ~n:!n_ici ~m:!m_ici ();
                                        titre_ic ~c:!c_ici ~n:!n_ici ~m:!m_ici;)
(*                        (** Pour changer l'échelle de couleur. *)*)
(*                        | 'c'  -> (change_echelle_globale !c_ici ();*)
(*                                        actualise_taille ~s:taille_piece ~n:!n_ici ~m:!m_ici ();*)
(*                                        afficher_instance !instance_ici;*)
(*                                        titre_ic ~c:!c_ici ~n:!n_ici ~m:!m_ici;)*)
                        
                        (** Pour changer n. *)

                        | 'n'  -> (n_ici := new_n_ic ();
                                        actualise_taille ~s:taille_piece ~n:!n_ici ~m:!m_ici ();
                                        titre_ic ~c:!c_ici ~n:!n_ici ~m:!m_ici;)
                        
                        (** Pour changer m. *)

                        | 'm'  -> (m_ici := new_m_ic ();
                                        actualise_taille ~s:taille_piece ~n:!n_ici ~m:!m_ici ();
                                        titre_ic ~c:!c_ici ~n:!n_ici ~m:!m_ici;)
                        
                        (** Pour charger une instance enregistrée dans un fichier. Actualise les paramètres courants (c, n, m). *)

                        | 'b'  -> (instance_ici := (browse_instance ());
                                        c_ici := !instance_ici.ci;
                                        change_echelle_globale !c_ici ();
                                        n_ici := !instance_ici.ni;
                                        m_ici := !instance_ici.mi;
                                        actualise_taille ~s:taille_piece ~n:!n_ici ~m:!m_ici ();
                                        afficher_instance !instance_ici;
                                        titre_ic ~c:!c_ici ~n:!n_ici ~m:!m_ici;)
                        
                        (** Pour choisir une pièce, sa position, changer l'instance courante, et la réafficher. *)

                        | 'p'  -> (
                                  let piece_courante = (ask_piece ~c:!c_ici ()) in
                                  let (i0, j0) = (ask_position ~n:!n_ici ~m:!m_ici ~s:taille_piece ()) in
                                  let p = (Resolution.matrix_of_list ~n:!n_ici ~m:!m_ici ~l:(!instance_ici.pi)) in
                                  p.(i0).(j0) <- piece_courante;
                                  instance_ici := { ci = !c_ici; ni = !n_ici; mi = !m_ici; pi = (Resolution.list_of_matrix p)};
                                  actualise_taille ~s:taille_piece ~n:!n_ici ~m:!m_ici ();
                                  afficher_instance !instance_ici;
                                  titre_ic ~c:!c_ici ~n:!n_ici ~m:!m_ici;
                                  )
                        
                        (** Pour vérifier la validité du plateau courant. *)

                        | 'v'  ->(
                                  (try (Resolution.est_valide_plateau (Resolution.plateau_of_instance !instance_ici)) with
                                        | Resolution.Solution_trouvee -> 
                                                zenity_info "Le plateau affiché à l'écran <span color='red'>est valide</span>.";
                                        | Resolution.Mauvais_tableau  -> (* n'arrive jamais. *)
                                                zenity_info "Le plateau affiché à l'écran <span color='red'>n'est pas valide</span> \n<b>car</b> il est mal construit.";
                                        | Resolution.Erreur_compatibilite_h(ii0,jj0)        ->
                                                zenity_info ("Le plateau affiché à l'écran <span color='red'>n'est pas valide</span> \n<b>car</b> il y a une incompatibilité horizontale, entre la case ("^(string_of_int ii0)^","^(string_of_int jj0)^") et ("^(string_of_int (ii0 + 1))^","^(string_of_int jj0)^").");
                                        |Resolution.Erreur_compatibilite_v(ii1,jj1)        -> 
                                                zenity_info ("Le plateau affiché à l'écran <span color='red'>n'est pas valide</span> \n<b>car</b> il y a une incompatibilité verticale, entre la case ("^(string_of_int ii1)^","^(string_of_int jj1)^") et ("^(string_of_int ii1)^","^(string_of_int (jj1 + 1))^").");
                                );
                                  
                                ) 
                        
                        (** Pour résoudre l'instance courante. *)

                        | 'r'  -> (afficher_instance !instance_ici;
                                  zenity_info "La resolution de l'instance courante va commencer. Confirmez-vous ?";
                                  Temps.lancer_chrono ();
                                  Graphics.set_window_title "Projet Puzzle : resolution EN COURS ...";
                                  try (
                                  plateau_ici := resoud_naivement_graphique !instance_ici;
                                  instance_ici := instance_of_plateau !plateau_ici;
                                  afficher_instance !instance_ici;
                                  Graphics.set_window_title "Projet Puzzle : resolution terminee (UNE solution est affichee)";
(*                                  zenity_info "La résolution de l'instance courante est terminée.";*)
(*                                  faire "export date2=`date \"+%Hh:%Mm-%Ss\"`";*)
                                  zenity_info ("La résolution de l'instance courante avec affichage intermédiaire est terminée.\nTemps interne mis = <b><span color='red'>"^(Temps.temps_chrono ())^"</span></b>\nRésolution lancée avec c="^(string_of_int !c_ici)^", n="^(string_of_int !n_ici)^", m="^(string_of_int !m_ici));
(*                                  zenity_info ("La résolution de l'instance courante est terminée.\nTemps interne mis = <b><span color='red'>"^(Temps.temps_chrono ())^"</span></b>\nRésolution lancée à $date1; avec c="^(string_of_int !c_ici)^", n="^(string_of_int !n_ici)^", m="^(string_of_int !m_ici)^";\n  et résolution terminée à $date2");*)
                                  ) with 
                                          | Resolution.Aucune_solution | Resolution.Mauvais_tableau | Resolution.Erreur_compatibilite_h(_,_) | Resolution.Erreur_compatibilite_v(_,_) -> (fail_recherche !instance_ici ());)
                        
                        (** Pour résoudre l'instance courante sans afficher les plateaux courants. *)

                        | 'k'  -> (afficher_instance !instance_ici;
                                  zenity_info "La resolution de l'instance courante sans affichages intermédiaires va commencer. Confirmez-vous ?";
                                  Temps.lancer_chrono ();
                                  Graphics.set_window_title "Projet Puzzle : resolution EN COURS ...";
                                  try (
                                  plateau_ici := resoud_naivement_no_graphique !instance_ici;
                                  instance_ici := instance_of_plateau !plateau_ici;
                                  afficher_instance !instance_ici;
                                  Graphics.set_window_title "Projet Puzzle : resolution terminee (UNE solution est affichee)";
(*                                  zenity_info "La résolution de l'instance courante est terminée.";*)
(*                                  faire "export date2=`date \"+%Hh:%Mm-%Ss\"`";*)
                                  zenity_info ("La résolution de l'instance courante sans affichage intermédiaire est terminée.\nTemps interne mis = <b><span color='red'>"^(Temps.temps_chrono ())^"</span></b>\nRésolution lancée avec c="^(string_of_int !c_ici)^", n="^(string_of_int !n_ici)^", m="^(string_of_int !m_ici));
(*                                  zenity_info ("La résolution de l'instance courante est terminée.\nTemps interne mis = <b><span color='red'>"^(Temps.temps_chrono ())^"</span></b>\nRésolution lancée à $date1; avec c="^(string_of_int !c_ici)^", n="^(string_of_int !n_ici)^", m="^(string_of_int !m_ici)^";\n  et résolution terminée à $date2");*)
                                  ) with 
                                          | Resolution.Aucune_solution | Resolution.Mauvais_tableau | Resolution.Erreur_compatibilite_h(_,_) | Resolution.Erreur_compatibilite_v(_,_) -> (fail_recherche !instance_ici ());)
                        
                        (** Pour sauver l'image courante en un fichier .jpeg. *)

                        | 'i'        -> (capture_ecran ();
(*                                        actualise_taille ~s:taille_piece ~n:!n_ici ~m:!m_ici ();*)
                                        afficher_instance !instance_ici;
                                        titre_ic ~c:!c_ici ~n:!n_ici ~m:!m_ici;)
                        
                        (** Pour sauver l'instance courante en un fichier .instance. *)

                        | 's'        -> (ecrit_instance_browse !instance_ici ();
(*                                        actualise_taille ~s:taille_piece ~n:!n_ici ~m:!m_ici ();*)
                                        afficher_instance !instance_ici;
                                        titre_ic ~c:!c_ici ~n:!n_ici ~m:!m_ici;)
                        
                        (** Pour générer une instance aléatoire avec les paramètres locaux. *)

                        | ' '        -> (
                                        actualise_taille ~s:taille_piece ~n:!n_ici ~m:!m_ici ();
                                        instance_ici := (aff_random ~m:!m_ici ~n:!n_ici ~c:!c_ici);
(*                                        afficher_instance !instance_ici;*)
                                        titre_ic ~c:!c_ici ~n:!n_ici ~m:!m_ici;)
                        
                        (** Pour générer une nouvelle instance aleatoire, ayant une solution, avec les parametres courant, et l'afficher. *)

                        | 'w'        -> ( instance_ici := (Resolution.generer_instance_solution ~n:!n_ici ~m:!m_ici ~c:!c_ici ());
                                        actualise_taille ~s:taille_piece ~n:!n_ici ~m:!m_ici ();
                                        afficher_instance !instance_ici;
                                        titre_ic ~c:!c_ici ~n:!n_ici ~m:!m_ici;)
                        
                        (** Pour générer une solution aleatoire, avec les parametres courant, et l'afficher. *)

                        | 'y'        -> ( plateau_ici := (Resolution.generer_plateau_solution ~n:!n_ici ~m:!m_ici ~c:!c_ici ());
                                        instance_ici := (Resolution.instance_of_plateau !plateau_ici);
                                        actualise_taille ~s:taille_piece ~n:!n_ici ~m:!m_ici ();
                                        afficher_instance !instance_ici;
                                        titre_ic ~c:!c_ici ~n:!n_ici ~m:!m_ici;)
                        |   _  -> ()
                ) in
        (squel 
        ~f_init:(fun () -> 
                (zenity_info "Lancement de l'interface utilisateur du projet Puzzle en cours...";
                init_fenetre ~x:700 ~y:700 ();
                Graphics.open_graph " 700x700";
                Graphics.set_window_title "Projet Puzzle";
                Graphics.moveto 0 0;
                n_ici := new_m_ic ();
                m_ici := new_n_ic ();
                c_ici := new_c_ic ();
                change_echelle_globale !c_ici ();
                actualise_taille ~s:taille_piece ~n:!n_ici ~m:!m_ici ();
                titre_ic ~c:!c_ici ~n:!n_ici ~m:!m_ici;
                instance_ici := (Resolution.creer_instance_random ~m:!m_ici ~n:!n_ici ~c:!c_ici ());
                plateau_ici := (Resolution.plateau_of_instance !instance_ici);
                afficher_instance !instance_ici;
                print_string "\nINIT OK !";
(*                read_line ();*)
                ) )
        ~f_end:(fun () -> (Graphics.clear_graph(); print_string "\nJ'espere que ca vous a fait rire :D !"Graphics.close_graph (); zenity_info "Merci d'avoir utilise ce programme ecrit par <b>Lilian BESSON</b>.\n\tProjet Puzzle - ENS de Cachan 2012 (c) et (r)."; exit(0);))
        ~f_key:(trait_char)
        ~f_mouse:(fun x y -> 
        (
                                  let piece_courante = (ask_piece ~c:!c_ici ()) in
                                  let (i0, j0) = ( ((x - 10) / (2*taille_piece+4)), ((y - 10) / (2*taille_piece+4))) in
                                  let p = (Resolution.matrix_of_list ~n:!n_ici ~m:!m_ici ~l:(!instance_ici.pi)) in
                                  p.(i0).(j0) <- piece_courante;
                                  instance_ici := { ci = !c_ici; ni = !n_ici; mi = !m_ici; pi = (Resolution.list_of_matrix p)};
                                  actualise_taille ~s:taille_piece ~n:!n_ici ~m:!m_ici ();
                                  afficher_instance !instance_ici;
                                  titre_ic ~c:!c_ici ~n:!n_ici ~m:!m_ici;
                                  )
                )
        ~f_except:(fun e -> ()))