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

#include "DeerStudio/EditorEngine.h"
#include "DeerStudio/EditorEngine/AngelscriptPredefined.h"
#include "DeerStudio/EditorEngine/DockPanel/DockPanelContext.h"
#include "DeerStudio/EditorEngine/DockPanel/DockPanelObject.h"
#include "DeerStudio/EditorEngine/ServiceScript/ServiceScriptContext.h"

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

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

namespace Deer {
	namespace EditorEngine {
		asIScriptEngine *scriptEngine = nullptr;

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

		asIScriptContext *executingScriptContext;

		bool active = false;
	} // namespace EditorEngine

	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();

		// We generate a as.predefined file generic for services
		generateAngelscriptPredefined();
		loadServiceScripts();

		generateAngelscriptPredefined();
		loadDockPanels();

		active = true;
		for (ServiceScriptContext &service : serviceScriptModules) {
			service.init();
		}

		for (DockPanelContext &pannel : dockPanelModules)
			pannel.init();
	}

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

		if (scriptEngine)
			scriptEngine->ShutDownAndRelease();

		scriptEngine = nullptr;
		active = false;
	}

	void EditorEngine::render() {
		if (!active)
			return;

		for (auto &panel : dockPanelModules)
			panel.render();
	}
} // namespace Deer