#include "DeerStudio/StudioAPI/UI.h"
#include "DeerStudio/AngelScriptEngine/AngelScriptRegisters.h"
#include "DeerStudio/StudioAPI/Layout.h"
#include "DeerStudio/StudioAPI/Menu.h"
#include "imgui.h"

namespace Deer {
	void AngelScriptEngine::registerUIFunctions() {
		scriptEngine->SetDefaultNamespace("UI");

		// Buttons
		REGISTER_GLOBAL_FUNC("bool button(const string& in text)", StudioAPI::button);
		REGISTER_GLOBAL_FUNC("bool buttonCenter(const string& in text)", StudioAPI::buttonCenter);
		REGISTER_GLOBAL_FUNC("bool buttonEnd(const string& in text)", StudioAPI::buttonEnd);

		REGISTER_GLOBAL_FUNC("bool cartIconButton(const string& in label, const string& in icon, int iconSize, int width)", StudioAPI::cartIconButton);
		REGISTER_GLOBAL_FUNC("bool cartIconButton(const string& in label, FrameBuffer frameBuffer, int iconSize, int width)", StudioAPI::cartIconButton_frameBuffer);

		// Checkboxes
		REGISTER_GLOBAL_FUNC("bool checkbox(const string& in text, bool value)", StudioAPI::checkbox);
		REGISTER_GLOBAL_FUNC("bool checkboxDisabled(const string& in text, bool value)", StudioAPI::checkboxDisabled);

		// Sliders & Inputs
		REGISTER_GLOBAL_FUNC("float magicSlider(const string& in text, float value, float speed)", StudioAPI::magicSlider);
		REGISTER_GLOBAL_FUNC("vec3 magicSlider3(const string& in text, vec3 value, float speed)", StudioAPI::magicSlider3);
		REGISTER_GLOBAL_FUNC("int sliderInt(string& in text, int value, int min, int max)", StudioAPI::sliderInt);
		REGISTER_GLOBAL_FUNC("float slider(string& in text, float value, float min, float max)", StudioAPI::slider);
		REGISTER_GLOBAL_FUNC("bool inputText(const string& in text, const string& in value, string& out valueOutput)", StudioAPI::inputText);

		// Menus
		REGISTER_GLOBAL_FUNC("bool menuItem(const string& in text)", StudioAPI::menuItem);
		REGISTER_GLOBAL_FUNC("void menuItemDisabled(const string& in text)", StudioAPI::menuItemDisabled);
		REGISTER_GLOBAL_FUNC("void subMenu(const string& in text, Callback@+ func)", StudioAPI::subMenu);

		// Text
		REGISTER_GLOBAL_FUNC("void text(const string& in text)", StudioAPI::text);
		REGISTER_GLOBAL_FUNC("void textCenter(const string& in text)", StudioAPI::textCenter);
		REGISTER_GLOBAL_FUNC("void textEnd(const string& in text)", StudioAPI::textEnd);
		REGISTER_GLOBAL_FUNC("void textColor(float r, float g, float b, const string& in text)", StudioAPI::textColor);

		// Titles
		REGISTER_GLOBAL_FUNC("void title(const string& in text)", StudioAPI::title);
		REGISTER_GLOBAL_FUNC("void titleCenter(const string& in text)", StudioAPI::titleCenter);
		REGISTER_GLOBAL_FUNC("void titleCenterY(const string& in text, int height)", StudioAPI::titleCenterY);
		REGISTER_GLOBAL_FUNC("void titleEnd(const string& in text)", StudioAPI::titleEnd);

		// Layout helpers
		REGISTER_GLOBAL_FUNC("void sameline()", StudioAPI::sameline);
		REGISTER_GLOBAL_FUNC("void separator()", StudioAPI::separator);
		REGISTER_GLOBAL_FUNC("void space()", StudioAPI::space);
		REGISTER_GLOBAL_FUNC("void space(int x, int y = 10)", StudioAPI::space_params);

		// Drawing
		REGISTER_GLOBAL_FUNC("void drawFrameBuffer(FrameBuffer, int, int)", StudioAPI::drawFrameBuffer);
		REGISTER_GLOBAL_FUNC("void drawFrameBufferCentered(FrameBuffer, int, int)", StudioAPI::drawFrameBufferCentered);
		REGISTER_GLOBAL_FUNC("void drawIcon(const string& in, int)", StudioAPI::drawIcon);
		REGISTER_GLOBAL_FUNC("void drawIconCentered(const string& in, int)", StudioAPI::drawIconCentered);
		REGISTER_GLOBAL_FUNC("void drawIconHighlight(const string& in, int)", StudioAPI::drawIconHighlight);
		REGISTER_GLOBAL_FUNC("void drawIconCenteredHighlight(const string& in, int)", StudioAPI::drawIconCenteredHighlight);

		REGISTER_GLOBAL_FUNC("void drawIcon(Texture texture, int)", StudioAPI::drawIcon_resource);
		REGISTER_GLOBAL_FUNC("void drawIconCentered(Texture texture, int)", StudioAPI::drawIconCentered_resource);
		REGISTER_GLOBAL_FUNC("void drawIconHighlight(Texture texture, int)", StudioAPI::drawIconHighlight_resource);
		REGISTER_GLOBAL_FUNC("void drawIconCenteredHighlight(Texture texture, int)", StudioAPI::drawIconCenteredHighlight_resource);

		// Input state
		REGISTER_GLOBAL_FUNC("bool isKeyDown(key)", StudioAPI::isKeyDown);
		REGISTER_GLOBAL_FUNC("bool isKeyPressed(key)", StudioAPI::isKeyPressed);
		REGISTER_GLOBAL_FUNC("bool isMouseDragging(key)", StudioAPI::isMouseDragging);
		REGISTER_GLOBAL_FUNC("bool isItemClicked(int)", StudioAPI::isItemClicked);
		REGISTER_GLOBAL_FUNC("bool isMouseDoubleClicked(int)", StudioAPI::isMouseDoubleClicked);

		// Mouse info
		REGISTER_GLOBAL_FUNC("float getMouseDragDeltaX()", StudioAPI::getMouseDragDeltaX);
		REGISTER_GLOBAL_FUNC("float getMouseDragDeltaY()", StudioAPI::getMouseDragDeltaY);
		REGISTER_GLOBAL_FUNC("float getMouseDeltaX()", StudioAPI::getMouseDeltaX);
		REGISTER_GLOBAL_FUNC("float getMouseDeltaY()", StudioAPI::getMouseDeltaY);

		// Panel & layout control
		REGISTER_GLOBAL_FUNC("bool isPanelActive()", StudioAPI::isPanelActive);
		REGISTER_GLOBAL_FUNC("void disablePanelPadding(bool)", StudioAPI::disablePanelPadding);
		REGISTER_GLOBAL_FUNC("int getAvailableSizeX()", StudioAPI::getAvailableSizeX);
		REGISTER_GLOBAL_FUNC("int getAvailableSizeY()", StudioAPI::getAvailableSizeY);

		// Columns
		REGISTER_GLOBAL_FUNC("void automaticColumns(int)", StudioAPI::automaticColumns);
		REGISTER_GLOBAL_FUNC("void columns(int)", StudioAPI::columns);
		REGISTER_GLOBAL_FUNC("void nextColumn()", StudioAPI::nextColumn);
		REGISTER_GLOBAL_FUNC("void endColumns()", StudioAPI::endColumns);

		// Tree & Components
		REGISTER_GLOBAL_FUNC("void treeNodeLeaf(const string& in, bool)", StudioAPI::treeNodeLeaf);
		REGISTER_GLOBAL_FUNC("bool treeNode(const string& in, bool, Callback@+)", StudioAPI::treeNode);
		REGISTER_GLOBAL_FUNC("bool componentNode(const string& in, Callback@+)", StudioAPI::componentNode);
		REGISTER_GLOBAL_FUNC("bool componentNodeContextMenu(const string& in,  Callback@+, Callback@+)", StudioAPI::componentNodeContextMenu);

		// Popups & Modals
		REGISTER_GLOBAL_FUNC("void contextItemPopup(const string& in, Callback@+)", StudioAPI::contextItemPopup);
		REGISTER_GLOBAL_FUNC("void contextMenuPopup(const string& in, Callback@+)", StudioAPI::contextMenuPopup);
		REGISTER_GLOBAL_FUNC("void modalPopup(const string& in, Callback@+)", StudioAPI::modalPopup);
		REGISTER_GLOBAL_FUNC("void simplePopup(const string& in, Callback@+)", StudioAPI::simplePopup);
		REGISTER_GLOBAL_FUNC("void openPopup(const string& in, any@)", StudioAPI::openPopup);
		REGISTER_GLOBAL_FUNC("void closePopup()", StudioAPI::closePopup);

		// Drag & Drop
		REGISTER_GLOBAL_FUNC("void dragDropSource(const string& in, any@+, const string& in)", StudioAPI::dragDropSource);
		REGISTER_GLOBAL_FUNC("void dragDropTarget(const string& in, AnyCallback@+)", StudioAPI::dragDropTarget);
		scriptEngine->SetDefaultNamespace("");
	}


