/*****************************************************************************
 *
 *	Copyright (C) 2003 Cédric Brégardis <cedric.bregardis@free.fr>
 *
 *	This file is part of BRIQUOLO
 *
 *	BRIQUOLO is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License as published by
 *	the Free Software Foundation; either version 2 of the License, or
 *	(at your option) any later version.
 *
 *	BRIQUOLO is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with BRIQUOLO; if not, write to the Free Software
 *	Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *****************************************************************************/
#include "MOGL_Fenetre.h"
#include "MOGL_Temps.h"
#include <fstream>

#ifdef WIN32
#include <io.h>
#else
#include <unistd.h>
#endif

MOGL_Fenetre::MOGL_Fenetre(const char * p_Titre):_ResolutionX(640), _ResolutionY(480), _NbBitParPixel(16), _FinBoucle(false),
                                                 _Fullscreen(false),_GrabCurseur(false),
                                                 _RepetitionDelai(SDL_DEFAULT_REPEAT_DELAY), _RepetitionIntervalle(SDL_DEFAULT_REPEAT_INTERVAL),
                                                 _NumeroImage(0), _ExisteFenetre(false), _CacheSouris(true), _bManualResize(false)

{
	cout<<p_Titre<<endl;
	// Affichage des extensions
	//cout<<glGetString(GL_EXTENSIONS)<<endl;
	if (p_Titre!=NULL)
	{
		_Titre=new char[strlen(p_Titre)+1];
		strcpy(_Titre,p_Titre);
	}
	SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_JOYSTICK);
	SDL_EnableUNICODE(1);
	_NombreJoysticks=SDL_NumJoysticks();
	_Joysticks=new SDL_Joystick * [_NombreJoysticks];
	for(unsigned int i=0; i<_NombreJoysticks; i++)
	{
		_Joysticks[i]=NULL;
	}

	// On récupère la profaondeur d'affichage
	if (SDL_GetVideoInfo())
	{
		_NbBitParPixel = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
	}

	// On récupère les résolutions
	SDL_Rect **modes;
	modes = SDL_ListModes(NULL, SDL_OPENGL | SDL_FULLSCREEN);
	cout << "SDL tells that the following fullscreen resolutions are available:" << endl;
	for(unsigned int i = 0; modes[i]; i++)
	{
		cout << modes[i]->w << "x" << modes[i]->h << " ";
		modes[i]->x = 0;
		modes[i]->y = 0;
		_SetResolution.insert(MOGL_Resolution(modes[i]->w, modes[i]->h));
	}
	cout << endl;
	// Si la liste est vide, on ajoute la liste des resolution non fullscreen
	if (!modes[0])
	{
		cout << "There is no fullscreen resolution! So we search non-fullscreen resolution." << endl;
		cout << "SDL tell us that the following non-fullscreen resolution are available:" << endl;
		modes = SDL_ListModes(NULL, SDL_OPENGL);
		for(unsigned int i = 0; modes[i]; i++)
		{
			cout << modes[i]->w << "x" << modes[i]->h << " ";
			modes[i]->x = 0;
			modes[i]->y = 0;
			_SetResolution.insert(MOGL_Resolution(modes[i]->w, modes[i]->h));
		}
		cout << endl;
	}
}


MOGL_Fenetre::~MOGL_Fenetre()
{
    SDL_Quit();
    delete [] _Titre;
    for(unsigned int i=0; i<_NombreJoysticks; i++)
    {
        if (_Joysticks[i]==NULL)
        {
            SDL_JoystickClose(_Joysticks[i]);
        }
    }
    delete [] _Joysticks;
}

MOGL_Fenetre::MOGL_Set_Resolution MOGL_Fenetre::GetAvailableResolution() const
{
    return _SetResolution;
}

