#include "Wumbo-Header.h"
#include "Wumbo-Texture.h"

namespace Wumbo
{
	GLuint Texture::getWidth()
	{
		return width;
	}

	GLuint Texture::getHeight()
	{
		return height;
	}

	GLuint Texture::getTexture()
	{
		return texture;
	}

	Texture::Texture(GLuint texID, unsigned int width, unsigned int height)
	{
		width = width;
		height = height;
		texture = texID;
	}
	Texture::Texture()
	{
		loadType = 0;
		textureLoaded = false;
		width = 1;
		height = 1;
#if PLATFORM_OSX || PLATFORM_IOS
		filepath = @""; 
#else
		filepath = "";
#endif
	}

	#if PLATFORM_OSX || PLATFORM_IOS
	Texture::Texture(NSString *fname)
	#else
	Texture::Texture(std::string fname)
	#endif
	{
		textureLoaded = false;
		load(fname);
	}
	
	#if PLATFORM_OSX || PLATFORM_IOS
	bool Texture::load(NSString *fname)
	#else
	bool Texture::load(std::string fname)
	#endif
	{
		if (textureLoaded)
			return true;
		loadType = 0;
		textureLoaded = true;
		filepath = fname;
	#if PLATFORM_IOS
		NSString* path = fname;//[NSString stringWithUTF8String:fname.c_str()];
		NSError *err = nil;
		NSData *data = [NSData dataWithContentsOfFile:path options:nil error:&err];
		if (data == nil)
		{
			texture = 0;
			NSLog(@"GLtexture::load() could not find file at: %@", path);
			NSLog([[NSBundle mainBundle] resourcePath]);
			printf("%s\n", [[err description] UTF8String]);
			return false;
		}    
		UIImage *uimg = [UIImage imageWithData:data];
		CGImageRef image = [uimg CGImage];
		NSLog(@"GLtexture::load() success: %@. Dimensions: %i, %i",path,(int)CGImageGetWidth(image),(int)CGImageGetHeight(image));
		width = CGImageGetWidth(image);
		height = CGImageGetHeight(image);
		CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
		void *imageData = malloc( height * width * 4);// ,1);
		CGContextRef context = CGBitmapContextCreate( imageData, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big );
		// Flip the Y-axis
		CGContextTranslateCTM (context, 0, height);
		CGContextScaleCTM (context, 1.0, -1.0);
		CGColorSpaceRelease( colorSpace );
		CGContextDrawImage( context, CGRectMake( 0, 0, width, height ), image );
	#else
	#if PLATFORM_OSX
		if (!img.loadFromFile([fname UTF8String]))
		{
			printf("Error loading file: %s\n",[fname UTF8String]);
	#else
		if (!img.loadFromFile(fname))
		{
			printf("Error loading file: %s\n",fname.c_str());
	#endif
			return false;
		}
		img.flipVertically();
		const sf::Uint8 *imageData = img.getPixelsPtr();
		width = img.getSize().x;
		height = img.getSize().y;
	#endif 
		glGenTextures(1, &texture);
		glBindTexture(GL_TEXTURE_2D, texture);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);//GL_LINEAR
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);//GL_LINEAR
	#if PLATFORM_IOS
		CGContextRelease(context);
	#endif
		return true;
	}

	#if PLATFORM_WINDOWS
	Texture::Texture(const sf::Uint8* pointer, unsigned int size)
	{
		textureLoaded = false;
		load(pointer,size);
	}

	bool Texture::load(const sf::Uint8* pointer, unsigned int size)
	{
		if (textureLoaded)
			return false;
		loadType = 1;
		filepointer = (sf::Uint8*) pointer;
		filesize = size;
		textureLoaded = true;
		printf("Loading from memory.");
		sf::Image img;
		if (!img.loadFromMemory(pointer,size))
		{
			printf("Error loading memory: %i",pointer);
			return false;
		}
		img.flipVertically();
		const sf::Uint8 *imageData = img.getPixelsPtr();
		width = img.getSize().x;
		height = img.getSize().y;
		glGenTextures(1, &texture);
		glBindTexture(GL_TEXTURE_2D, texture);
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//GL_NEAREST);
		glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//GL_NEAREST);
		return false;
	}
	#endif


	void Texture::reload()
	{
		unload();
	#if PLATFORM_WINDOWS
		if (loadType == 0)
			load(filepath);
		if (loadType == 1)
			load(filepointer,filesize);
	#else
		load(filepath);
	#endif
	}

	void Texture::unload()
	{
		if (textureLoaded)
		{
			glDeleteTextures(1,&texture);
			textureLoaded = false;
		}
	}
		
	void Texture::bind()
	{
		glBindTexture(GL_TEXTURE_2D, texture);
	}
};