/*
    Copyright (c) 2007 SIEGE Development Team
    All rights reserved.
    
    This file is part of libSIEGE.
    
    This software is copyrighted work licensed under the terms of the
    2-clause BSD license. Please consult the file "license.txt" for
    details.
    
    If you did not recieve the file with this program, please email
    Tim Chas <darkuranium@gmail.com>.
*/

#include "turtle.h"

static void pysTurtleDealloc(PysTurtle* self)
{
    sgTurtleDestroy(self->turtle);
    self->ob_type->tp_free(self);
}
static PyObject* pysTurtleNew(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
    PysTurtle* self = (PysTurtle*)type->tp_alloc(type, 0);
    if(self != NULL)
        self->turtle = NULL;
    return (PyObject*)self;
}
static int pysTurtleInit(PysTurtle* self, PyObject* args, PyObject* kwargs)
{
    float x;
    float y;
    float degs;
    SGbool draw;
    if(!PyArg_ParseTuple(args, "fffb", &x, &y, &degs, &draw));
        return -1;

    self->turtle = sgTurtleCreateDegs(x, y, degs, draw);
    return 0;
}

static PyObject* pysTurtleReset(PysTurtle* self)
{
    sgTurtleReset(self->turtle);
    Py_RETURN_NONE;
}
static PyObject* pysTurtlePush(PysTurtle* self)
{
    sgTurtlePush(self->turtle);
    Py_RETURN_NONE;
}
static PyObject* pysTurtlePop(PysTurtle* self)
{
    sgTurtlePop(self->turtle);
    Py_RETURN_NONE;
}
static PyObject* pysTurtleStep(PysTurtle* self, PyObject* args)
{
    float dist;
    if(!PyArg_ParseTuple(args, "f", &dist))
        return NULL;

    sgTurtleStep(self->turtle, dist);
    Py_RETURN_NONE;
}
static PyObject* pysTurtleMove(PysTurtle* self, PyObject* args)
{
    float x;
    float y;
    if(!PyArg_ParseTuple(args, "ff", &x, &y))
        return NULL;

    sgTurtleMove(self->turtle, x, y);
    Py_RETURN_NONE;
}
static PyObject* pysTurtleJump(PysTurtle* self, PyObject* args)
{
    float x;
    float y;
    if(!PyArg_ParseTuple(args, "ff", &x, &y))
        return NULL;

    sgTurtleJump(self->turtle, x, y);
    Py_RETURN_NONE;
}
static PyObject* pysTurtlePenUp(PysTurtle* self)
{
    sgTurtlePenUp(self->turtle);
    Py_RETURN_NONE;
}
static PyObject* pysTurtlePenDown(PysTurtle* self)
{
    sgTurtlePenDown(self->turtle);
    Py_RETURN_NONE;
}

static PyObject* pysTurtleSetPen(PysTurtle* self, PyObject* args)
{
    SGbool pen;
    if(!PyArg_ParseTuple(args, "b", &pen))
        return NULL;

    sgTurtleSetPen(self->turtle, pen);
    Py_RETURN_NONE;
}
static PyObject* pysTurtleGetPen(PysTurtle* self)
{
    if(sgTurtleGetPen(self->turtle))
        Py_RETURN_TRUE;
    Py_RETURN_FALSE;
}