bool MOGL_Fenetre::Initialiser()
{
	const SDL_VideoInfo* info;
	int flags = 0;

	if (_Fullscreen)
	{
		cout << "Fullscreen is true" << endl;
		flags = SDL_OPENGL | SDL_FULLSCREEN;
	}
	else
	{
		cout << "Fullscreen is false" << endl;
		flags = SDL_OPENGL | SDL_RESIZABLE;
	}

	// On regarde si notre résolution est bien disponible
	cout << "Trying resolution from configuration file..." << endl;
	MOGL_Resolution rect (_ResolutionX, _ResolutionY);
	if (_SetResolution.find(rect) == _SetResolution.end())
	{
		// On n'a pas trouvé la résolution
		cerr<<"Resolution "<<_ResolutionX<<"x"<<_ResolutionY<<" unknown."<<endl;
		cout << "Trying default static resolution..." << endl;
		// On reessaye avec 640x480
		rect.w = 640;
		rect.h = 480;
		if (_SetResolution.find(rect) == _SetResolution.end())
		{
			// On n'a pas trouvé la résolution
			cerr<<"Resolution "<<rect.w<<"x"<<rect.h<<" unknown."<<endl;
			cout << "Trying the smallest resolution returned by SDL..." << endl;
			rect.w = _SetResolution.begin()->w;
			rect.h = _SetResolution.begin()->h;
			// On essaye pour finir la résolution la plus faible
			if (_SetResolution.find(rect) == _SetResolution.end())
			{
				// On n'a pas trouvé la résolution
				cerr<<"Resolution "<<rect.w<<"x"<<rect.h<<" unknown."<<endl;
				// On ne va pas plus loin, on quitte la fonction
				return false;
			}
		}
	}
	_ResolutionX = rect.w;
	_ResolutionY = rect.h;
	cout<<"Resolution "<<_ResolutionX<<"x"<<_ResolutionY<<endl;

	// Maintenant on crée la fenêtre
	_SurfaceSDL = _CreerFenetre(_NbBitParPixel, flags);
	if (_SurfaceSDL == NULL)
	{
		// Erreur lors de la crétaion de la fenêtre
		// On regarde si l'on est en 32 bits
		if (_NbBitParPixel == 32)
		{
			// Il est possible que l'on soit en fait en 24 bit
			// (SDL dit un peu n'importe quoi dans ce cas !)
			// On recommence donc !
			_NbBitParPixel = 24;
			_SurfaceSDL = _CreerFenetre(_NbBitParPixel, flags);
		}
	}
	if (_SurfaceSDL == NULL)
	{
		// Erreur lors de la crétaion de la fenêtre
		// On regarde si l'on est en fullscreen
		// Dans ce cas on retourne en fenetre
		if (flags & SDL_FULLSCREEN)
		{
			cout << "Fullscreen window init error" << endl;
			cout << "Trying in non-fullscreen..." << endl;
			flags &= ~SDL_FULLSCREEN;
			_Fullscreen = false;
			_SurfaceSDL = _CreerFenetre(_NbBitParPixel, flags);
		}
	}
	if (_SurfaceSDL == NULL)
	{
		cerr<<"Video Init error: can't create the window!"<<endl;
		return false;
	}

	ChangementMode.Emettre(_ResolutionX, _ResolutionY, _NbBitParPixel);


	SDL_WM_SetCaption(_Titre,NULL);
	info=SDL_GetVideoInfo();

	// Initialisation de OpenGL
	_InitGL();

	_Reshape(_ResolutionX, _ResolutionY);  // Set Up Our Perspective GL Screen
	glClearColor(0.25,0.25,0.25,0.25);
	glClear(GL_COLOR_BUFFER_BIT);

	SDL_GL_SwapBuffers( );

	_ExisteFenetre=true;
	return true;
}

