#include "DeerStudio/EditorEngine.h"
#include "DeerStudio/EditorEngine/ErrorHandle.h"
#include "DeerStudio/EditorEngine/API.h"

#include "DeerStudio/EditorEngine/DockPanelObject.h"
#include "DeerStudio/EditorEngine.h"

#include "Deer/Log.h"
#include <vector>

#include "angelscript.h"
#include "scriptbuilder.h"
#include "scriptstdstring.h"

void extract_angelScript();
		
namespace Deer {
    namespace EditorEngine {
        asIScriptEngine* scriptEngine = nullptr;
		asIScriptModule* scriptModule = nullptr;
		asIScriptContext* scriptContext = nullptr;

        std::vector<DockPanelObject> dockPanels;
        DockPanelObject* currentDockPanelExecution = nullptr;

        bool active = false;
    }

    void EditorEngine::initialize() {
        int err = 0;

        // If it exist we will reload it
        deinitialize();

        scriptEngine = asCreateScriptEngine();
        RegisterStdString(scriptEngine);

        AS_RET_CHECK(scriptEngine->SetMessageCallback(asFUNCTION(Deer::EditorEngine::errorCallback), 0, asCALL_CDECL));
        
        DEER_CORE_TRACE("Registering Editor Engine interface");
        registerEditorEngineStructs();
        registerEditorEngineFunctions();
        registerDockPanel();

		loadScripts();

		scriptModule = scriptEngine->GetModule("DeerModule");
		scriptContext = scriptEngine->CreateContext();

		extract_angelScript();
		
        extractDockPanels();

        active = true;

        for (auto& pannel : dockPanels) {
            currentDockPanelExecution = &pannel;
            pannel.init();
        }
        currentDockPanelExecution = nullptr;
    }

    void EditorEngine::deinitialize() {
        dockPanels.clear();

        if (scriptContext)
		    scriptContext->Release();
        if (scriptEngine)
            scriptEngine->ShutDownAndRelease();
        
        scriptEngine = nullptr;
		scriptModule = nullptr;
		scriptContext = nullptr;
        
		active = false;
    }

    void EditorEngine::render() {
        if (!active)
            return;
        
        for (auto& panel : dockPanels) {
            currentDockPanelExecution = &panel;
            panel.executeRender();
        }
        currentDockPanelExecution = nullptr;
    }
}