
#include "load_texture_Gl3.h"

bool loadTextureGl3(GLuint & id, const std::string & fichierImage){
	// Chargement de l'image dans une surface SDL
	SDL_Surface *imageSDL = IMG_Load(fichierImage.c_str());
	if(imageSDL == NULL){
		std::cout << "Erreur, le fichier " << fichierImage<< " n'existe pas" << std::endl;
		return false;
	}
	// Génération de l'ID
	glGenTextures(1, &id);
	// Verrouillage
	glBindTexture(GL_TEXTURE_2D, id);
	// Détermination du nombre de composantes
	GLenum format(0);
	if(imageSDL->format->BytesPerPixel == 3) format = GL_RGB;
	else if(imageSDL->format->BytesPerPixel == 4) format = GL_RGBA;
	else{   // Dans les autres cas, on arrête le chargement
		std::cout << "Erreur, format de l'image inconnu" << std::endl;
		SDL_FreeSurface(imageSDL);
		return false;
	}
	SDL_Surface* imageOpenGl = verticalMirror(imageSDL) /*imageSDL*/;
	SDL_FreeSurface(imageSDL); //on n'oublie pas de dégommer l'image de SDL
// 	Copie des pixels
	glTexImage2D(GL_TEXTURE_2D, 0, imageOpenGl->format->BytesPerPixel, imageOpenGl->w, imageOpenGl->h, 0, format, GL_UNSIGNED_BYTE, imageOpenGl->pixels);
	// Application des filtres
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	// Déverrouillage
	glBindTexture(GL_TEXTURE_2D, 0);
	// Fin de la méthode
	SDL_FreeSurface(imageOpenGl); //on n'oublie pas de dégommer l'image de OPENGL
	return true;
}

inline int getPixel(int i, int j, int bytesperPix, int pitch){
	return i*pitch + j*bytesperPix;
}

///fonction qui inverse l'image verticalement (pour convertir une image de SDL en image de OPENGL
/**	@param imageSource : image que l'on veut inversée
 * 	@return image inversée
*/
SDL_Surface* verticalMirror(const SDL_Surface *imageSource){
#ifdef NEW_V_MIRROR
	// Copie conforme de l'image source sans les pixels
	SDL_Surface *imageInversee = SDL_CreateRGBSurface(SDL_HWSURFACE, imageSource->w, imageSource->h, imageSource->format->BitsPerPixel, imageSource->format->Rmask, imageSource->format->Gmask, imageSource->format->Bmask, imageSource->format->Amask);
	// Tableau intermédiaires permettant de manipuler les pixels
	unsigned char* pixelsSources = (unsigned char*) imageSource->pixels;
	unsigned char* pixelsInverses = (unsigned char*) imageInversee->pixels;
	// Inversion des pixels
	for(int i = 0; i < imageSource->h; i++){
		for(int j = 0; j < imageSource->w * imageSource->format->BytesPerPixel; j++)
		pixelsInverses[(imageSource->w * imageSource->format->BytesPerPixel * (imageSource->h - 1 - i)) + j] = pixelsSources[(imageSource->w * imageSource->format->BytesPerPixel * i) + j];
	}
	// Retour de l'image inversée
	return imageInversee;
#else
	//ça c'est une vieille technique mais au moins elle a le mérite de fonctionner correctement, pas comem l'autre
	SDL_Surface *res;
	int src,dest;
	
	int bytesperpix;
	unsigned char *srcpixels, *destpixels;

	if(imageSource == NULL) return NULL;

       	bytesperpix = imageSource->format->BytesPerPixel;

	// Creation d'une surface de meme taille
	res = SDL_CreateRGBSurface(SDL_HWSURFACE, imageSource->w, imageSource->h, imageSource->format->BitsPerPixel,
			imageSource->format->Rmask, imageSource->format->Gmask, imageSource->format->Bmask, imageSource->format->Amask);

	if(res == NULL) return NULL;

	// Maintenant on inverse les pixels
	srcpixels = (unsigned char*) imageSource->pixels;
	destpixels = (unsigned char*) res->pixels;
	int i, j;
	for(i = 0; i < imageSource->h; i++){
		for(j = 0; j < imageSource->w; j++){
			src = getPixel(i, j, bytesperpix, imageSource->pitch);
			dest = getPixel(imageSource->h-1-i, j, bytesperpix, imageSource->pitch);

			destpixels[dest] = srcpixels[src];
			dest++;src++;

			destpixels[dest] = srcpixels[src];
			dest++;src++;

			destpixels[dest] = srcpixels[src];
			dest++;src++;

			if(bytesperpix==4){
				destpixels[dest] = srcpixels[src];
				dest++;src++;
			}
		}
	}
	return res;
#endif
}