SDL_Surface * MOGL_Fenetre::_CreerFenetre(unsigned int & p_Bpp, unsigned int p_Flags)
{

    unsigned int rMask = 5, gMask = 6, bMask = 5;
    switch (p_Bpp)
    {
        case 0:
        {
            const SDL_VideoInfo * vidInf = SDL_GetVideoInfo();
            if (vidInf == NULL)
            {
                return NULL;
            }
            SDL_PixelFormat * pixFormat = vidInf->vfmt;
            if (vidInf == NULL)
            {
                return NULL;
            }
            p_Bpp = pixFormat->BitsPerPixel;
            rMask = pixFormat->Rmask;
            gMask = pixFormat->Gmask;
            bMask = pixFormat->Bmask;

            break;
        }
        case 16:
        {
            rMask = 5;
            gMask = 6;
            bMask = 5;
            break;
        }
        case 24:
        case 32:
        {
            rMask = 8;
            gMask = 8;
            bMask = 8;
            break;
        }
    }
    SDL_GL_SetAttribute( SDL_GL_RED_SIZE, rMask );
    SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, gMask );
    SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, bMask );
    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, p_Bpp );
    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

    cout<<"  Trying attributes and BPP: rMask="<<rMask<<" gMask="<<gMask<<" bMask="<<bMask<<" BPP="<<p_Bpp;
    SDL_Surface * surf = SDL_SetVideoMode( _ResolutionX, _ResolutionY, p_Bpp, p_Flags );
    if (surf == NULL)
    {
        cout<<" => Failed"<<endl;
    }
    else
    {
        cout<<" => Ok"<<endl;
    }
    return surf;
}

bool MOGL_Fenetre::LancerBoucle()
{
    // Initialisation du temps
    MOGL_Temps::_MajTemps();

    SDL_Event event;

    while (SDL_PollEvent( &event ));

    if (_CacheSouris)
    {
        SDL_ShowCursor(0);
    }
    else
    {
        SDL_ShowCursor(1);
    }

    if (_GrabCurseur)
    {
        SDL_WM_GrabInput(SDL_GRAB_ON);
    }
    else
    {
        SDL_WM_GrabInput(SDL_GRAB_OFF);
    }
    SDL_EnableKeyRepeat(_RepetitionDelai, _RepetitionIntervalle);

    while( !_FinBoucle )
    {
        MOGL_Temps::_MajTemps();

        // Gestion des évènements
        _GestionEvenement();

        // On emmet le signal OnIdle
        Idle.Emettre();

        // On affiche les interfaces
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        for (MOGL_ItMap_Interface itMap=_EnsembleInterface.begin(); itMap!=_EnsembleInterface.end(); itMap++)
        {
            for (MOGL_ItSet_Interface itSet=itMap->second.begin(); itSet!=itMap->second.end(); itSet++)
            {
                if (!(*itSet)->GetCacher())
                {
                    (*itSet)->SetDimension(_ResolutionX, _ResolutionY);
                    (*itSet)->Afficher();
                }
            }
        }
        // On fait le switch des buffers
        SDL_GL_SwapBuffers( );
    }
    Destruction.Emettre();
    return true;																	// Success
}

void MOGL_Fenetre::Arreter()
{
    _FinBoucle=true;
}
bool MOGL_Fenetre::SetMode(int p_ResolutionX, int p_ResolutionY)
{
    return SetMode(p_ResolutionX, p_ResolutionY, _Fullscreen);
}

