/*
 *
 * Copyright (C) 2008 Fontaine Clément
 *
 * This program 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.
 *
 * this program 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 this program. If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "sdl_gl.h"

void fenetrePleineEcran(SDL_Surface **ecran)
{
        if(SDL_Init(SDL_INIT_VIDEO) == -1) /* initialisation de la SDL */
        {
                fprintf(stderr, "Erreur d'initialisation de la SDL : %s\n", SDL_GetError());
                exit(EXIT_FAILURE);
        }
        /* on verifie si le mode vidéo est chargé */
        if((*ecran = SDL_SetVideoMode(0, 0, 32, SDL_OPENGL | SDL_FULLSCREEN)) == NULL)
        {
                fprintf(stderr, "Impossible de charger le mode vidéo : %s\n", SDL_GetError());
                exit(EXIT_FAILURE);
        }
        /* on empèche le curseur de partir de la fenêtre */
        SDL_WM_GrabInput(SDL_GRAB_ON);
        
        /* on rend invisible le curseur */
        SDL_ShowCursor(SDL_DISABLE);
}

void fenetreTaille(SDL_Surface **ecran, const coordonnees taille)
{
        if(SDL_Init(SDL_INIT_VIDEO) == -1)
        {
                fprintf(stderr, "Erreur d'initialisation de la SDL : %s\n", SDL_GetError());
                exit(EXIT_FAILURE);
        }
        if((*ecran = SDL_SetVideoMode(taille.x, taille.y, 32, SDL_OPENGL)) == NULL)
        {
                fprintf(stderr, "Impossible de charger le mode vidéo : %s\n", SDL_GetError());
                exit(EXIT_FAILURE);
        }
}

void fenetrePerspective(const SDL_Surface *ecran, const int fovy, const int near, const int far)
{
        glMatrixMode(GL_PROJECTION); /* matrice de projection */
        glLoadIdentity(); /* initialise avec la matrice d'identité */
        gluPerspective(fovy, (double) ecran->w / ecran->h, near, far);
}

void fenetreTitre(const char *titre)
{
        SDL_WM_SetCaption(titre, NULL);
}

void fenetreAfficher(void)
{
        glFlush(); /* force les commandes OpenGL à s'exécuter */
        SDL_GL_SwapBuffers(); /* on met à jour l'écran */
}

void fenetreDetruire(SDL_Surface *ecran)
{
        SDL_WM_GrabInput(SDL_GRAB_OFF);
        SDL_ShowCursor(SDL_ENABLE);
        
        SDL_FreeSurface(ecran); /* libère la mémoire */
        SDL_Quit(); /* quite la SDL */
}

void tempsInitialiser(unsigned int *depart)
{
        *depart = SDL_GetTicks();
}

void tempsPause(unsigned int *ecart, unsigned int debut, unsigned int temporisation)
{
        *ecart = SDL_GetTicks() - debut;
        
        if((*ecart) < temporisation)
        {
                SDL_Delay(temporisation - (*ecart)); /* pause */
        }
}

void tempsActualiser(unsigned int *ecart, unsigned int *courant, unsigned int *ancien)
{
        /* on met à jour les valeurs */
        *courant = SDL_GetTicks();
        *ecart = (*courant) - (*ancien);
        *ancien = *courant;
}

Uint32 pixel(SDL_Surface *surface, int x, int y)
{
	int nb_octets_par_pixel = surface->format->BytesPerPixel;

	/* ici p est l'adresse du pixel que l'on veut connaitre
	surface->pixels contient l'adresse du premier pixel de l'image */
	Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * nb_octets_par_pixel;

	/* gestion différents retour suivant le nombre d'octets par pixel de l'image */
	switch(nb_octets_par_pixel)
	{
		case 1:
			return *p;

		case 2:
			return *(Uint16 *)p;

		case 3:
			/* suivant l'architecture de la machine */
			if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
			{
				return p[0] << 16 | p[1] << 8 | p[2];
			}
			else
			{
				return p[0] | p[1] << 8 | p[2] << 16;
			}

		case 4:
			return *(Uint32 *)p;

		default:
			return 0;
	}
}
