/*====================ÉCOLE POLYTECHNIQUE DE MONTRÉAL============================

	NOM DU FICHIER :frmediteurtrou.ui.h

	DESCRIPTION :	Fichier contenant l'implémentation de la classe frmEditeurTrou, qui permet d'éditer un trou

	AUTEUR : Martin Bisson, Anne-Marie Buki, Mylène Denis & Jean-François Pérusse

	DATE DE CRÉATION : 2004-3-17

	MISES À JOUR :

===============================================================================*/





/*------------------------------------------------------------------
  Fonction :	frmEditeurTrou::TourneSelectionHoraire

  Description :	Cette fonction tourne la sélection en sens horaire

  Paramètres :

  Valeur retournée :	void : 

  Par : 2004-3-17 Martin Bisson, Anne-Marie Buki, Mylène Denis & Jean-François Pérusse
  MAJ: 
------------------------------------------------------------------*/
void frmEditeurTrou::TourneSelectionHoraire()
{
    OrientationSelection = type_orientation((int)OrientationSelection + 1);
    if (OrientationSelection == ORIENTATION_END)
	OrientationSelection = ORIENTATION_1;
    //Ajuster la tuile ou l'objet courant pour l'orientation courante!
    if (TerrainEnCours.GetTuileCourante() != EDITEURTUILE_NONE &&
	TerrainEnCours.GetTuileCourante() != EDITEURTUILE_SQUARE)
	TerrainEnCours.SetTuileCourante(type_editeurtuile(EDITEURTUILE_UL + OrientationSelection));
    if (TerrainEnCours.GetObjetCourant() >= EDITEUROBJET_DEPART_UP
	&& TerrainEnCours.GetObjetCourant() <= EDITEUROBJET_DEPART_LEFT)
	TerrainEnCours.SetObjetCourant(type_editeurobjet(EDITEUROBJET_DEPART_UP+OrientationSelection));
    if (TerrainEnCours.GetObjetCourant() >= EDITEUROBJET_BANDE_N
	&& TerrainEnCours.GetObjetCourant() <= EDITEUROBJET_BANDE_SE)
	TerrainEnCours.SetObjetCourant(type_editeurobjet(EDITEUROBJET_BANDE_N+OrientationSelection));
    glEditeurWidget1->UpdateWidget();	
}




/*------------------------------------------------------------------
  Fonction :	frmEditeurTrou::ChargerTerrain

  Description :	Fonction qui charge un terrain

  Paramètres :
	 const QString& NomFichier : Nom du fichier contenant le terrain

  Valeur retournée :	void : 

  Par : 2004-3-17 Martin Bisson, Anne-Marie Buki, Mylène Denis & Jean-François Pérusse
  MAJ: 
------------------------------------------------------------------*/
void frmEditeurTrou::ChargerTerrain(const QString& NomFichier)
{
    //Charger d'un fichier
    TerrainEnCours.Charge(NomFichier);
    glEditeurWidget1->setTerrainActif(&TerrainEnCours);
    glEditeurWidget1->UpdateWidget();
    OrientationSelection = ORIENTATION_1;
}




/*------------------------------------------------------------------
  Fonction :	frmEditeurTrou::NouveauTerrain

  Description :	Fonction qui charge un terrain vide

  Paramètres :

  Valeur retournée :	void : 

  Par : 2004-3-17 Martin Bisson, Anne-Marie Buki, Mylène Denis & Jean-François Pérusse
  MAJ: 
------------------------------------------------------------------*/
void frmEditeurTrou::NouveauTerrain()
{
    TerrainEnCours = CEditeurTerrain();
    this->glEditeurWidget1->setTerrainActif(&TerrainEnCours);
    this->glEditeurWidget1->UpdateWidget();
    OrientationSelection = ORIENTATION_1;
}




/*------------------------------------------------------------------
  Fonction :	frmEditeurTrou::WidgetMove

  Description :	Fonction qui gère le déplacement de la souris dans le widget

  Paramètres :
	  Qt::ButtonState button : Bouton potentiellement appuyé
	 float x : position en x de la souris
	 float y : position en y de la souris

  Valeur retournée :	void : 

  Par : 2004-3-17 Martin Bisson, Anne-Marie Buki, Mylène Denis & Jean-François Pérusse
  MAJ: 
------------------------------------------------------------------*/
void frmEditeurTrou::WidgetMove( Qt::ButtonState button, float x, float y)
{
    TerrainEnCours.SetMousePosition(x,y);
    if ((button & Qt::LeftButton))
    {
	if (TerrainEnCours.GetTuileCourante() == EDITEURTUILE_SQUARE)
	    if (int(x) >= 0 && int(y) >= 0 && int(x) < GRILLE_W && int(y) < GRILLE_H)
		TerrainEnCours.setTuile(int(x)+1, int(y)+1, EDITEURTUILE_SQUARE);
    }
    glEditeurWidget1->UpdateWidget();
}




