#include "interface.h"

//constructeur : création d'une grille, initialisation des widgets, et
//on place les widgets dans le grille
interface::interface() :
  lagrille(10,5,false), 
  scrollzone(),
  m_button1("Ecrire dans le fichier"),
  m_button2("Valider cette regle"),
  saisieAngle(),
  saisieAxiome(),
  saisieSymboleRegle(),
  saisieRegle(),
  labelAxiome("Axiome"),
  labelAngle("Angle"),
  labelSymboleRegle("Symbole de la regle"),
  labelRegle("Regle"),
  saisieNbFois(),
  boutonAppliqueRegle("Develloper"),
  labelNbFois("Niveau de developpement"),
  saisieNvAxiome(),
  boutonCreeLSyst("Creer le L-Systeme"),
  boutonDessine("Dessiner"),
  labelTitre("Le L-Systeme"),
  boutonClean("Effacer"),
  labelDestNvLsyst("Destination(/Exemple/monexemple.txt): "),
  saisieDestNvLsyst(),
  separation(),
  labelDestLsyst("Destination du fichier a charger"),
  saisieDestLsyst(),
  labelTailleSeg("Rentrer la taille d'un segment (25 par defaut)"),
  saisieTailleSeg()
{
  tailleTrait = 25;
  set_title("Les L-Systemes");
  set_border_width(10);
  set_usize(800,700);
  scrollzone.add_with_viewport(lagrille);
  m_button1.clicked.connect(slot(this, &interface::ecrireLSyst));
  lagrille.attach(m_button1, 2, 3, 2, 3, GTK_FILL, 0, 0, 0); 
  m_button2.clicked.connect(slot(this, &interface::validerRegle));
  lagrille.attach(m_button2, 4, 5, 1, 2, GTK_FILL, 0, 0, 0);
  saisieAngle.set_editable(true);
  lagrille.attach(saisieAngle, 3, 4, 0, 1, GTK_FILL, 0, 0, 0);
  saisieAxiome.set_editable(true);
  lagrille.attach(saisieAxiome, 1, 2, 0, 1, GTK_FILL, 0, 0, 0); 
  saisieSymboleRegle.set_editable(true);
  lagrille.attach(saisieSymboleRegle, 1, 2, 1, 2, GTK_FILL, 0, 0, 0);
  saisieRegle.set_editable(true);
  lagrille.attach(saisieRegle, 3, 4, 1, 2, GTK_FILL, 0, 0, 0);
  lagrille.attach(labelAxiome,0,1,0,1,GTK_FILL,0,0,0);
  lagrille.attach(labelAngle,2,3,0,1,GTK_FILL,0,0,0);
  lagrille.attach(labelSymboleRegle,0,1,1,2,GTK_FILL,0,0,0);
  lagrille.attach(labelRegle,2,3,1,2,GTK_FILL,0,0,0);
  lagrille.attach(saisieNbFois,1,2,5,6,GTK_FILL,0,0,0);
  boutonAppliqueRegle.clicked.connect(slot(this, &interface::developpeLSyst));
  lagrille.attach(labelNbFois,0,1,5,6,GTK_FILL,0,0,0);
  lagrille.attach(boutonAppliqueRegle,2,3,5,6,GTK_FILL,0,0,0);
  lagrille.attach(saisieNvAxiome,3,4,5,6,GTK_FILL,0,0,0);
  boutonCreeLSyst.clicked.connect(slot(this, &interface::creeLSyst));
  lagrille.attach(boutonCreeLSyst,2,3,4,5,GTK_FILL,0,0,0);
  boutonDessine.clicked.connect(slot(this, &interface::dessineAxiome));
  lagrille.attach(boutonDessine,2,3,7,8,GTK_FILL,0,0,0);
  lagrille.attach(labelTitre,0,5,3,4,GTK_FILL,0,0,0);
  boutonClean.clicked.connect(slot(zone, &zoneDessin::erase));
  lagrille.attach(boutonClean,2,3,9,10,GTK_FILL,0,0,0);
  lagrille.attach(labelDestNvLsyst,0,1,2,3,GTK_FILL,0,0,0);
  lagrille.attach(saisieDestNvLsyst,1,2,2,3,GTK_FILL,0,0,0);
  lagrille.attach(separation,0,5,6,7,GTK_FILL,0,0,0);
  lagrille.attach(labelDestLsyst,0,1,4,5,GTK_FILL,0,0,0);
  lagrille.attach(saisieDestLsyst,1,2,4,5,GTK_FILL,0,0,0);
  lagrille.attach(labelTailleSeg,0,1,7,8,GTK_FILL,0,0,0);
  lagrille.attach(saisieTailleSeg,1,2,7,8,GTK_FILL,0,0,0);
  zone.size(600, 800);
  lagrille.attach(zone,0,5,8,9,GTK_FILL,GTK_FILL,0,0);
  add(scrollzone);
  show_all();
}

