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

	NOM DU FICHIER :glEditeurWidget.cpp

	DESCRIPTION :	Fichier contenant l'implémentation du widget qui sert à l'affichage d'OpenGL

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

	DATE DE CRÉATION : 2004-3-17

	MISES À JOUR :

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

#include "CEditeurDepart.h"
#include "CEditeurTrou.h"
#include "CEditeurTerrain.h"
#include "CEditeurTrappe.h"
#include "CEditeurTroudeau.h"
#include "CEditeurBande.h"

#include "glEditeurWidget.h"



/*------------------------------------------------------------------
  Fonction :	glEditeurWidget::glEditeurWidget

  Description :	Constructeur

  Paramètres :
	 QWidget* parent : parent du widget
	 const char* nom : nom du widget

  Valeur retournée :	Aucune (constructeur) : 

  Par : 2004-3-17 Martin Bisson, Anne-Marie Buki, Mylène Denis & Jean-François Pérusse
  MAJ: 
------------------------------------------------------------------*/
glEditeurWidget::glEditeurWidget(QWidget* parent, const char* nom)
    : QGLWidget(parent, nom)
{
    TerrainActif = 0;
    DrawingPixmap = false;
}




/*------------------------------------------------------------------
  Fonction :	glEditeurWidget::~glEditeurWidget

  Description :	Destructeur du widget

  Paramètres :

  Valeur retournée :	 : 

  Par : 2004-3-17 Martin Bisson, Anne-Marie Buki, Mylène Denis & Jean-François Pérusse
  MAJ: 
------------------------------------------------------------------*/
glEditeurWidget::~glEditeurWidget()
{
    CEditeurDepart::DechargeTextures();
    CEditeurTrou::DechargeTextures();
    CEditeurTerrain::DechargeTextures();
    CEditeurTrappe::DechargeTextures();
    CEditeurTroudeau::DechargeTextures();
    CEditeurBande::DechargeTextures();
}




/*------------------------------------------------------------------
  Fonction :	glEditeurWidget::initializeGL

  Description :	Fonction qui initialise l'OpenGL

  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 glEditeurWidget::initializeGL()
{
    glClearColor(1,1,1,0);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    CEditeurDepart::ChargeTextures();
    CEditeurTrou::ChargeTextures();
    CEditeurTerrain::ChargeTextures();
    CEditeurTrappe::ChargeTextures();
    CEditeurTroudeau::ChargeTextures();
    CEditeurBande::ChargeTextures();
}




/*------------------------------------------------------------------
  Fonction :	glEditeurWidget::paintGL

  Description :	Fonction qui effectue le rendu OpenGL

  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 glEditeurWidget::paintGL()
{
    makeCurrent();
    glClear(GL_COLOR_BUFFER_BIT);
    
    if (TerrainActif)
    {
	TerrainActif->Affiche(DrawingPixmap);
	if (!DrawingPixmap)
	    TerrainActif->DrawSelection();
    }
    if (!DrawingPixmap)
	CEditeurTerrain::AfficheGrille();
    if (!DrawingPixmap)
	TerrainActif->DrawEfface();
}




/*------------------------------------------------------------------
  Fonction :	glEditeurWidget::resizeGL

  Description :	Fonction qui s'occupe de la redimension du widget

  Paramètres :
	 int w : largeur du widget
	 int h : hauteur du widget

  Valeur retournée :	void : 

  Par : 2004-3-17 Martin Bisson, Anne-Marie Buki, Mylène Denis & Jean-François Pérusse
  MAJ: 
------------------------------------------------------------------*/
void glEditeurWidget::resizeGL(int w, int h)
{
    glViewport(0,0,w,h);
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    //On affiche un peu plus grand afin de voir
    //les bordures extérieures.
    gluOrtho2D(-BORDER_WIDTH, GRILLE_W+BORDER_WIDTH, -BORDER_WIDTH, GRILLE_H+BORDER_WIDTH);
    
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}




////////////////////////////////////////////
//                                        //
//  Fonctions surchargées qui gèrent les  //
//  événements de la souris.              //
//                                        //
////////////////////////////////////////////

#define MOUSE_X ((float) ((e->x() / (float)width()) * ((float)GRILLE_W + 2.0f*BORDER_WIDTH) - BORDER_WIDTH))
#define MOUSE_Y (GRILLE_H+2.0f*BORDER_WIDTH) - (float) (((e->y() / (float) height()) * (GRILLE_H+2.0f*BORDER_WIDTH) + BORDER_WIDTH))

void glEditeurWidget::mousePressEvent(QMouseEvent * e)
{
    emit MouseClick(e->button(), BUTTON_DOWN,
		    MOUSE_X,
		    MOUSE_Y
		    );
}

void glEditeurWidget::mouseReleaseEvent(QMouseEvent * e)
{
    emit MouseClick(e->button(), BUTTON_UP,
		    MOUSE_X,
		    MOUSE_Y
		    );
}

void glEditeurWidget::mouseMoveEvent(QMouseEvent * e)
{
    emit MouseMove(e->state(), \
		   MOUSE_X,\
		   MOUSE_Y
		   );
}




/*------------------------------------------------------------------
  Fonction :	glEditeurWidget::resizeEvent

  Description :	Fonction qui gère le comportement lors de la redimension

  Paramètres :
	 QResizeEvent * e : information sur la redimension

  Valeur retournée :	void : 

  Par : 2004-3-17 Martin Bisson, Anne-Marie Buki, Mylène Denis & Jean-François Pérusse
  MAJ: 
------------------------------------------------------------------*/
void glEditeurWidget::resizeEvent(QResizeEvent * e)
{
    int min;
    
    if (e->size().width() > e->size().height())
	min = e->size().height();
    else
	min = e->size().width();
    
    resize(min, min);
    resizeGL(min, min);
    updateGL();
}




/*------------------------------------------------------------------
  Fonction :	glEditeurWidget::getTerrainActif

  Description :	retourne le terrain actif

  Paramètres :

  Valeur retournée :	CEditeurTerrain const* : terrain actif

  Par : 2004-3-17 Martin Bisson, Anne-Marie Buki, Mylène Denis & Jean-François Pérusse
  MAJ: 
------------------------------------------------------------------*/
CEditeurTerrain const* glEditeurWidget::getTerrainActif() const
{
    return this->TerrainActif;
}




/*------------------------------------------------------------------
  Fonction :	glEditeurWidget::setTerrainActif

  Description :	Assigne une valeur au terrain actif

  Paramètres :
	 CEditeurTerrain* NouveauTerrain : Nouveau terrain actif

  Valeur retournée :	void : 

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




/*------------------------------------------------------------------
  Fonction :	glEditeurWidget::UpdateWidget

  Description :	Fonction qui actualise le widget

  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 glEditeurWidget::UpdateWidget()
{
    updateGL();
}