/*------------------------------------------------------------------
  Fonction :	frmEditeurTrou::WidgetClick

  Description :	Fonction qui gère le clique de la souris

  Paramètres :
	  Qt::ButtonState button : Bouton cliqué (ou relâché)
	 bool mousedown : état du bouton
	 float x : position de la souris en x
	 float y : position de la souris en y

  Valeur retournée :	void : 

  Par : 2004-3-17 Martin Bisson, Anne-Marie Buki, Mylène Denis & Jean-François Pérusse
  MAJ: 
------------------------------------------------------------------*/
void frmEditeurTrou::WidgetClick( Qt::ButtonState button, bool mousedown, float x, float y )
{
    if (button == Qt::LeftButton && mousedown)
    {
	if (!boutonEffacer->isOn()) //Ajout de tuile/objet
	{
	    if (TerrainEnCours.GetTuileCourante() != EDITEURTUILE_NONE)
	    {
		if (int(x) >= 0 && int(y) >= 0 && int(x) < GRILLE_W && int(y) < GRILLE_H)
		    TerrainEnCours.setTuile(int(x)+1, int(y)+1, TerrainEnCours.GetTuileCourante());
	    } else {
		TerrainEnCours.AjoutObjetCourant();
	    }
	    glEditeurWidget1->UpdateWidget();
	} else { //Efface!
	    TerrainEnCours.Efface();
	}
	glEditeurWidget1->UpdateWidget();
    } else if (button == Qt::RightButton && mousedown) {
	TourneSelectionHoraire();
    }
    glEditeurWidget1->UpdateWidget();
}





/*------------------------------------------------------------------
  Fonction :	frmEditeurTrou::SetTuileCarre

  Description :	Assigne courante la tuile a un carré

  Paramètres :

  Valeur retournée :	void : 

  Par : 2004-3-17 Martin Bisson, Anne-Marie Buki, Mylène Denis & Jean-François Pérusse
  MAJ: 
------------------------------------------------------------------*/
void frmEditeurTrou::SetTuileCarre()
{
    OrientationSelection = ORIENTATION_1;
    TerrainEnCours.SetTuileCourante(EDITEURTUILE_SQUARE);
    TerrainEnCours.SetObjetCourant(EDITEUROBJET_NONE);
    glEditeurWidget1->UpdateWidget();	
}





/*------------------------------------------------------------------
  Fonction :	frmEditeurTrou::SetTuileTriangle

  Description :	Assigne la tuile courante à un triangle

  Paramètres :

  Valeur retournée :	void : 

  Par : 2004-3-17 Martin Bisson, Anne-Marie Buki, Mylène Denis & Jean-François Pérusse
  MAJ: 
------------------------------------------------------------------*/
void frmEditeurTrou::SetTuileTriangle()
{
    OrientationSelection = ORIENTATION_1;
    TerrainEnCours.SetTuileCourante(type_editeurtuile(EDITEURTUILE_UL+OrientationSelection));
    TerrainEnCours.SetObjetCourant(EDITEUROBJET_NONE);    
    glEditeurWidget1->UpdateWidget();	
}





/*------------------------------------------------------------------
  Fonction :	frmEditeurTrou::Termine

  Description :	Fonction qui gère la sortie de la fenêtre de l'éditeur de trou

  Paramètres :

  Valeur retournée :	void : 

  Par : 2004-3-17 Martin Bisson, Anne-Marie Buki, Mylène Denis & Jean-François Pérusse
  MAJ: 
------------------------------------------------------------------*/
void frmEditeurTrou::Termine()
{
    int reponse;
    reponse = QMessageBox::question(
	    this,
	    "Conserver ce trou?",
	    "Désires-tu conserver les modifications que tu as faites à ce trou?",
	    "&Oui", "&Non", "&Annuler");
    
    switch (reponse)
    {
    case (0): // On enregistre le terrain
	switch(TerrainEnCours.TerrainValide())
	{
	case (0)://Si le terrain est valide
	    {
		TerrainEnCours.Enregistre(QString("terrains/") + fichieractif, glEditeurWidget1);
		accept();
		break;
	    }
	case (1): //S'il manque un trou
	    QMessageBox::warning(
		    this,
		    "Terrain invalide!",
		    "Tu dois ajouter un trou au terrain pour pouvoir l'enregistrer!"
		    );
	    break;
	case (2)://S'il manque un départ
	    QMessageBox::warning(
		    this,
		    "Terrain invalide!",
		    "Tu dois ajouter un départ au terrain pour pouvoir l'enregistrer!"
		    );
	    break;
	case (3)://S'il manque un départ ET un trou
	    QMessageBox::warning(
		    this,
		    "Terrain invalide!",
		    "Tu dois ajouter un départ et un trou au terrain pour pouvoir l'enregistrer!"
		    );
	    break;
	case (4)://S'il n'y a pas de chemin valide entre le trou et le départ
	    QMessageBox::warning(
		    this,
		    "Terrain invalide!",
		    "La balle ne peut pas se rendre au trou. Change le départ ou le trou de place."
		    );
	    break;
	}
	break;
    case (1): // On n 'enregistre pas le terrain
	reject();
	break;
    case (2): // On revient à l'éditeur
	break;
    }
}




