#pragma once

#pragma once

#include <Widgets/Panel.h>
#include <Widgets/Label.h>
#include "../Mechanics/PlayerGame.h"
#include <sstream>
#include <Widgets/Organizers/LinearOrganizer.h>
#include "../Mechanics/Townsfolk.h"
#include "../Mechanics/Soldier.h"
#include <Widgets/Window.h>
#include <Widgets/DialogWindow.h>
#include <Widgets/Listbox.h>
#include "Actions.h"
#include "ItemChooser.h"
#include "../Mechanics/MilitaryBuilding.h"

//for vs
#undef interface

namespace interface {

	class Inventory : public gge::widgets::DialogWindow {
	public:
		Inventory() : accepted("Accepted", this) {
			ok.Text="Ok";

			SetDefault(ok);
			SetCancel(ok);

			AddDialogButton(ok);

			Title="Inventory";

			Resize(340,255);

			headL.SetContainer(this);
			headL.Text="Head";
			headL.SetBlueprint(gge::widgets::WR.Labels.Bold);
			headL.Move(110,0);

			headN.SetContainer(this);
			headN.Text="";
			headN.Move(110,20);

			headSel.SetContainer(this);
			headSel.Text="Choose";
			headSel.Move(110,45);
			headSel.ClickEvent.RegisterLambda([&]{
				itemChooser.Show(assets::Item::HeadArmor);
			});



			mainL.SetContainer(this);
			mainL.Text="Main hand";
			mainL.SetBlueprint(gge::widgets::WR.Labels.Bold);
			mainL.Move(0,90);

			mainN.SetContainer(this);
			mainN.Text="";
			mainN.Move(0,110);

			mainSel.SetContainer(this);
			mainSel.Text="Choose";
			mainSel.Move(0,135);
			mainSel.ClickEvent.RegisterLambda([&]{
				itemChooser.Show(assets::Item::MainHand);
			});



			chestL.SetContainer(this);
			chestL.Text="Body armor";
			chestL.SetBlueprint(gge::widgets::WR.Labels.Bold);
			chestL.Move(110,90);

			chestN.SetContainer(this);
			chestN.Text="";
			chestN.Move(110,110);

			chestSel.SetContainer(this);
			chestSel.Text="Choose";
			chestSel.Move(110,135);
			chestSel.ClickEvent.RegisterLambda([&]{
				itemChooser.Show(assets::Item::BodyArmor);
			});



			offhandL.SetContainer(this);
			offhandL.Text="Offhand";
			offhandL.SetBlueprint(gge::widgets::WR.Labels.Bold);
			offhandL.Move(220,90);

			offhandN.SetContainer(this);
			offhandN.Text="";
			offhandN.Move(220,110);

			offhandSel.SetContainer(this);
			offhandSel.Text="Choose";
			offhandSel.Move(220,135);
			offhandSel.ClickEvent.RegisterLambda([&]{
				itemChooser.Show(assets::Item::OffHand);
			});

			info.Move(0, 165);
			info.Resize(200, 20);
			info.SetContainer(this);
			

			Hide();

			ok.ClickEvent.Register(this, &gge::widgets::DialogWindow::Close);

			itemChooser.accepted.RegisterLambda([&](mechanics::Item *item) {
				if(!mechanics::Map::current().getPointInfoMap()(soldier->currentLocation()).buildable) {
					soldier->log("Out of city.");
					return;
				}
				mechanics::Item *prev=soldier->inventory().items[itemChooser.slot];

				if(prev) {
					if(prev->provider().ID=="Unarmored") {
						if(item) {
							soldier->removeItem(prev);
							delete prev;
						}
						else
							return;
					}
					else {
						mechanics::StorageBuilding *storage=NULL;
						for(unsigned j=0;j<mechanics::PlayerGame::current().getMilitaryBuildingList().size();j++) {
							if(dynamic_cast<mechanics::StorageBuilding*>(mechanics::PlayerGame::current().getMilitaryBuildingList()[j])) {
								auto mb=dynamic_cast<mechanics::StorageBuilding*>(mechanics::PlayerGame::current().getMilitaryBuildingList()[j]);
								if(mb->storageType()==prev->type()) {
									if(mb->isAvailable()) {
										storage=mb;
										break;
									}
								}
							}
						}

						if(!storage) {
							soldier->log	("Cannot store weapon");
							return;
						}

						storage->store(prev);
						soldier->removeItem(prev);

						soldier->moveTo(storage->provider().usablePoints[0]+storage->currentLocation());

						//!add to storage
						mechanics::PlayerGame::current().addItem(*prev);
					}
				}

				if(item) {
					mechanics::StorageBuilding *storage=mechanics::PlayerGame::current().takeItem(*item);
					soldier->addItem(*item, true);
					if(storage)
#ifdef LINUX
						soldier->moveTo(storage->provider().usablePoints[0]+storage->currentLocation());
#else
						soldier->moveTo(gge::utils::Random((std::vector<gge::utils::Point>)storage->provider().usablePoints)+storage->currentLocation());
#endif
				}
				else if(itemChooser.slot==assets::Item::BodyArmor) {
					mechanics::Item &body=*new mechanics::Item(*assets::Item::list["Unarmored"], *new graphics::Animation(*assets::Item::list["Unarmored"]->animation));
					soldier->addItem(body, true);
				}

				Show(soldier);
			});

			ClosingEvent.RegisterLambda([&] {
				cancelCount--;
			});
		}

		void update() {
			if(mechanics::Map::current().getPointInfoMap()(soldier->currentLocation()).buildable) {
				headSel.Enable();
				mainSel.Enable();
				chestSel.Enable();
				offhandSel.Enable();
				info.Text="";
			}
			else {
				headSel.Disable();
				mainSel.Disable();
				chestSel.Disable();
				offhandSel.Disable();
				info.Text="Should be in town range to be able to switch equipment.";
			}
		}

		virtual void Show(mechanics::Soldier *soldier) {
			this->soldier=soldier;
			update();

			if(!this->IsVisible()) cancelCount++;
			gge::widgets::DialogWindow::Show(true);

			Title="Inventory of "+soldier->name()+" "+soldier->surname();


			if(soldier->inventory().headArmor) {
				headN.Text=soldier->inventory().headArmor->provider().ID;
			}
			else {
				headN.Text="None";
			}

			if(soldier->inventory().mainHand) {
				mainN.Text=soldier->inventory().mainHand->provider().ID;
			}
			else {
				mainN.Text="None";
			}

			if(soldier->inventory().bodyArmor) {
				chestN.Text=soldier->inventory().bodyArmor->provider().ID;
			}
			else {
				chestN.Text="None";
			}

			if(soldier->inventory().offHand) {
				offhandN.Text=soldier->inventory().offHand->provider().ID;
			}
			else {
				offhandN.Text="None";
			}

			MoveToCenter();
		}



		gge::utils::EventChain<Inventory, std::string> accepted;
	protected:
		gge::widgets::Listbox<std::string> type;
		gge::widgets::Button ok;
		gge::widgets::LinearOrganizer organizer;

		ItemChooser itemChooser;

		mechanics::Soldier *soldier;

		gge::widgets::Label headL, mainL, chestL, offhandL;
		gge::widgets::Label headN, mainN, chestN, offhandN;
		gge::widgets::Button headSel, mainSel, chestSel, offhandSel;

		gge::widgets::Label info;
	};

}