bool MOGL_Fenetre::SetMode(int p_ResolutionX, int p_ResolutionY, bool p_Fullscreen)
{
	_ResolutionX=p_ResolutionX;
	_ResolutionY=p_ResolutionY;
	_Fullscreen=p_Fullscreen;
	const SDL_VideoInfo* info;
	int flags = 0;

	if (_ExisteFenetre)
	{
        if (_Fullscreen)
        {
            cout << "Fullscreen is true" << endl;
            flags = SDL_OPENGL | SDL_FULLSCREEN;
        }
        else
        {
            cout << "Fullscreen is false" << endl;
            flags = SDL_OPENGL | SDL_RESIZABLE;
        }
#ifdef WIN32
		// Sous windows le changement de résolution semble très alléatoire...
		// Du coup on va dire à SDL de terminer la gestion de la video
		// (ce qui devrait détruire la fenêtre), puis d'initialiser la video
		// en recéreant une fenêtre. Il semble que cela fonctionne mieux.

		SDL_QuitSubSystem(SDL_INIT_VIDEO);
		SDL_InitSubSystem(SDL_INIT_VIDEO);
#endif

		_SurfaceSDL = _CreerFenetre(_NbBitParPixel, flags);

		if (_SurfaceSDL == NULL)
		{
			// Erreur lors de la crétaion de la fenêtre
			// On regarde si l'on est en 32 bits
			if (_NbBitParPixel == 32)
			{
				// Il est possible que l'on soit en fait en 24 bit
				// (SDL dit un peu n'importe quoi dans ce cas !)
				// On recommence donc !
				_NbBitParPixel = 24;
				_SurfaceSDL = _CreerFenetre(_NbBitParPixel, flags);
			}
		}
		if (_SurfaceSDL == NULL)
		{
			// Erreur lors de la crétaion de la fenêtre
			// On regarde si l'on est en fullscreen
			// Dans ce cas on retourne en fenetre
			if (flags & SDL_FULLSCREEN)
			{
				flags &= ~SDL_FULLSCREEN;
				_SurfaceSDL = _CreerFenetre(_NbBitParPixel, flags);
			}
		}
		if (_SurfaceSDL == NULL)
		{
			return false;
		}

#ifdef WIN32
		SDL_WM_SetCaption(_Titre,NULL);
#endif


		_Reshape(_ResolutionX, _ResolutionY);

		info=SDL_GetVideoInfo();
		//_NbBitParPixel=info->vfmt->BitsPerPixel;

		if (_CacheSouris)
		{
			SDL_ShowCursor(0);
		}
		else
		{
			SDL_ShowCursor(1);
		}

		if (_GrabCurseur)
		{
			SDL_WM_GrabInput(SDL_GRAB_ON);
		}
		else
		{
			SDL_WM_GrabInput(SDL_GRAB_OFF);
		}
		SDL_EnableKeyRepeat(_RepetitionDelai, _RepetitionIntervalle);


		ChangementMode.Emettre(_ResolutionX, _ResolutionY, _NbBitParPixel);
	}
	return true;
}

int MOGL_Fenetre::GetResolutionX() const
{
    return _ResolutionX;
}

int MOGL_Fenetre::GetResolutionY() const
{
    return _ResolutionY;
}

int MOGL_Fenetre::GetBPP() const
{
    return _NbBitParPixel;
}

void MOGL_Fenetre::SetTitre(char * p_Titre)
{
    if (_Titre!=NULL)
    {
        delete [] _Titre;
    }
    if (p_Titre!=NULL)
    {
        _Titre=new char[strlen(p_Titre)+1];
        strcpy(_Titre,p_Titre);
    }
}

bool MOGL_Fenetre::GetFullscreen() const
{
    return _Fullscreen;
}

void MOGL_Fenetre::SetFullscreen(bool p_Fullscreen)
{
    if (_Fullscreen!=p_Fullscreen)
    {
        _Fullscreen=p_Fullscreen;
        if (_ExisteFenetre)
        {
            if (_bManualResize)
            {
                _bManualResize = false;
                _ResolutionX=_MemResolutionX;
                _ResolutionY=_MemResolutionY;
            }
            SetMode(_ResolutionX, _ResolutionY, p_Fullscreen);
#if 0
#ifdef WIN32
            // Bien entendu, sous windows le changement de résulotion n'est pas si simple que cela...
            // Au lieu de simplement appeler une petite fonction, il faut détruire l'environnement video
            // de SDL est le reconstruire.
            // Paur faire simple on va demander le changement de résolution, qui demande la même chose.
            SetMode(_ResolutionX, _ResolutionY, p_Fullscreen);
#else
            SDL_WM_ToggleFullScreen(_SurfaceSDL);
#endif
#endif
        }
    }
}


bool MOGL_Fenetre::_InitGL()
{
    glEnable(GL_DEPTH_TEST);

    glEnable(GL_TEXTURE_2D);

    //glShadeModel(GL_SMOOTH);
    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
    glClearDepth(1.0f);
    glClearColor(0.25f,0.25f,0.25f,1.0f);


    glEnable(GL_CULL_FACE);
    glEnable(GL_LIGHTING);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    return true;
}


// *************************

