module config.inputconfig;



private import std.math;
private import gedo.video.ggl;
private import gedo.video.rect;
private import gedo.video.color;
private import gedo.video.texture;
private import gedo.audio.music;
private import gedo.gui.label;
private import gedo.gui.table;
private import gedo.gui.camera;
private import gedo.gui.cursor;
private import gedo.gui.component;
private import gedo.input.joystick;
private import gedo.system.scene;
private import vs.action.button;



public class InputConfig : Scene
{
public:
	this(Joystick joystick, Scene parent)
	{
		_camera = new Camera(640, 480, 0.0, 0.0, 0.5);

		_parent   = parent;
		_joystick = joystick;

		_cursor = new Cursor();
		_cursor.joystick = Joysticks().keyboard;
		_cursor.onCancel = &backToParentScene;

		Texture[2] guideTextures;

		guideTextures[0] = Texture("$LIB/config/guide_inputconfig0.png", false);
		guideTextures[1] = Texture("$LIB/config/guide_inputconfig1.png", false);

		{
			auto guide = new MultiLineLabel(guideTextures);

			guide.position[1] = -240.0 + guide.size[1]*0.5;
			guide.color = GREEN;

			_camera.add(guide);
		}

		auto rootMenu = new Component();
		{
			ImageLabel[4] menus;

			menus[0] = new ImageLabel(Texture("$LIB/config/left.png", false));
			menus[1] = new ImageLabel(Texture("$LIB/config/right.png", false));
			menus[2] = new ImageLabel(Texture("$LIB/config/back.png", false));
			menus[3] = new ImageLabel(Texture("$LIB/config/front.png", false));

			auto table = new Table(2, 4);
			table.position[] = 0.0;

			foreach(y, menu; menus)
			{
				auto digit = new DigitLabel(joystick.axisConfig[y]);

				table.set(0, y, menu);
				table.set(1, y, digit);

				table.rows[y].cbClick = &onClickAxisItem;
			}

			rootMenu.add(table);

			_cursor.focus = table.rows[0];
		}

		{
			ImageLabel[ActionButton.max+1] menus;

			menus[ActionButton.SEARCH]  = new ImageLabel(Texture("$LIB/config/search.png", false));
			menus[ActionButton.DEFEND]  = new ImageLabel(Texture("$LIB/config/defend.png", false));
			menus[ActionButton.SHOT]    = new ImageLabel(Texture("$LIB/config/shot.png", false));
			menus[ActionButton.HIT]     = new ImageLabel(Texture("$LIB/config/hit.png", false));
			menus[ActionButton.SPECIAL] = new ImageLabel(Texture("$LIB/config/special.png", false));
			menus[ActionButton.PAUSE]   = new ImageLabel(Texture("$LIB/config/pause.png", false));

			auto table = new Table(2, 6);
			table.position[] = 0.0;

			foreach(y, menu; menus)
			{
				auto digit = new DigitLabel(joystick.buttonConfig[y]);

				table.set(0, y, menu);
				table.set(1, y, digit);

				table.rows[y].cbClick = &onClickButtonItem;
			}

			rootMenu.add(table);
		}

		_assignGuide = new ImageLabel(Texture("$LIB/config/assignbutton.png", false));
		_assignGuide.position[] = 0.0;
		_assignGuide.color      = GREEN;

		_cursor.color = YELLOW;
	}


	override void update()
	{
		_camera.update();
		_cursor.focus.root.update();
		if(_joystick.onAxisMotion || _joystick.onButtonDown || _assignGuide.isAnimating)
		{
			_assignGuide.update();
		}
		else
		{
			_cursor.update();
		}
	}


	override void draw()
	{
		_camera.drawRecursive();

		_cursor.focus.parent.drawRecursive();

		_cursor.draw();

		if(_joystick.onAxisMotion || _joystick.onButtonDown || _assignGuide.isAnimating)
		{
			Rect(_assignGuide.position, _assignGuide.size).fill(rgba(0, 0, 0, 192));
			_assignGuide.draw();
		}
	}


private:
	ImageLabel _assignGuide;
	Joystick   _joystick;
	Camera     _camera;
	Cursor     _cursor;
	Scene      _parent;


	void backToParentScene()
	{
		auto a=0;
		foreach(t; _cursor.focus.root)
		{
			auto table = cast(Table)t;

			uint[] buffer;

			buffer.length = table.rows.length;
			foreach(i, row; table.rows)
			{
				buffer[i] = (cast(DigitLabel)row.items[1]).value;
			}

			switch(a)
			{
			case 0:
				_joystick.configAxis(buffer);
				break;

			case 1:
				_joystick.configButton(buffer);
				break;
			}
			++a;
		}

		_nextScene = _parent;
	}


	void onClickAxisItem()
	{
		_assignGuide.position[] = 0.0;
		_assignGuide.slideIn();

		_joystick.onAxisMotion = &onAxisMotion;
	}


	void onClickButtonItem()
	{
		_assignGuide.position[] = 0.0;
		_assignGuide.slideIn();

		_joystick.onButtonDown = &onButtonDown;
	}


	void onAxisMotion(uint n, int v)
	{
		if(abs(v) >= 24*1024)
		{
			if(_joystick !is Joysticks().keyboard)
			{
				int expected = 0;
				foreach(i, row; (cast(Table)_cursor.focus.parent).rows)
				{
					if(row is _cursor.focus)
					{
						if(i & 1)
						{
							expected = 1;
						}
						else
						{
							expected = -1;
						}
						break;
					}
				}
				assert(expected != 0);

				if(expected * v < 0)
				{
					n |= 0x80;
				}
			}

			(cast(DigitLabel)(cast(RowItem)_cursor.focus).items[1]).value = n;

			_joystick.onAxisMotion = null;

			_assignGuide.slideOut();
		}
	}


	void onButtonDown(uint n)
	{
		(cast(DigitLabel)(cast(RowItem)_cursor.focus).items[1]).value = n;

		_joystick.onButtonDown = null;

		_assignGuide.slideOut();
	}
}