    void AngelScriptEngine::registerUIStructs() {
        AS_CHECK(scriptEngine->RegisterEnum("key"));

        AS_CHECK(scriptEngine->RegisterEnumValue("key", "A", ImGuiKey_A));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "B", ImGuiKey_B));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "C", ImGuiKey_C));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "D", ImGuiKey_D));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "E", ImGuiKey_E));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "F", ImGuiKey_F));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "G", ImGuiKey_G));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "H", ImGuiKey_H));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "I", ImGuiKey_I));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "J", ImGuiKey_J));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "K", ImGuiKey_K));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "L", ImGuiKey_L));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "M", ImGuiKey_M));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "N", ImGuiKey_N));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "O", ImGuiKey_O));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "P", ImGuiKey_P));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "Q", ImGuiKey_Q));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "R", ImGuiKey_R));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "S", ImGuiKey_S));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "T", ImGuiKey_T));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "U", ImGuiKey_U));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "V", ImGuiKey_V));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "W", ImGuiKey_W));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "X", ImGuiKey_X));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "Y", ImGuiKey_Y));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "Z", ImGuiKey_Z));

        AS_CHECK(scriptEngine->RegisterEnumValue("key", "K0", ImGuiKey_0));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "K1", ImGuiKey_1));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "K2", ImGuiKey_2));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "K3", ImGuiKey_3));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "K4", ImGuiKey_4));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "K5", ImGuiKey_5));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "K6", ImGuiKey_6));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "K7", ImGuiKey_7));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "K8", ImGuiKey_8));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "K9", ImGuiKey_9));

        AS_CHECK(scriptEngine->RegisterEnumValue("key", "Tab", ImGuiKey_Tab));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "Enter", ImGuiKey_Enter));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "Escape", ImGuiKey_Escape));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "Backspace", ImGuiKey_Backspace));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "Space", ImGuiKey_Space));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "Delete", ImGuiKey_Delete));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "Insert", ImGuiKey_Insert));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "Home", ImGuiKey_Home));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "End", ImGuiKey_End));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "PageUp", ImGuiKey_PageUp));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "PageDown", ImGuiKey_PageDown));
        
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "Right", ImGuiKey_RightArrow));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "Up", ImGuiKey_UpArrow));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "Down", ImGuiKey_DownArrow));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "Left", ImGuiKey_LeftArrow));
        
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "RightCtrl", ImGuiKey_RightCtrl));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "LeftShift", ImGuiKey_LeftShift));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "RightShift", ImGuiKey_RightShift));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "LeftAlt", ImGuiKey_LeftAlt));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "RightAlt", ImGuiKey_RightAlt));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "LeftSuper", ImGuiKey_LeftSuper));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "RightSuper", ImGuiKey_RightSuper));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "LeftCtrl", ImGuiKey_LeftCtrl));

        AS_CHECK(scriptEngine->RegisterEnumValue("key", "MouseLeft", ImGuiKey_MouseLeft));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "MouseRight", ImGuiKey_MouseRight));
        AS_CHECK(scriptEngine->RegisterEnumValue("key", "MouseMiddle", ImGuiKey_MouseMiddle));
    }


} // namespace Deer