module gedo.gui.label;



private import gedo.gui.component;
private import gedo.video.ggl;
private import gedo.video.color;
private import gedo.video.texture;
private import gedo.video.staticmesh;
private import gedo.video.skinnedmesh;



public class StaticMeshLabel : Component
{
public:
	this(StaticMesh m)
	{
		_mesh = m;
	}


	override void onDraw()
	{
		_mesh.draw();
	}


private:
	StaticMesh _mesh;
}



public class SkinnedMeshLabel : Component
{
public:
	this(SkinnedMesh m)
	{
		_mesh = m;

		_timer = new Timer(m);

		_timer.set(0);
	}


	Timer timer()
	{
		return _timer;
	}


	override void onUpdate()
	{
		_timer.update();
	}


	override void onDraw()
	{
		_timer.draw();
	}


private:
	SkinnedMesh _mesh;
	Timer       _timer;
}



public class ImageLabel : Component
{
public:
	this(Texture t)
	{
		texture = t;

		_color = WHITE;
	}


	void texture(Texture t)
	{
		_texture = t;

		size[0] = t.width;
		size[1] = t.height;
	}


	Texture texture()
	{
		return _texture;
	}


	void color(Color c)
	{
		_color = c;
	}


	override void onDraw()
	{
		_texture.draw(_color);
	}


private:
	Texture _texture;
	Color   _color;
}



public class BooleanLabel : Component
{
public:
	this(Texture t0, Texture t1)
	{
		_textures[0] = t0;
		_textures[1] = t1;

		value = false;

		_color = WHITE;
	}


	void value(bool v)
	{
		_value = v;

		auto tex = texture;

		size[0] = tex.width;
		size[1] = tex.height;
	}


	bool value()
	{
		return _value;
	}


	void toggle()
	{
		_value = !_value;
	}


	void color(Color c)
	{
		_color = c;
	}


	override void onDraw()
	{
		texture.draw(_color);
	}


	override bool onClick()
	{
		toggle();

		return false;
	}


private:
	Texture[2] _textures;
	Color      _color;
	bool       _value;


	Texture texture()
	{
		if(_value)
		{
			return _textures[1];
		}
		else
		{
			return _textures[0];
		}
	}
}



public class DigitLabel : Component
{
public:
	this(int x)
	{
		if(!_meshes[0])
		{
			char[] filename = "$LIB/digit/bb0.gsa".dup;

			foreach(i, inout mesh; _meshes)
			{
				filename[length - 5] = '0' + i;

				mesh = StaticMesh(filename);
			}
		}

		_scale = 16.0;

		value  = x;

		_color = WHITE;
	}


	void scale(float s)
	{
		_scale = s;

		size[0] = s * _count;
		size[1] = s * 2.0;
	}


	void value(int x)
	{
		if(x < 0)
		{
			x = -x;
		}

		_count = _bcd.length;
		foreach(i, inout b; _bcd)
		{
			int x2 = x / 10;

			b = x - x2*10;

			x = x2;
			if(x == 0)
			{
				_count = i+1;
				break;
			}
		}

		scale = _scale;
	}


	int value()
	{
		int x = 0;

		foreach_reverse(b; _bcd[0 .. _count])
		{
			x = x*10 + b;
		}

		return x;
	}


	void color(Color c)
	{
		_color = c;
	}


	override void onDraw()
	{
		GGL_scale(_scale, _scale, 1.0);

		float x = (_count - 1)*0.5;
		GGL_translate(x, 0.0, 0.0);
		foreach(b; _bcd[0 .. _count])
		{
			_meshes[b].draw(_color);
			GGL_translate(-1.0, 0.0, 0.0);
		}
	}


private:
	static StaticMesh[10] _meshes;

	ubyte[8] _bcd;
	Color    _color;
	float    _scale;
	uint     _count;
}



public class MultiLineLabel : Component
{
public:
	this(Texture[] t)
	{
		textures = t;

		_color = WHITE;
	}


	void textures(Texture[] t)
	{
		_textures = t.dup;

		size[] = 0.0;

		foreach(i, texture; t)
		{
			if(texture.width > size[0])
			{
				size[0] = texture.width;
			}
			size[1] += texture.height + 4.0;
		}
	}


	void color(Color c)
	{
		_color = c;
	}


	override void onDraw()
	{
		float y = size[1] * 0.5 - 2.0;

		GGL_translate(0.0, y, 0.0);

		foreach(texture; _textures)
		{
			GGL_translate(0.0, -(texture.height*0.5), 0.0);

			texture.draw(_color);

			GGL_translate(0.0, -(texture.height*0.5 + 4.0), 0.0);
		}
	}


private:
	Texture[] _textures;
	Color     _color;
}
