#include "py_baselib.h"

extern int SCREEN_WIDTH;
extern int SCREEN_HEIGHT;

extern PyTypeObject pyship_type;

extern Engine *engine;

PyMethodDef fftMethods[] =
{
	{"Exit", (PyCFunction)fft_exit, METH_VARARGS, "Exit(message)\nExits the current game displaying \"message\", then returns to the main menu\n"},
	{"SetMainShip", (PyCFunction)fft_setmainship, METH_VARARGS, "SetMainShip(ship)\nSets the Main ship of the program to this ship, and gives it control\n"},
	{"Render", (PyCFunction)fft_render, METH_NOARGS, "Probably not going to exist\n"},
	{"MessageBox", (PyCFunction)fft_messagebox, METH_VARARGS, "MessageBox(message)\nDisplays \"message\" in a message box\n"},
	{"YesNoBox", (PyCFunction)fft_yesnobox, METH_VARARGS, "YesNoBox(message)\nDisplays \"message\" in a message box that has a yes or no option.  Returns a nonzero value if yes is pressed, zero if no is pressed.\n"},
	{"Victory", (PyCFunction)fft_victory, METH_NOARGS, "Victory()\nFunction which exists for the sole purpose of determining when victory conditions are met.  To make this work, you have to create your own victory function (returning a non zero number on loss, and a 0 otherwise) and set fft.Victory equal to it.  The function must have no arguments to work properly.  This function will have no effect when called from the script.\n"},
	{"Loss", (PyCFunction)fft_loss, METH_NOARGS, "Loss()\nFunction which exists for the sole purpose of determining when losing conditions are met.  To make this work, you have to create your own loss function (returning a non zero number on loss, and a 0 otherwise) and set fft.Loss equal to it.  The function must have no arguments to work properly.  This function will have no effect when called from the script.\n"},
	{0}
};

PyMethodDef catchMethods[] =
{
	{"write", (PyCFunction)fft_log, METH_VARARGS, "write function to override sysout and syserr"},
	{0}
};

PyObject* fft_log(PyObject* self, PyObject* args)
{
	char* LogStr = NULL;
	if (!PyArg_ParseTuple(args, "s", &LogStr)) return NULL;

	Log::Writen(LogStr);

	Py_INCREF(Py_None);
	return Py_None;
}
PyObject* fft_victory(PyObject* self)
{
	PyObject* retval=Py_BuildValue("i", 0);
	Py_INCREF(retval);
	return retval;
}
PyObject* fft_loss(PyObject* self)
{
	PyObject* retval=Py_BuildValue("i", 0);
	Py_INCREF(retval);
	return retval;
}
PyObject* fft_exit(PyObject* self, PyObject* args)
{
	char* ExitStr = NULL;
	if (!PyArg_ParseTuple(args, "s", &ExitStr)) return NULL;

	Log::Write("Exiting the game via fft.Exit() with message \"%s\"\n**********************\n",ExitStr);
	ExitToMenuBox(SCREEN_WIDTH, SCREEN_HEIGHT, ExitStr);
	engine->CleanUpGame();
	//This part is designed to stifle the exception from showing up in the log.
	//Must be reinstated to catchmodule when loading a new module
	PyObject* sysModule = PyImport_ImportModule("sys");
	PyObject_SetAttrString(sysModule, "stdout", Py_None);
	PyObject_SetAttrString(sysModule, "stderr", Py_None);
	PyErr_SetString(PyExc_RuntimeError, "stopping execution");

	Py_INCREF(Py_None);
	return Py_None;
}
PyObject* fft_messagebox(PyObject* self, PyObject* args)
{
	char* Message = NULL;
	if (!PyArg_ParseTuple(args, "s", &Message)) return NULL;

	SDL_Surface *screen=SDL_GetVideoSurface();
	SDL_Surface *bg = SDL_CreateRGBSurface(0, screen->w, screen->h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
	SDL_Rect dest;
	dest.x = 0;
	dest.y = 0;
	SDL_BlitSurface(screen, NULL, bg, &dest);
	MsgBox(SCREEN_WIDTH, SCREEN_HEIGHT, Message);
	SDL_BlitSurface(bg, NULL, screen, &dest);
	SDL_FreeSurface(bg);

	Py_INCREF(Py_None);
	return Py_None;
}
PyObject* fft_yesnobox(PyObject* self, PyObject* args)
{
	char* Message = NULL;
	if (!PyArg_ParseTuple(args, "s", &Message)) return NULL;

	SDL_Surface *screen=SDL_GetVideoSurface();
	SDL_Surface *bg = SDL_CreateRGBSurface(0, screen->w, screen->h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
	SDL_Rect dest;
	dest.x = 0;
	dest.y = 0;
	SDL_BlitSurface(screen, NULL, bg, &dest);
	int yesno=YesNoBox(SCREEN_WIDTH, SCREEN_HEIGHT, Message);
	PyObject *retval=Py_BuildValue("i", yesno);
	SDL_BlitSurface(bg, NULL, screen, &dest);
	SDL_FreeSurface(bg);

	Py_INCREF(retval);
	return retval;
}
PyObject* fft_render(PyObject* self)
{
	engine->Render();
	Py_INCREF(Py_None);
	return Py_None;
}
PyObject* fft_setmainship(PyObject* self, PyObject* args)
{
	ShipObject *ship;
	if (!PyArg_ParseTuple(args, "O:SetMainShip", &ship)) return NULL;

	if ((PyObject*)ship == Py_None)
	{
		engine->InControl(false);
	}
	else
	{
		if (ship->ob_type != &pyship_type)
		{
			PyErr_SetString(PyExc_TypeError, "SetMainShip not called with Ship object or None.");
			return 0;
		}
		engine->InControl(true);
		engine->SetMainShip(ship->unit);
	}

	Py_INCREF(Py_None);
	return Py_None;
}