void MOGL_Fenetre::_ManualResize(int p_ResolutionX, int p_ResolutionY)
{
	if (!_bManualResize)
	{
		_MemResolutionX=_ResolutionX;
		_MemResolutionY=_ResolutionY;
		_bManualResize = true;
	}
    _ResolutionX=p_ResolutionX;
    _ResolutionY=p_ResolutionY;
    _Fullscreen=false;
    const SDL_VideoInfo* info;
    int flags = 0;

    flags = SDL_OPENGL | SDL_RESIZABLE;

    if (_ExisteFenetre)
    {
#ifdef WIN32
        // Sous windows le changement de résolution semble très alléatoire...
        // Du coup on va dire à SDL de terminer la gestion de la video
        // (ce qui devrait détruire la fenêtre), puis d'initialiser la video
        // en recéreant une fenêtre. Il semble que cela fonctionne mieux.

        SDL_QuitSubSystem(SDL_INIT_VIDEO);
        SDL_InitSubSystem(SDL_INIT_VIDEO);
#endif

        _SurfaceSDL = _CreerFenetre(_NbBitParPixel, flags);

        if (_SurfaceSDL == NULL)
        {
            // Erreur lors de la crétaion de la fenêtre
            // On regarde si l'on est en 32 bits
            if (_NbBitParPixel == 32)
            {
                // Il est possible que l'on soit en fait en 24 bit
                // (SDL dit un peu n'importe quoi dans ce cas !)
                // On recommence donc !
                _NbBitParPixel = 24;
                _SurfaceSDL = _CreerFenetre(_NbBitParPixel, flags);
            }
        }
        if (_SurfaceSDL == NULL)
        {
            // Erreur lors de la crétaion de la fenêtre
            // On regarde si l'on est en fullscreen
            // Dans ce cas on retourne en fenetre
            if (flags & SDL_FULLSCREEN)
            {
                flags &= ~SDL_FULLSCREEN;
                _SurfaceSDL = _CreerFenetre(_NbBitParPixel, flags);
            }
        }
        if (_SurfaceSDL == NULL)
        {
            cerr<<"Manual resize error !"<<endl;
        }

#ifdef WIN32
        SDL_WM_SetCaption(_Titre,NULL);
#endif


        _Reshape(_ResolutionX, _ResolutionY);

        info=SDL_GetVideoInfo();
        //_NbBitParPixel=info->vfmt->BitsPerPixel;

        if (_CacheSouris)
        {
            SDL_ShowCursor(0);
        }
        else
        {
            SDL_ShowCursor(1);
        }

        if (_GrabCurseur)
        {
            SDL_WM_GrabInput(SDL_GRAB_ON);
        }
        else
        {
            SDL_WM_GrabInput(SDL_GRAB_OFF);
        }
        SDL_EnableKeyRepeat(_RepetitionDelai, _RepetitionIntervalle);


        ChangementMode.Emettre(_ResolutionX, _ResolutionY, _NbBitParPixel);
    }
}

void MOGL_Fenetre::_Reshape(int w, int h)
{
    glViewport (0, 0, (GLsizei) w, (GLsizei) h);

    _ResolutionX=w;
    _ResolutionY=h;

/*
  glMatrixMode (GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(45, 4.0/3.0, 5, 5000);
  glFrustum(-1,1,-1,1,5,5000);
  glMatrixMode(GL_MODELVIEW);
*/
}

