#pragma once

#include <sstream>

#include <Widgets/Panel.h>
#include <Widgets/Label.h>
#include <Widgets/Organizers/LinearOrganizer.h>
#include <Widgets/Window.h>
#include <Widgets/DialogWindow.h>
#include <Widgets/Listbox.h>

#include "../Assets/Item.h"
#include "../Mechanics/PlayerGame.h"
#include "../Mechanics/Item.h"
#include "Actions.h"

//for vs
#undef interface

namespace interface {

	class ItemChooser : public gge::widgets::DialogWindow {
	public:
		ItemChooser() : 
		  accepted("Accepted", this)
		  {
			  SetOrganizer(organizer);

			  ok.Text="Ok";
			  cancel.Text="Cancel";

			  SetDefault(ok);
			  SetCancel(cancel);

			  Title="Item chooser";

			  auto nl=organizer.nextline;

			  organizer
				  <<type<<nl
				  <<info<<nl
				  <<cancel<<ok<<nl
				  ;

			  info.Autosize=gge::widgets::AutosizeModes::None;
			  info.SetHeight(55);
			  Reorganize();

			  Hide();

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

			  type.ItemClickedEvent.RegisterLambda([&] {
				  if(this->type.GetSelectedItem()) {
					  if(prev==this->type.GetValue()) {
						  ok.ClickEvent();
					  }
					  ok.Enable();

					  if(this->type.FindLocation(*this->type.GetSelectedItem())!=0) {
						  auto &item=listedItems[this->type.FindLocation(*this->type.GetSelectedItem())]->provider();

						  std::stringstream ss;

						  if(item.type==assets::Item::Armor) {
							  ss<<"Armor: "<<item.armor;
						  }
						  else if(item.type==assets::Item::Passive) {
						  }
						  else {
							  ss<<"Damage: "<<item.damage<<" ("<<std::fixed<<std::setprecision(1)<<item.CD/1000.f<<"s)";
							  if(item.parry>0)
								  ss<<", parry: "<<item.parry;
							  if(item.block>0)
								  ss<<", block: "<<item.block;
						  }

						  info.Text=ss.str();
					  }
					  else {
						  info.Text="";
					  }

					  prev=this->type.GetValue();
				  }
			  });

			  ok.ClickEvent.RegisterLambda([&]{
				  accepted(listedItems[this->type.FindLocation(*this->type.GetSelectedItem())]);
				  Close();
			  });

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

		void update() {
			type.DeleteAll();

			listedItems.clear();
			type.Add("[ NONE ]");
			listedItems.push_back(NULL);

			for(auto it=mechanics::PlayerGame::current().getCraftedItemList().begin();it!=mechanics::PlayerGame::current().getCraftedItemList().end();++it) {
				if((*it)->provider().slot==slot) {
					type.Add((*it)->name());
					listedItems.push_back(*it);
				}
			}
		}

		virtual void Show(assets::Item::Slot slot) {
			this->slot=slot;

			update();

			if(!this->IsVisible()) cancelCount++;
			gge::widgets::DialogWindow::Show(true);
			Move(
				(gge::widgets::TopLevel.GetWidth()-GetWidth())*3/4,
				gge::widgets::TopLevel.GetHeight()-GetHeight()-150
			);

			prev="";
			ok.Disable();
		}



		assets::Item::Slot slot;

		gge::utils::EventChain<ItemChooser, mechanics::Item*> accepted;

	protected:
		gge::widgets::Listbox<std::string> type;
		gge::widgets::Button ok, cancel;
		gge::widgets::LinearOrganizer organizer;
		gge::widgets::Label info;

		std::vector<mechanics::Item*> listedItems;

		std::string prev;

	};

}
