#include "DeerStudio/StudioAPI/Menu.h"
#include "angelscript.h"
#include "imgui.h"
#include "scriptany.h"

#include "DeerStudio/AngelScriptEngine.h"
#include "DeerStudio/AngelScriptEngine/ErrorHandle.h"

namespace Deer {
	namespace StudioAPI {
		namespace MenuContext {
			CScriptAny* payload = nullptr;
			std::string menuId;
		} // namespace MenuContext

		void contextItemPopup(std::string& menu_id, asIScriptFunction* func) {
			ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
			if (ImGui::BeginPopupContextItem(menu_id.c_str())) {

				if (AngelScriptEngine::scriptContext &&
				    AngelScriptEngine::scriptContext->PushState() == asSUCCESS) {

					AS_CHECK(AngelScriptEngine::scriptContext->Prepare(func));
					AS_CHECK(AngelScriptEngine::scriptContext->Execute());

					AngelScriptEngine::scriptContext->PopState();
				} else {
					ImGui::Text("Something failed");
				}

				ImGui::EndPopup();
			}
			ImGui::PopStyleVar();
		}

		void contextMenuPopup(std::string& menu_id, asIScriptFunction* func) {
			ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
			if (ImGui::BeginPopupContextWindow(menu_id.c_str())) {

				if (AngelScriptEngine::scriptContext &&
				    AngelScriptEngine::scriptContext->PushState() == asSUCCESS) {

					AS_CHECK(AngelScriptEngine::scriptContext->Prepare(func));
					AS_CHECK(AngelScriptEngine::scriptContext->Execute());

					AngelScriptEngine::scriptContext->PopState();
				} else {
					ImGui::Text("Something failed");
				}

				ImGui::EndPopup();
			}
			ImGui::PopStyleVar();
		}

		void closePopup() {
			if (MenuContext::payload) {
				MenuContext::payload->Release();
				MenuContext::payload = nullptr;
			}

			MenuContext::menuId = "";
			ImGui::CloseCurrentPopup();
		}

		void openPopup(std::string& menu_id, CScriptAny* data) {
			if (MenuContext::payload) {
				MenuContext::payload->Release();
			}

			data->AddRef();
			MenuContext::payload = data;
			MenuContext::menuId = menu_id;
		}

		void modalPopup(std::string& menu_id, asIScriptFunction* func) {
			if (!ImGui::IsPopupOpen("", ImGuiPopupFlags_AnyPopup) &&
			    MenuContext::menuId == menu_id) {
				ImGui::OpenPopup(menu_id.c_str());
				MenuContext::menuId = "";
			}

			ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
			if (ImGui::BeginPopupModal(menu_id.c_str())) {
				// This should not happen
				if (!MenuContext::payload) {
					ImGui::CloseCurrentPopup();
					ImGui::EndPopup();
					ImGui::PopStyleVar();

					return;
				}

				if (AngelScriptEngine::scriptContext &&
				    AngelScriptEngine::scriptContext->PushState() == asSUCCESS) {
					AS_CHECK(AngelScriptEngine::scriptContext->Prepare(func));

					AS_CHECK(AngelScriptEngine::scriptContext->SetArgObject(
					    0, MenuContext::payload));

					AS_CHECK(AngelScriptEngine::scriptContext->Execute());

					AngelScriptEngine::scriptContext->PopState();
				} else {
					ImGui::Text("Something failed");
				}

				ImGui::EndPopup();
			}
			ImGui::PopStyleVar();
		}

		void simplePopup(std::string& menu_id, asIScriptFunction* func) {
			if (!ImGui::IsPopupOpen("", ImGuiPopupFlags_AnyPopup)) {
				if (MenuContext::menuId == menu_id) {
					ImGui::OpenPopup(menu_id.c_str());
					MenuContext::menuId = "";

					ImVec2 mouse_pos = ImGui::GetMousePos();
					ImVec2 popup_size = ImVec2(200, 0);
					ImVec2 popup_pos =
					    ImVec2(mouse_pos.x - popup_size.x * 0.5f, mouse_pos.y);
					ImGui::SetNextWindowSize(popup_size);
					ImGui::SetNextWindowPos(popup_pos, ImGuiCond_Appearing);

					// In the case a payload is loaded we unload it
				} else if (MenuContext::payload && MenuContext::menuId == "") {
					MenuContext::payload->Release();
					MenuContext::payload = nullptr;
				}
			}

			ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
			if (ImGui::BeginPopup(menu_id.c_str())) {
				// This should not happen
				if (!MenuContext::payload) {
					ImGui::CloseCurrentPopup();
					ImGui::EndPopup();
					ImGui::PopStyleVar();
					return;
				}

				if (AngelScriptEngine::scriptContext &&
				    AngelScriptEngine::scriptContext->PushState() == asSUCCESS) {
					AS_CHECK(AngelScriptEngine::scriptContext->Prepare(func));
					AS_CHECK(AngelScriptEngine::scriptContext->Execute());

					AngelScriptEngine::scriptContext->PopState();
				} else {
					ImGui::Text("Something failed");
				}

				ImGui::EndPopup();
			}
			ImGui::PopStyleVar();
		}
	} // namespace StudioAPI
} // namespace Deer