#include <stdlib.h>
#include <stdio.h>
#include <GL/glu.h>
#include <SDL.h>
#include <SDL_image.h>

#include "texture.h"

texture* texture_new(char* filename) {
	GLenum glerror;
	SDL_Surface* image;
	SDL_Surface* imgfmt; /* For getting desired image format (ick) */
	SDL_Surface* imgtmp; /* Used to keep track of the original surface */
	Uint32 rmask, gmask, bmask, amask;
	texture* this;
	if(!(this = malloc(sizeof(texture)))) {
		fprintf(stderr, "Warning: out of heap for texture record!\n");
		return 0;
	}

	/* http://jcatki.no-ip.org/SDL_image/SDL_image_frame.html */
	image = IMG_Load(filename);
	if(!image) {
		fprintf(stderr, "Failed to load texture '%s' (%s)!\n", filename, IMG_GetError());
		return 0;
	}
	/* components = (image->format.Amask == 0) ? 3 : 4; *//* Alpha channel? */
	/* Endian-ness fun! http://www.libsdl.org/cgi/docwiki.cgi/SDL_5fCreateRGBSurface */
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
	rmask = 0xff000000;
	gmask = 0x00ff0000;
	bmask = 0x0000ff00;
	amask = 0x000000ff;
#else
	rmask = 0x000000ff;
	gmask = 0x0000ff00;
	bmask = 0x00ff0000;
	amask = 0xff000000;
#endif
	imgfmt = SDL_CreateRGBSurface(SDL_SWSURFACE, image->w, image->h, 32, rmask, gmask, bmask, amask);
	if(!imgfmt) {
		fprintf(stderr, "Failed to create format template (%s)!\n", SDL_GetError());
		return 0;
	}
	imgtmp = image;
	image = SDL_ConvertSurface(image, imgfmt->format, SDL_SWSURFACE);
	SDL_FreeSurface(imgtmp); /* Bye bye unconverted, loaded image */
	SDL_FreeSurface(imgfmt); /* Bye bye temporary format-getting image */

	glGenTextures(1, &this->id);
	glBindTexture(GL_TEXTURE_2D, this->id);
	SDL_LockSurface(image);
	glTexImage2D(GL_TEXTURE_2D, 0, 4, image->w, image->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels);
	glerror = gluBuild2DMipmaps(GL_TEXTURE_2D, 4, image->w, image->h, GL_RGBA, GL_UNSIGNED_BYTE, image->pixels);
	if(glerror) {
		fprintf(stderr, "Mipmap generation failed for %s: %s\n", filename, gluErrorString(glerror));
	}
	SDL_UnlockSurface(image);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

//	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
//	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	
	/* Texture has now been copied to texture memory */
	SDL_FreeSurface(image);

	fprintf(stderr, "Loaded texture %s as ID %i\n", filename, this->id);

	return this;
}

void texture_destroy(texture* this) {
	if(!this){return;}
	glDeleteTextures(1, &this->id);
	free(this);
}

/* See also:
   http://www.gamedev.net/community/forums/topic.asp?topic_id=184477&whichpage=1 (bottom post)
   http://homepage.mac.com/kijibato/macreatefan/letssdl02.html */
