#include ".\pythoninclude\Python.h"
#include "scripts.h"
#include "engine.h"
#include "gmmain.h"
#include "plugin.h"
#include "gmconsolecommands.h"
#include "vector3_type.h"
#pragma warning( disable : 701 127 )

int *CommandsCount;
ConsoleCommand *CommandsArray;
_SortCommands SortCommands;
_UpdateCommands UpdateCommands;

ConsoleCommand::~ConsoleCommand() {
}

ConsoleCommand::ConsoleCommand() {
	_asm {
		lea eax, this
		push eax
		mov ecx, 0x0081D098
		mov eax, 0x00428FE0
		call eax
	}
}

void ConsoleCommand::InstallCommands() {
	new ConsoleCommand_PyExecute;
	new ConsoleCommand_PyLoad;
	new ConsoleCommand_PyReload;
	new ConsoleCommand_PyReloadAll;

	_asm {
		mov eax, 0x00428470 //cleanup and order the console commands
		call eax
	}
	Console_Output("Python Plugin console commands injected.\n");
};


const char *ConsoleCommand_PyExecute::GetName()
{
	return "pyexecute";
}

const char *ConsoleCommand_PyExecute::GetAlias()
{
	return "pyexec";
}

const char *ConsoleCommand_PyExecute::GetHelp()
{
	return "PYEXECUTE <text> - Executes a piece of Python source code";
}

void ConsoleCommand_PyExecute::Activate(const char *CommandLine)
{
	const char* code;

	if (!CommandLine) return;
	if (stricmp(CommandLine, "") == 0)
	{
		Console_Output("PYEXECUTE <text> - Executes a piece of Python code");
		return;
	}
	TokenClass Cmd(CommandLine);
	if (Cmd[0].empty()) { return; }
	if (Cmd[1].empty()) { return; }
	code = Cmd[0].c_str();
	PyRun_SimpleString(code);
}


const char *ConsoleCommand_PyLoad::GetName()
{
	return "pyload";
}

const char *ConsoleCommand_PyLoad::GetAlias()
{
	return "";
}

const char *ConsoleCommand_PyLoad::GetHelp()
{
	return "PYLOAD <file> - Loads a Python file from the PythonPlugins folder";
}

void ConsoleCommand_PyLoad::Activate(const char *CommandLine)
{

	if (!CommandLine) return;
	if (stricmp(CommandLine, "") == 0)
	{
		Console_Output("PYLOAD <file> - Loads a Python file from the PythonPlugins folder");
		return;
	}
	TokenClass Cmd(CommandLine);
	if (Cmd[0].empty()) { return; }
	if (Cmd[1].empty()) { return; }
	std::string file = "PythonPlugins.";
	file += Cmd[1].c_str();
	Load_Module(file.c_str());
}


const char *ConsoleCommand_PyReload::GetName()
{
	return "pyreload";
}

const char *ConsoleCommand_PyReload::GetAlias()
{
	return "";
}

const char *ConsoleCommand_PyReload::GetHelp()
{
	return "PYRELOAD <file> - Reloads a Python file from the PythonPlugins folder";
}

void ConsoleCommand_PyReload::Activate(const char *CommandLine)
{
	PyObject *pTemp, *pFunc;
	if (!CommandLine) return;
	if (stricmp(CommandLine, "") == 0)
	{
		Console_Output("PYRELOAD <file> - Reloads a Python file from the PythonPlugins folder");
		return;
	}
	TokenClass Cmd(CommandLine);
	if (Cmd[0].empty()) { return; }
	if (Cmd[1].empty()) { return; }
	std::string file = "PythonPlugins.";
	file += Cmd[1].c_str();
	pTemp = PyImport_ReloadModule(PyImport_AddModule(file.c_str()));
	if (NULL == pTemp ) 
	{
		printf("Error opening module '%s', make sure you don't include the '.py' extension in the name", Cmd[1].c_str());
	}
	else 
	{
		if (PyObject_HasAttrString(pTemp, "OnLoad")) 
		{
			pFunc = PyObject_GetAttrString(pTemp, "OnLoad");
			if (pFunc && PyCallable_Check(pFunc)) 
			{			
				PyObject_CallObject(pFunc, NULL);
			}
			else 
			{
				if (PyErr_Occurred())
				{
					PyErr_Print();
				}
			}
			Py_XDECREF(pFunc);
		}
	}
}

const char *ConsoleCommand_PyReloadAll::GetName()
{
	return "pyreloadall";
}

const char *ConsoleCommand_PyReloadAll::GetAlias()
{
	return "";
}

const char *ConsoleCommand_PyReloadAll::GetHelp()
{
	return "PYRELOADALL - Reloads all loaded Python modules";
}

void ConsoleCommand_PyReloadAll::Activate(const char *CommandLine)
{
	PyObject *pTemp, *pFunc;

	for( int i = 0; i < ModulesArrayIndex; ++i)
	{
		pTemp = ModulesArray[i];
		PyImport_ReloadModule(pTemp);

		if (PyObject_HasAttrString(pTemp, "OnLoad")) 
		{
			pFunc = PyObject_GetAttrString(pTemp, "OnLoad");
			if (pFunc && PyCallable_Check(pFunc)) 
			{			
				PyObject_CallObject(pFunc, NULL);
			}
			else 
			{
				if (PyErr_Occurred())
				{
					PyErr_Print();
				}
			}
			Py_XDECREF(pFunc);
		}
	}
}