void MOGL_Fenetre::_GestionEvenement()
{
    SDL_Event event;

    // On traite tous les évènements en attente
    while( SDL_PollEvent( &event ) )
    {
        switch( event.type )
        {
            case SDL_KEYDOWN:
                // Touche pressée
                KeyDown.Emettre(&event.key.keysym);
                break;
            case SDL_KEYUP:
                // Touche lachée
                KeyUp.Emettre(&event.key.keysym);
                break;
            case SDL_MOUSEMOTION:
                // Mouvement souris
                MouseMove.Emettre(&event.motion);
                break;
            case SDL_MOUSEBUTTONDOWN:
                // Bouton préssé
                MouseButtonDown.Emettre(&event.button);
                break;
            case SDL_MOUSEBUTTONUP:
                // Bouton relaché
                MouseButtonUp.Emettre(&event.button);
                break;
            case SDL_JOYAXISMOTION:
                // Déplacement d'un axe d'un joystick
                _MouvementAxeJoystick(&event.jaxis);
                break;
            case SDL_JOYBUTTONDOWN:
                // Appuie sur un bouton de joystick
                _BoutonJoystickDown(&event.jbutton);
                break;
            case SDL_JOYBUTTONUP:
                // Bouton de joystick relaché
                _BoutonJoystickUp(&event.jbutton);
                break;
            case SDL_QUIT:
                // Quitter
                _FinBoucle=true;
                break;
            case SDL_VIDEORESIZE:
                _ManualResize(event.resize.w,event.resize.h);
                break;
        }
    }
}

void MOGL_Fenetre::AjouterInterface(MOGL_Interface * p_Interface)
{
    _EnsembleInterface[p_Interface->GetNiveau()].insert(p_Interface);
}

bool MOGL_Fenetre::RetirerInterface(MOGL_Interface * p_Interface)
{
    MOGL_ItMap_Interface itMap=_EnsembleInterface.find(p_Interface->GetNiveau());
    if (itMap!=_EnsembleInterface.end())
    {
        MOGL_ItSet_Interface itSet=itMap->second.find(p_Interface);
        if (itSet!=itMap->second.end())
        {
            itMap->second.erase(itSet);
            return true;
        }
        else
        {
            return false;
        }
    }
    else
    {
        return false;
    }
}

void MOGL_Fenetre::SetGrabCurseur(bool p_Val)
{
    _GrabCurseur=p_Val;
    if (_GrabCurseur)
    {
        SDL_WM_GrabInput(SDL_GRAB_ON);
    }
    else
    {
        SDL_WM_GrabInput(SDL_GRAB_OFF);
    }
}

void MOGL_Fenetre::SetCacherCurseur(bool p_Val)
{
    _CacheSouris=p_Val;
    if (_CacheSouris)
    {
        SDL_ShowCursor(0);
    }
    else
    {
        SDL_ShowCursor(1);
    }
}


void MOGL_Fenetre::DefinirRepetitionTouche(int p_Delai, int p_Intervalle)
{
    _RepetitionDelai=p_Delai;
    _RepetitionIntervalle=p_Delai;

    SDL_EnableKeyRepeat(_RepetitionDelai, _RepetitionIntervalle);
}

bool MOGL_Fenetre::ScreenshotBMP(char * p_NomFichier)
{
    SDL_Surface *image;
    SDL_Surface *temp;

    image = SDL_CreateRGBSurface(SDL_SWSURFACE, _ResolutionX, _ResolutionY, 24, 0x0000FF, 0x00FF00, 0xFF0000, 0);
    temp = SDL_CreateRGBSurface(SDL_SWSURFACE, _ResolutionX, _ResolutionY, 24, 0x0000FF, 0x00FF00, 0xFF0000, 0);

    glReadPixels(0, 0, _ResolutionX, _ResolutionY, GL_RGB, GL_UNSIGNED_BYTE, image->pixels);
    for (int y = 0; y < _ResolutionY; y++)
    {
        memcpy((char*)temp->pixels + 3 * _ResolutionX * y, (char *)image->pixels + 3 * _ResolutionX*(_ResolutionY - y), 3*_ResolutionX);
    }
    memcpy(image->pixels,temp->pixels,_ResolutionX * _ResolutionY * 3);
    int err=SDL_SaveBMP(image, p_NomFichier);
    SDL_FreeSurface(image);
    if (err==0)
    {
        return true;
    }
    {
        return false;
    }
}

void MOGL_Fenetre::_MouvementAxeJoystick(SDL_JoyAxisEvent * p_JoyAxisEvent)
{
//	MouvementAxeJoystick.Emettre(unsigned int p_JoystickIndex, unsigned int p_AxeIndex, float p_Valeur);
    MouvementAxeJoystick.Emettre(p_JoyAxisEvent->which, p_JoyAxisEvent->axis, p_JoyAxisEvent->value);
}