//permet de mettre la règle saisie dans un vecteur de string
void interface::validerRegle(){  
  string symboleRegle = saisieSymboleRegle.get_text();
  string uneRegle = saisieRegle.get_text();
  string laRegle = symboleRegle+"devient"+uneRegle;
  ensRegle.push_back(laRegle);
  cout<<laRegle<<endl;
  saisieSymboleRegle.set_text("");
  saisieRegle.set_text("");
}

//permet d'écrire un l_système dans un fichier avec un format spécifique
void interface::ecrireLSyst(){
  angle = saisieAngle.get_text();
  axio = saisieAxiome.get_text();
  saisieAngle.set_text("");
  saisieAxiome.set_text("");
  string nomfichier = saisieDestNvLsyst.get_text();
  if(nomfichier == ""){
    labelTitre.set_text("Rentrer un nom de fichier");
  }
  else{
    labelTitre.set_text("");
    ofstream fichier;
    string nom_fichier(nomfichier);
    fichier.open(nom_fichier.c_str()); //ouverture du fichier à créer
    if(fichier.fail()){
      labelTitre.set_text("Erreur ouverture fichier");
    }
    else{
     labelTitre.set_text("");
     fichier <<angle<<";"<<axio<<";";   //ecriture des données
     for(iterateur = ensRegle.begin(); iterateur< ensRegle.end(); iterateur++){
       fichier<< *iterateur<<";";
     }   
     fichier.close();
    }
    saisieAxiome.set_text("");
    saisieAngle.set_text("");
    labelTitre.set_text("Fichier cree!");
  }
}
//permet de charger un l_systeme à partir d'un fichier texte.
//on fera appel à la classe lecteur
void interface::creeLSyst(){
  ifstream fichierALire;
  string nomfichierLsyst = saisieDestLsyst.get_text();
  if(nomfichierLsyst == ""){
    labelTitre.set_text("Rentrer un nom de fichier");
  }
  string nom_fichier(nomfichierLsyst);
  fichierALire.open(nom_fichier.c_str());
  if(fichierALire.fail()){
    labelTitre.set_text("Erreur ouverture fichier");
  }
  else{
    fichierALire.close();
    labelTitre.set_text("");
    saisieNbFois.set_text("");
    saisieNvAxiome.set_text("");
    lecteur l = lecteur(nomfichierLsyst);
    l.appliqueRegleAxiome();
    l.creeLSysteme();
    l_syst = l.getL_systeme();
    angleLSyst = l_syst.getAngle();
    saisieDestLsyst.set_text("");
    labelTitre.set_text("L-systeme cree!");
  }
}
//callback du bouton pour developper n niveaux du l_systeme
//on utilise la classe l_systeme et ses méthodes
void interface::developpeLSyst(){
  string s = saisieNbFois.get_text(); //on récupère le niveau de developpement
  const char* nb = s.c_str();
  int n = atoi(nb);   
  l_syst.developpeNiveau(n);
  string axio1 = l_syst.getSymbNvAxiome();
  saisieNvAxiome.set_text(axio1);
  
  }

//permet dessiner l'axiome. On appel pour l'interpreteGraphique de 
//chaque symbole de l'axiome la méthode "dessine" de cette classe
  
void interface::dessineAxiome(){
  zone.erase();
  string t = saisieTailleSeg.get_text();
  if(t !=""){
    tailleTrait = atoi(t.c_str());
  }
  
  //initialisation des points de départ
  positionX=500;
  positionY=500;
  positionNvX=500;
  positionNvY=500;
  positionMemX=500;
  positionMemY=500;
  angle2 = 0;
  
  vector<symbole> listeSymb;
  vector<symbole>::iterator ite;
  axiomeLsyst = l_syst.getNouvelAxiome();
  listeSymb = axiomeLsyst.getVector(); //liste de symbole de l'axiome
  //parcours des symboles de l'axiome et on les interprête
  for(ite=listeSymb.begin(); ite<listeSymb.end(); ite++){
    symbole syAxio = *ite;
    interpreteGraphique logo = syAxio.getInterpreteGraphique();
    cout<<"le logo est : "<<logo.getLettre()<<", "<<logo.estRepresentable()<<endl;
    logo.dessine(zone, angleLSyst, angle2, positionX, positionY, positionMemX, positionMemY, tailleTrait);
    //on change les positions courantes par les nouvelles
    positionX = logo.getNouvelX(); 
    positionY = logo.getNouvelY();
    positionMemX = logo.getMemX();
    positionMemY = logo.getMemY();
    angle2 = logo.getNvAngle();  //le nouveau cap à suivre
  }
  cout<<"******************fin du dessin*********************"<<endl;
}

int main (int argc, char *argv[])
{
  Gtk::Main monLSyst(argc, argv);
  interface interface;
  monLSyst.run();
  return 0;
}
