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

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

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

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

void extract_angelScript();
		
namespace Deer {
    namespace EditorEngine {
        asIScriptEngine* scriptEngine = nullptr;

        std::vector<DockPanelContext> dockPanelModules;
        DockPanelObject* currentDockPanelExecution = nullptr;

        asIScriptContext* executingScriptContext;

        bool active = false;
    }

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

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

        scriptEngine = asCreateScriptEngine();

        AS_RET_CHECK(scriptEngine->SetMessageCallback(asFUNCTION(Deer::EditorEngine::errorCallback), 0, asCALL_CDECL));

        RegisterStdString(scriptEngine);
        RegisterScriptArray(scriptEngine, true);
        RegisterScriptDictionary(scriptEngine);

        registerEditorEngineStructs();
        registerEditorEngineFunctions();

        // This is simply to generate the as.predefined for better experience
		extract_angelScript();
		
        loadDockPanels();

        active = true;
        for (DockPanelContext& pannel : dockPanelModules) 
            pannel.init();

    }

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

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

    void EditorEngine::render() {
        if (!active)
            return;
        
        for (auto& panel : dockPanelModules)
            panel.render();
    }
}