void MOGL_Fenetre::_BoutonJoystickDown(SDL_JoyButtonEvent * p_JoyButtonEvent)
{
//	BoutonJoystickDown.Emettre(unsigned int p_JoystickIndex, unsigned int p_BoutonIndex);
    BoutonJoystickDown.Emettre(p_JoyButtonEvent->which, p_JoyButtonEvent->button);
}

void MOGL_Fenetre::_BoutonJoystickUp(SDL_JoyButtonEvent * p_JoyButtonEvent)
{
//	BoutonJoystickDown.Emettre(unsigned int p_JoystickIndex, unsigned int p_BoutonIndex);
    BoutonJoystickDown.Emettre(p_JoyButtonEvent->which, p_JoyButtonEvent->button);
}

unsigned int MOGL_Fenetre::GetNombreJoystick() const
{
    return _NombreJoysticks;
}

bool MOGL_Fenetre::OuvrirJoystick(unsigned int p_IndiceJoystick)
{
    if (p_IndiceJoystick>=_NombreJoysticks)
    {
        return false;
    }


    SDL_Joystick * joy=SDL_JoystickOpen(p_IndiceJoystick);
    if (joy==NULL)
    {
        return false;
    }
    else
    {
        _Joysticks[p_IndiceJoystick]=joy;
        return true;
    }
}

bool MOGL_Fenetre::FermerJoystick(unsigned int p_IndiceJoystick)
{
    if (p_IndiceJoystick<_NombreJoysticks && _Joysticks[p_IndiceJoystick]!=NULL)
    {
        SDL_JoystickClose(_Joysticks[p_IndiceJoystick]);
        _Joysticks[p_IndiceJoystick]=NULL;
        return true;
    }
    else
    {
        return false;
    }
}

bool MOGL_Fenetre::ScreenshotPrefixBMP(char * p_Prefix)
{
    // On détermine le nom de sauvegarde
    string nomFichier;
    char suf[20];
    bool fin=false;

    while((!fin) && (_NumeroImage<0xFFFFFFFF))
    {
        _NumeroImage++;
        sprintf(suf, "%u.bmp", _NumeroImage);
        nomFichier=string(p_Prefix)+string(suf);

        //ofstream file(nomFichier.c_str(), ios::out | ios::binary | ios::noreplace);

#ifdef WIN32
        if (_access(nomFichier.c_str(), 00) != 0)
#else
        if (access(nomFichier.c_str(), F_OK) != 0)
#endif
        {
            ofstream file(nomFichier.c_str(), ios::out | ios::binary);

            if (file.good())
            {
                fin=true;
            }
        }
    }
    /** @todo régler le problème de l'impossibilité de création à cause du manque de droit. */

    if (!(_NumeroImage<0xFFFFFFFF))
    {
        return false;
    }



    // On sauvegarde l'image
    SDL_Surface *image;
    SDL_Surface *temp;

    image = SDL_CreateRGBSurface(SDL_SWSURFACE, _ResolutionX, _ResolutionY, 24, 0x0000FF, 0x00FF00, 0xFF0000, 0);
    temp = SDL_CreateRGBSurface(SDL_SWSURFACE, _ResolutionX, _ResolutionY, 24, 0x0000FF, 0x00FF00, 0xFF0000, 0);

    glReadPixels(1, 1, _ResolutionX, _ResolutionY, GL_RGB, GL_UNSIGNED_BYTE, image->pixels);
    for (int y = 0; y < _ResolutionY; y++)
    {
        memcpy((char*)temp->pixels + 3 * _ResolutionX * y, (char *)image->pixels + 3 * _ResolutionX*(_ResolutionY - y), 3*_ResolutionX);
    }
    memcpy(image->pixels,temp->pixels,_ResolutionX * _ResolutionY * 3);
    int res=SDL_SaveBMP(image, nomFichier.c_str());
    SDL_FreeSurface(image);
    if (res==0)
    {
        return true;
    }
    {
        return false;
    }
}

