#include "Alpha.h"

#include <stdexcept>

using namespace std;
using namespace gge;
using namespace gge::utils;
using namespace gge::resource;
using namespace gge::widgets;

namespace gaming { namespace menu {


	AlphaHider::AlphaHider() :
	tinting(layer), Operation(None), parent(NULL)
	{ 
		tinting.SetController(controller);
		controller.Finished.Register(this, &AlphaHider::animationcomplete);
	}

	void AlphaHider::Setup(Menu &menu) {
		parent=&menu;
		LayerBase &parentlayer=parent->MainLayer();

		parentlayer.parent->Add(layer, parentlayer.GetOrder());
		parentlayer.parent->Remove(parentlayer);
		layer.Add(parentlayer);
		layer.BoundingBox=parentlayer.BoundingBox;
		parentlayer.BoundingBox.MoveTo(0,0);
	}

	void AlphaHider::Load(gge::resource::DataArray &data) {
		if(data.getInt(1)!=1)
			throw std::runtime_error("Alpha hider version is not suitable.");

		duration=data.getInt(2);
	}
	void AlphaHider::Hide(bool animate) {
		if(!animate) {
			layer.Ambient=0x00ffffff;
			layer.IsVisible=false;
			parent->HideComplete();
		} else {
			Operation=Hiding;
			tinting.Setup(layer.Ambient, 0x00ffffff, duration);
		}
	}
	void AlphaHider::Show(bool animate) {
		layer.IsVisible=true;
		if(!animate) {
			layer.Ambient=0xffffffff;
			parent->ShowComplete();
		} else {
			Operation=Showing;
			tinting.Setup(layer.Ambient, 0xffffffff, duration);
		}
	}

	void AlphaHider::animationcomplete() {
		if(Operation==Showing) {
			parent->ShowComplete();
		}
		else if(Operation==Hiding) {
			layer.IsVisible=false;
			parent->HideComplete();
		}

	}


	void AlphaMinimizer::Setup(Menu& menu) {
		if(parent)
			btn.ClickEvent.Clear();

		parent=&menu;
		btn.ClickEvent.LinkTo(parent->RestoreButton.ClickEvent);
		btn.ClickEvent.Register(this, &AlphaMinimizer::restore_click);

		LayerBase &btnlayer=parent->MainLayer();
		LayerBase &minlayer=parent->MinimizeLayer();

		btnlayer.parent->Add(buttonlayer, btnlayer.GetOrder());
		btnlayer.parent->Remove(btnlayer);
		buttonlayer.Add(btnlayer);
		buttonlayer.BoundingBox=btnlayer.BoundingBox;
		btnlayer.BoundingBox.MoveTo(0,0);

		minlayer.Add(minimizerlayer);
		minimizerlayer.BoundingBox.SetSize(minlayer.BoundingBox.GetSize());
		minimizerlayer.Ambient=0x00ffffff;
	}

	void AlphaMinimizer::Refresh() {
		if(!parent) return;

		btn.Text=parent->RestoreButton.Text;
		btn.Icon=parent->RestoreButton.Icon;
		btn.SetEnabled(!parent->RestoreButton.Disabled);
		parent->MinimizeLayer().IsVisible=parent->RestoreButton.Visible;
	}

	void AlphaMinimizer::Load(gge::resource::DataArray &data) {
		if(data.getInt(1)!=1)
			throw std::runtime_error("Alpha minimizer version is not suitable.");

		btn.Move(data.getPoint(2));
		duration=data.getInt(3);
		alwaysvisible=data.getInt(4)!=0;

		if(data.checkLink(5)) {
			bp=true;
			btn.SetBlueprint(dynamic_cast<gge::widgets::checkbox::Blueprint&>(data.getLink(5)));
		}
		else {
			bp=false;
			btn.SetBlueprint(gge::widgets::WR.Buttons.Decorative);
		}
	}

	void AlphaMinimizer::Restore(bool animate) {
		if(!animate) {
			buttonlayer.Ambient   =0xffffffff;
			parent->RestoreComplete();
			if(!alwaysvisible) {
				minimizerlayer.Ambient=0x00ffffff;
			}
		} else {
			Operation=Restoring;
			btntinting.Setup(buttonlayer.Ambient, 0xffffffff, duration);
			if(!alwaysvisible) {
				mintinting.Setup(minimizerlayer.Ambient, 0x00ffffff, duration);
			}
		}
	}

	void AlphaMinimizer::Minimize(bool animate) {
		if(!animate) {
			buttonlayer.Ambient   =0x00ffffff;
			minimizerlayer.Ambient=0xffffffff;
			parent->MinimizeComplete();
		} else {
			Operation=Minimizing;
			btntinting.Setup(buttonlayer.Ambient, 0x00ffffff, duration);
			if(alwaysvisible) {
				minimizerlayer.Ambient=0xffffffff;
			}
			else {
				mintinting.Setup(minimizerlayer.Ambient, 0xffffffff, duration);
			}
		}
	}

	AlphaMinimizer::AlphaMinimizer() : duration(0),
		btntinting(buttonlayer), mintinting(minimizerlayer),
		alwaysvisible(true), bp(false)
	{
		btn.SetContainer(vp);
		btn.ClickEvent.Register(this, &AlphaMinimizer::restore_click);

		if(gge::widgets::WR.Buttons.Decorative) 
			btn.SetBlueprint(gge::widgets::WR.Buttons.Decorative);;

		btntinting.SetController(btncontroller);
		mintinting.SetController(mincontroller);

		vp.LandOn(minimizerlayer);

		btncontroller.Finished.Register(this, &AlphaMinimizer::animationcomplete);

		gge::widgets::WR.LoadedEvent.Register(this, &AlphaMinimizer::wr_loaded);
	}

	void AlphaMinimizer::animationcomplete() {
		if(Operation==Restoring) {
			parent->RestoreComplete();
		}
		else if(Operation==Minimizing) {
			parent->MinimizeComplete();
		}
	}

} }