/*------------------------------------------------------------------
  Fonction :	frmEditeurTrou::setFichierActif

  Description :	Assigne à fichieractif une nouvelle valeur

  Paramètres :
	 const QString & fic : Nom du nouveau fichier

  Valeur retournée :	void : 

  Par : 2004-3-17 Martin Bisson, Anne-Marie Buki, Mylène Denis & Jean-François Pérusse
  MAJ: 
------------------------------------------------------------------*/
void frmEditeurTrou::setFichierActif( const QString & fic )
{
    fichieractif = fic;
}


// Pour qu'on ne puisse pas fermer la fenêtre avec le petit x
void frmEditeurTrou::closeEvent(QCloseEvent *)
{
    Termine();
}

void frmEditeurTrou::btnEffaceClick()
{
    if (groupeTerrain->selected() != 0)
	groupeTerrain->selected()->toggle();
    if (GroupeObstacles->selected() != 0)
	GroupeObstacles->selected()->toggle();
    TerrainEnCours.SetTuileCourante(EDITEURTUILE_NONE);
    TerrainEnCours.SetObjetCourant(EDITEUROBJET_NONE);    
    glEditeurWidget1->UpdateWidget();	
}


QString frmEditeurTrou::getFichierActif() const
{
    return fichieractif;
}


void frmEditeurTrou::untoggleErase()
{
    if (boutonEffacer->isOn())
	boutonEffacer->toggle();
}


void frmEditeurTrou::btnEffaceToggle( bool Down )
{
    if (!Down)
	glEditeurWidget1->setCursor(Qt::ArrowCursor);
    else
	glEditeurWidget1->setCursor(Qt::BlankCursor);
    TerrainEnCours.SetModeEfface( Down );
}




//////////////////////////////////////////////////
//                                              //
//  Différents "slots" pour chacun des boutons  //
//                                              //
//////////////////////////////////////////////////
void frmEditeurTrou::SetObjetTrou()
{
    OrientationSelection = ORIENTATION_1;
    TerrainEnCours.SetTuileCourante(EDITEURTUILE_NONE);
    TerrainEnCours.SetObjetCourant(EDITEUROBJET_TROU);    
    glEditeurWidget1->UpdateWidget();
}


void frmEditeurTrou::SetObjetDepart()
{
    OrientationSelection = ORIENTATION_1;
    TerrainEnCours.SetTuileCourante(EDITEURTUILE_NONE);
    TerrainEnCours.SetObjetCourant(type_editeurobjet(EDITEUROBJET_DEPART_UP + OrientationSelection));
    glEditeurWidget1->UpdateWidget();
}


void frmEditeurTrou::btnEffacerToutClick()
{
    NouveauTerrain();
}


void frmEditeurTrou::btnChargeTerrainClick()
{
    ChoixOptionTerrainForm* dialterrain = new ChoixOptionTerrainForm(this, "Choix Option Terrain", TRUE);
    
    if (dialterrain->exec())
    {
	// L'usager a choisi un terrain
	
	QString NomDuFic;
	QDir ledir("terrains");
	ledir.setFilter(QDir::Files);
	NomDuFic = dialterrain->getFileSelected();
	delete dialterrain;
	
	ChargerTerrain(QString("terrains/")+NomDuFic);
    }
    else
    {
	delete dialterrain;
    }
}

void frmEditeurTrou::SetObjetSable()
{
    OrientationSelection = ORIENTATION_1;
    TerrainEnCours.SetTuileCourante(EDITEURTUILE_NONE);
    TerrainEnCours.SetObjetCourant(type_editeurobjet(EDITEUROBJET_TRAPPE));
    glEditeurWidget1->UpdateWidget(); 
}

void frmEditeurTrou::SetObjetEau()
{
    OrientationSelection = ORIENTATION_1;
    TerrainEnCours.SetTuileCourante(EDITEURTUILE_NONE);
    TerrainEnCours.SetObjetCourant(type_editeurobjet(EDITEUROBJET_TROUDEAU));
    glEditeurWidget1->UpdateWidget();
}

void frmEditeurTrou::TabSelected( const QString& Text )
{
    if (Text == "Terrain")
    {
	if (groupeTerrain->selected() != 0)
	    groupeTerrain->selected()->animateClick();
    } else { //Obstacles
	if (GroupeObstacles->selected() != 0)
	    GroupeObstacles->selected()->animateClick();
    }
}


void frmEditeurTrou::SetObjetBande()
{
    OrientationSelection = ORIENTATION_1;
    TerrainEnCours.SetTuileCourante(EDITEURTUILE_NONE);
    TerrainEnCours.SetObjetCourant(type_editeurobjet(EDITEUROBJET_BANDE_N + OrientationSelection));
    glEditeurWidget1->UpdateWidget();
}