static PyObject* pysTurtleSetPos(PysTurtle* self, PyObject* args)
{
    float x;
    float y;
    if(!PyArg_ParseTuple(args, "ff", &x, &y))
        return NULL;

    sgTurtleSetPos(self->turtle, x, y);
    Py_RETURN_NONE;
}
static PyObject* pysTurtleGetPos(PysTurtle* self)
{
    float x, y;
    sgTurtleGetPos(self->turtle, &x, &y);
    return Py_BuildValue("(ff)", x, y);
}
static PyObject* pysTurtleSetPosX(PysTurtle* self, PyObject* args)
{
    float x;
    if(!PyArg_ParseTuple(args, "f", &x))
        return NULL;

    sgTurtleSetPosX(self->turtle, x);
    Py_RETURN_NONE;
}
static PyObject* pysTurtleGetPosX(PysTurtle* self)
{
    return Py_BuildValue("f", sgTurtleGetPosX(self->turtle));
}
static PyObject* pysTurtleSetPosY(PysTurtle* self, PyObject* args)
{
    float y;
    if(!PyArg_ParseTuple(args, "f", &y))
        return NULL;

    sgTurtleSetPosY(self->turtle, y);
    Py_RETURN_NONE;
}
static PyObject* pysTurtleGetPosY(PysTurtle* self)
{
    return Py_BuildValue("f", sgTurtleGetPosY(self->turtle));
}

static PyObject* pysTurtleTurnLeftRads(PysTurtle* self, PyObject* args)
{
    float rads;
    if(!PyArg_ParseTuple(args, "f", &rads))
        return NULL;

    sgTurtleTurnLeftRads(self->turtle, rads);
    Py_RETURN_NONE;
}
static PyObject* pysTurtleTurnLeftDegs(PysTurtle* self, PyObject* args)
{
    float degs;
    if(!PyArg_ParseTuple(args, "f", &degs))
        return NULL;

    sgTurtleTurnLeftDegs(self->turtle, degs);
    Py_RETURN_NONE;
}
static PyObject* pysTurtleTurnRightRads(PysTurtle* self, PyObject* args)
{
    float rads;
    if(!PyArg_ParseTuple(args, "f", &rads))
        return NULL;

    sgTurtleTurnRightRads(self->turtle, rads);
    Py_RETURN_NONE;
}
static PyObject* pysTurtleTurnRightDegs(PysTurtle* self, PyObject* args)
{
    float degs;
    if(!PyArg_ParseTuple(args, "f", &degs))
        return NULL;

    sgTurtleTurnRightDegs(self->turtle, degs);
    Py_RETURN_NONE;
}

static PyObject* pysTurtleSetAngleRads(PysTurtle* self, PyObject* args)
{
    float rads;
    if(!PyArg_ParseTuple(args, "f", &rads))
        return NULL;

    sgTurtleSetAngleRads(self->turtle, rads);
    Py_RETURN_NONE;
}
static PyObject* pysTurtleGetAngleRads(PysTurtle* self)
{
    return Py_BuildValue("f", sgTurtleGetAngleRads(self->turtle));
}

static PyObject* pysTurtleSetAngleDegs(PysTurtle* self, PyObject* args)
{
    float degs;
    if(!PyArg_ParseTuple(args, "f", &degs))
        return NULL;

    sgTurtleSetAngleDegs(self->turtle, degs);
    Py_RETURN_NONE;
}
static PyObject* pysTurtleGetAngleDegs(PysTurtle* self)
{
    return Py_BuildValue("f", sgTurtleGetAngleDegs(self->turtle));
}

