module gedo.video.texture;



private import gedo.video.color;
private import gedo.video.ggl;
private import gedo.video.staticmesh;
private import gedo.file.path;
private import gedo.system.cache;



public class Texture
{
public:
	static Texture white()
	{
		static Texture _white = null;
		if(!_white)
		{
			_white = new Texture();
		}

		return _white;
	}


	static Texture opCall(string path, bool compress = false)
	{
		if(!_cache)
		{
			_cache = new typeof(_cache);
		}

		return _cache.get(path,

				(out uint size)
				{
					Texture t = new Texture(path, compress);

					size = 4*t.width*t.height;

					return t;
				});
	}


	static void clearCache()
	{
		if(_cache)
		{
			_cache.clear();
		}
	}


	this(Color[] pixels, int w, int h)
	{
		_texture = GGL_createTextureRGBA(pixels.ptr, w, h);

		assert(_texture);
	}


	~this()
	{
		GGL_releaseTexture(_texture);
	}


	uint width()
	{
		return GGL_textureSize(_texture)[0];
	}


	uint height()
	{
		return GGL_textureSize(_texture)[1];
	}


	GGL_Texture gglTexture()
	{
		return _texture;
	}


	void wrap(int isRepeated)
	{
		GGL_wrapTexture(_texture, isRepeated);
	}


	void draw(GGL_Vertex[] vertices)
	{
		GGL_drawTriangleStrip(vertices.ptr, vertices.length, _texture);
	}


	void draw(Color c = WHITE)
	{
		auto plane = StaticMesh.plane();

		GGL_pushMatrix();

		GGL_scale(width, height, 1.0);

		plane.draw(this, c);

		GGL_popMatrix();
	}


	void draw(float sx, float sy, Color c = WHITE)
	{
		auto plane = StaticMesh.plane();

		GGL_pushMatrix();

		GGL_scale(sx, sy, 1.0);

		plane.draw(this, c);

		GGL_popMatrix();
	}


private:
	GGL_Texture _texture;


	this()
	{
		_texture = GGL_createTexture(null, false);
	}


	this(char[] path, bool compress)
	{
		_texture = GGL_createTexture(.gedo.file.path.toStringz(path), compress);
		if(!_texture)
		{
			throw new Exception(path ~ ": couldn't open!");
		}
	}
}



private Cache!(Texture, 16<<20) _cache;
