#pragma once

#include <Widgets/DialogWindow.h>
#include <Widgets/Button.h>
#include <Widgets/Numberbox.h>
#include <Widgets/Organizers/LinearOrganizer.h>
#include <Utils/StringEnum.h>

using namespace gge;

class EventType {
public:
	enum Type {
		Timer,
		Revealed,
		Destroyed,
		NthCitizen,
		NthSoldier,
		NthKill,
		NthRaid,
		NthTownBuilding,
		NthCrafting,
		end
	};

	static const char *Names[];
};

typedef utils::StringEnum<EventType> EventTypeEnum;


class MapEvents : public widgets::DialogWindow {
	friend class UI;

public:
	MapEvents() {
		SetOrganizer(organizer);

		auto nl=organizer.nextline;

		SetWidth(350);

		New.Text="New";
		Delete.Text="Delete";

		organizer
			<<EventList<<nl
			<<New<<Delete<<nl
			<<"Title: "<<Title<<nl
			<<"Type: "<<Type<<nl
			<<"Condition: "<<Condition<<nl
			<<"Image: "<<Image<<nl
			<<"Text:"<<nl
			<<Text<<nl
		;

		EventTypeEnum::AddAll(Type);

		widgets::DialogWindow::Title="Map Events";
		Ok.Text="Ok";

		AddDialogButton(Ok);
		SetCancel(Ok);

		MoveToCenter();

		Hide();

		EventList.ItemClickedEvent.RegisterLambda([&] {
			if(EventList.GetSelectedItem())
				Edit(EventList.FindLocation(*EventList.GetSelectedItem()));
		});

		New.ClickEvent.Register(this, &MapEvents::NewEvent);

		Title.ChangeEvent.RegisterLambda([&] {
			target->Get<resource::StringData>(editindex+0).value=Title.Text;

			std::stringstream ss;
			ss<<EventTypeEnum::ToString((EventTypeEnum::Type)target->getInt(editindex+1));
			ss<<" "<<target->getString(editindex+2)<<": "<<target->getString(editindex+0);

			EventList.GetSelectedItem()->Value=ss.str();
		});

		Type.ChangeEvent.RegisterLambda([&] {
			target->Get<resource::IntegerData>(editindex+1).value=Type.GetValue();

			std::stringstream ss;
			ss<<EventTypeEnum::ToString((EventTypeEnum::Type)target->getInt(editindex+1));
			ss<<" "<<target->getString(editindex+2)<<": "<<target->getString(editindex+0);

			EventList.GetSelectedItem()->Value=ss.str();
		});

		Condition.ChangeEvent.RegisterLambda([&] {
			target->Get<resource::StringData>(editindex+2).value=Condition.Text;

			std::stringstream ss;
			ss<<EventTypeEnum::ToString((EventTypeEnum::Type)target->getInt(editindex+1));
			ss<<" "<<target->getString(editindex+2)<<": "<<target->getString(editindex+0);

			EventList.GetSelectedItem()->Value=ss.str();
		});

		Image.ChangeEvent.RegisterLambda([&] {
			target->Get<resource::StringData>(editindex+3).value=Image.Text;
		});

		Text.ChangeEvent.RegisterLambda([&] {
			target->Get<resource::StringData>(editindex+4).value=Text.Text;
		});

		Ok.ClickEvent.Register(this, &MapEvents::Close);
	}

	void NewEvent() {
		int ind=target->GetCount();
		target->Add("Welcome").name="Title";
		target->Add(0).name="Type";
		target->Add("0").name="Condition";
		target->Add("").name="Image";
		target->Add("Welcome to Libreland.").name="Text";

		EventList.Add("Timer 0: Welcome");


		EventList.SetSelected(*EventList.Last());
	}

	void Edit(int ind) {
		enable();
		editindex=ind*5;
		Title=target->getString(editindex+0);
		Type.SetValue((EventTypeEnum::Type)target->getInt(editindex+1));
		Condition=target->getString(editindex+2);
		Image=target->getString(editindex+3);
		Text=target->getString(editindex+4);
	}

	void List() {
		disable();
		EventList.DeleteAll();

		for(int i=0;i<target->GetCount();i+=5) {
			std::stringstream ss;
			ss<<EventTypeEnum::ToString((EventTypeEnum::Type)target->getInt(i+1));
			ss<<" "<<target->getString(i+2)<<": "<<target->getString(i+0);

			EventList.Add(ss.str());
		}
	}

	void enable() {
		Title.Enable();
		Type.Enable();
		Condition.Enable();
		Image.Enable();
		Text.Enable();
	}

	void disable() {
		Title.Disable();
		Type.Disable();
		Condition.Disable();
		Image.Disable();
		Text.Disable();
	}

	virtual void Show(bool focus=true) {
		DialogWindow::Show(focus);
		
		List();
	}

	~MapEvents() {
		RemoveOrganizer();
	}

	int editindex;

	widgets::Button Ok, New, Delete;
	widgets::Listbox<> EventList;
	widgets::Textbox Title, Condition, Image, Text;
	widgets::Combobox<EventTypeEnum::Type, EventTypeEnum::ConvertToString> Type;
	widgets::LinearOrganizer organizer;

	gorgon::DataArray *target;
};