static PyMethodDef PysTurtleMethods[] = {
    {"reset", (PyCFunction)pysTurtleReset, METH_NOARGS, ""},
    {"push", (PyCFunction)pysTurtlePush, METH_NOARGS, ""},
    {"pop", (PyCFunction)pysTurtlePop, METH_NOARGS, ""},
    {"step", (PyCFunction)pysTurtleStep, METH_VARARGS, ""},
    {"move", (PyCFunction)pysTurtleMove, METH_VARARGS, ""},
    {"jump", (PyCFunction)pysTurtleJump, METH_VARARGS, ""},
    {"penUp", (PyCFunction)pysTurtlePenUp, METH_NOARGS, ""},
    {"penDown", (PyCFunction)pysTurtlePenDown, METH_NOARGS, ""},

    {"setPen", (PyCFunction)pysTurtleSetPen, METH_VARARGS, ""},
    {"getPen", (PyCFunction)pysTurtleGetPen, METH_NOARGS, ""},

    {"setPos", (PyCFunction)pysTurtleSetPos, METH_VARARGS, ""},
    {"getPos", (PyCFunction)pysTurtleGetPos, METH_NOARGS, ""},
    {"setPosX", (PyCFunction)pysTurtleSetPosX, METH_VARARGS, ""},
    {"getPosX", (PyCFunction)pysTurtleGetPosX, METH_NOARGS, ""},
    {"setPosY", (PyCFunction)pysTurtleSetPosY, METH_VARARGS, ""},
    {"getPosY", (PyCFunction)pysTurtleGetPosY, METH_NOARGS, ""},

    {"turnLeftRads", (PyCFunction)pysTurtleTurnLeftRads, METH_VARARGS, ""},
    {"turnLeftDegs", (PyCFunction)pysTurtleTurnLeftDegs, METH_VARARGS, ""},
    {"turnRightRads", (PyCFunction)pysTurtleTurnRightRads, METH_VARARGS, ""},
    {"turnRightDegs", (PyCFunction)pysTurtleTurnRightDegs, METH_VARARGS, ""},

    {"setAngleRads", (PyCFunction)pysTurtleSetAngleRads, METH_VARARGS, ""},
    {"getAngleRads", (PyCFunction)pysTurtleGetAngleRads, METH_NOARGS, ""},

    {"setAngleDegs", (PyCFunction)pysTurtleSetAngleDegs, METH_VARARGS, ""},
    {"getAngleDegs", (PyCFunction)pysTurtleGetAngleDegs, METH_NOARGS, ""},
    {NULL, NULL, 0, NULL}
};

static PyMemberDef PysTurtleMembers[] = {
    {NULL, 0, 0, 0, NULL}
};

static PyTypeObject PysTurtleType = {
    PyObject_HEAD_INIT(NULL)
    0,                         /*ob_size*/
    "siege.graphics.Turtle",   /*tp_name*/
    sizeof(PysTurtle),         /*tp_basicsize*/
    0,                         /*tp_itemsize*/
    (destructor)pysTurtleDealloc, /*tp_dealloc*/
    0,                         /*tp_print*/
    0,                         /*tp_getattr*/
    0,                         /*tp_setattr*/
    0,                         /*tp_compare*/
    0,                         /*tp_repr*/
    0,                         /*tp_as_number*/
    0,                         /*tp_as_sequence*/
    0,                         /*tp_as_mapping*/
    0,                         /*tp_hash */
    0,                         /*tp_call*/
    0,                         /*tp_str*/
    0,                         /*tp_getattro*/
    0,                         /*tp_setattro*/
    0,                         /*tp_as_buffer*/
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
    "",                        /* tp_doc */
    0,		                   /* tp_traverse */
    0,		                   /* tp_clear */
    0,		                   /* tp_richcompare */
    0,		                   /* tp_weaklistoffset */
    0,		                   /* tp_iter */
    0,		                   /* tp_iternext */
    PysTurtleMethods,          /* tp_methods */
    PysTurtleMembers,          /* tp_members */
    0,                         /* tp_getset */
    0,                         /* tp_base */
    0,                         /* tp_dict */
    0,                         /* tp_descr_get */
    0,                         /* tp_descr_set */
    0,                         /* tp_dictoffset */
    (initproc)pysTurtleInit,   /* tp_init */
    0,                         /* tp_alloc */
    pysTurtleNew,                 /* tp_new */
};

int pysTurtleCheck(PyObject* o)
{
    return PyObject_TypeCheck(o, &PysTurtleType);
}
void sgpyInitGraphicsTurtle(PyObject* parent)
{
    PysTurtleType.tp_new = PyType_GenericNew;
    if(PyType_Ready(&PysTurtleType) < 0)
        return;

    Py_INCREF(&PysTurtleType);
    PyModule_AddObject(parent, "Turtle", (PyObject*)&PysTurtleType);
}
