#pragma once

#include "Menu.h"
#include <Utils/Collection.h>
#include <Utils/Size2D.h>
#include <Utils/Point2D.h>
#include <Engine/GGEMain.h>
#include <Widgets/Base/VirtualPanel.h>
#include <Widgets/WidgetRegistry.h>
#include <Effects/Tinting.h>
#include <Widgets/Panel.h>

namespace gaming { namespace menu {

	//can have a background and location using a point and a reference corner, 
	//as well as the distance between items
	//and button size, also allows to use specific button blueprints
	class BasicOrganizer : public IOrganizer {
		//friend class Menu::Factory;
	public:

		enum Alignment {
			Topleft=0,
			Topright=1,
			Bottomleft=2,
			Bottomright=3
		};
		enum Layout {
			Vertical=0,
			Horizontal=1
		};
		enum CycleStrategy {
			Random = 0,
			Inorder = 1,
		};

		virtual void Setup(Menu&);
		virtual void Refresh();

		virtual void Load(gge::resource::DataArray &data);

		~BasicOrganizer() {
			gge::widgets::WR.LoadedEvent.Unregister(this, &BasicOrganizer::wr_loaded);
			Buttons.Destroy();
		}

		static IOrganizer *Create() { return new BasicOrganizer(); }

	protected:
		Menu *parent;

		gge::utils::Collection<gge::widgets::Button>	Buttons;
		gge::widgets::VirtualPanel			vp;
		gge::widgets::Panel					panel;

		int size;
		Alignment align;
		gge::utils::Point location;
		Layout layout;
		CycleStrategy cycle;
		int spacing;

		gge::widgets::checkbox::Blueprint *btn_st;
		gge::widgets::checkbox::Blueprint *btn_end;
		gge::utils::Collection<gge::widgets::checkbox::Blueprint> btn_mid;
		gge::widgets::panel::Blueprint    *pnl_bp;

		gge::widgets::Button *prev_first, *prev_last;

		void reorganize_completed() {
			if(!prev_last) return;

			if(layout==Horizontal)
				panel.SetWidth(prev_last->GetX()+prev_last->GetWidth());
			else
				panel.SetHeight(prev_last->GetY()+prev_last->GetHeight());
		}

		void wr_loaded() {
			if(btn_mid.GetCount()==0 && gge::widgets::WR.Buttons.Decorative) {
				for(auto button=Buttons.First();button.IsValid();button.Next()) {
					button->SetBlueprint(gge::widgets::WR.Buttons.Decorative);
				}
			}
		}

		BasicOrganizer() : parent(NULL), prev_first(NULL), prev_last(NULL),
			spacing(0), cycle(Random), location(0,0), align(), size(0), layout(Horizontal)
		{
			vp<<panel;
			panel.Padding=0;
			gge::widgets::WR.LoadedEvent.Register(this, &BasicOrganizer::wr_loaded);
		}
	};

} }