/*
    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 "sprite.h"
#include "texture.h"

static void pysSpriteDealloc(PysSprite* self)
{
    sgSpriteDestroy(self->sprite);
    self->ob_type->tp_free(self);
}
static PyObject* pysSpriteNew(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
    PysSprite* self = (PysSprite*)type->tp_alloc(type, 0);
    if(self != NULL)
        self->sprite = NULL;
    return (PyObject*)self;
}
static int pysSpriteInit(PysSprite* self, PyObject* args, PyObject* kwargs)
{
    PyObject* arg;
    float xoffset, yoffset;

    size_t size = PyTuple_Size(args);
    if(size == 3)
    {
        if(!PyArg_ParseTuple(args, "Off", &arg, &xoffset, &yoffset));
            return -1;

        if(pysTextureCheck(arg))
        {
            PysTexture* texture = (PysTexture*)arg;
            self->sprite = sgSpriteCreateTexture2f(texture->texture, xoffset, yoffset);
        }
        else
        {
            char* fname = PyString_AsString(arg);
            if(fname == NULL)
                return -1;
            self->sprite = sgSpriteCreateFile2f(fname, xoffset, yoffset);
        }
    }
    else if(size == 1)
    {
        if(!PyArg_ParseTuple(args, "O", &arg))
            return -1;

        if(pysTextureCheck(arg))
        {
            PysTexture* texture = (PysTexture*)arg;
            self->sprite = sgSpriteCreateTexture(texture->texture);
        }
        else
        {
            char* fname = PyString_AsString(arg);
            if(fname == NULL)
                return -1;
            self->sprite = sgSpriteCreateFile(fname);
        }
    }
    else
        return -1;

    return 0;
}

/*
    x,y,z,xscale,yscale,angle
    x,y,xscale,yscale,angle
    x,y,z,angle
    x,y,angle
*/
static PyObject* pysSpriteDrawRads(PysSprite* self, PyObject* args)
{
    float x, y, z;
    float xscale, yscale;
    float rads;

    size_t size = PyTuple_Size(args);
    if(size == 6)
    {
        if(!PyArg_ParseTuple(args, "ffffff", &x, &y, &z, &xscale, &yscale, &rads))
            return NULL;
        sgSpriteDrawRads3f2f1f(self->sprite, x, y, z, xscale, yscale, rads);
    }
    else if(size == 5)
    {
        if(!PyArg_ParseTuple(args, "fffff", &x, &y, &xscale, &yscale, &rads))
            return NULL;
        sgSpriteDrawRads2f2f1f(self->sprite, x, y, xscale, yscale, rads);
    }
    else if(size == 4)
    {
        if(!PyArg_ParseTuple(args, "ffff", &x, &y, &z, &rads))
            return NULL;
        sgSpriteDrawRads3f1f(self->sprite, x, y, z, rads);
    }
    else if(size == 3)
    {
        if(!PyArg_ParseTuple(args, "fff", &x, &y, &rads))
            return NULL;
        sgSpriteDrawRads2f1f(self->sprite, x, y, rads);
    }
    else
        return NULL;
    Py_RETURN_NONE;
}

/*
    x,y,z,xscale,yscale,angle
    x,y,xscale,yscale,angle
    x,y,z,angle
    x,y,angle
*/
static PyObject* pysSpriteDrawDegs(PysSprite* self, PyObject* args)
{
    float x, y, z;
    float xscale, yscale;
    float degs;

    size_t size = PyTuple_Size(args);
    if(size == 6)
    {
        if(!PyArg_ParseTuple(args, "ffffff", &x, &y, &z, &xscale, &yscale, &degs))
            return NULL;
        sgSpriteDrawDegs3f2f1f(self->sprite, x, y, z, xscale, yscale, degs);
    }
    else if(size == 5)
    {
        if(!PyArg_ParseTuple(args, "fffff", &x, &y, &xscale, &yscale, &degs))
            return NULL;
        sgSpriteDrawDegs2f2f1f(self->sprite, x, y, xscale, yscale, degs);
    }
    else if(size == 4)
    {
        if(!PyArg_ParseTuple(args, "ffff", &x, &y, &z, &degs))
            return NULL;
        sgSpriteDrawDegs3f1f(self->sprite, x, y, z, degs);
    }
    else if(size == 3)
    {
        if(!PyArg_ParseTuple(args, "fff", &x, &y, &degs))
            return NULL;
        sgSpriteDrawDegs2f1f(self->sprite, x, y, degs);
    }
    else
        return NULL;
    Py_RETURN_NONE;
}

/*
    x,y,z,xscale,yscale
    x,y,xscale,yscale
    x,y,z
    x,y
*/
static PyObject* pysSpriteDraw(PysSprite* self, PyObject* args)
{
    float x, y, z;
    float xscale, yscale;

    size_t size = PyTuple_Size(args);
    if(size == 5)
    {
        if(!PyArg_ParseTuple(args, "fffff", &x, &y, &z, &xscale, &yscale))
            return NULL;
        sgSpriteDraw3f2f(self->sprite, x, y, z, xscale, yscale);
    }
    else if(size == 4)
    {
        if(!PyArg_ParseTuple(args, "ffff", &x, &y, &xscale, &yscale))
            return NULL;
        sgSpriteDraw2f2f(self->sprite, x, y, xscale, yscale);
    }
    else if(size == 3)
    {
        if(!PyArg_ParseTuple(args, "fff", &x, &y, &z))
            return NULL;
        sgSpriteDraw3f(self->sprite, x, y, z);
    }
    else if(size == 2)
    {
        if(!PyArg_ParseTuple(args, "ff", &x, &y))
            return NULL;
        sgSpriteDraw2f(self->sprite, x, y);
    }
    else
        return NULL;
    Py_RETURN_NONE;
}

static PyObject* pysSpriteGetSize(PysSprite* self)
{
    SGuint width, height;
    sgSpriteGetSize(self->sprite, &width, &height);

    return Py_BuildValue("(II)", width, height);
}
static PyObject* pysSpriteGetWidth(PysSprite* self)
{
    return Py_BuildValue("I", sgSpriteGetWidth(self->sprite));
}
static PyObject* pysSpriteGetHeight(PysSprite* self)
{
    return Py_BuildValue("I", sgSpriteGetHeight(self->sprite));
}

static PyMethodDef PysSpriteMethods[] = {
    {"drawRads", (PyCFunction)pysSpriteDrawRads, METH_VARARGS, ""},
    {"drawDegs", (PyCFunction)pysSpriteDrawDegs, METH_VARARGS, ""},
    {"draw", (PyCFunction)pysSpriteDraw, METH_VARARGS, ""},

    {"getSize", (PyCFunction)pysSpriteGetSize, METH_NOARGS, ""},
    {"getWidth", (PyCFunction)pysSpriteGetWidth, METH_NOARGS, ""},
    {"getHeight", (PyCFunction)pysSpriteGetHeight, METH_NOARGS, ""},
    {NULL, NULL, 0, NULL}
};

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

static PyTypeObject PysSpriteType = {
    PyObject_HEAD_INIT(NULL)
    0,                         /*ob_size*/
    "siege.graphics.Sprite",   /*tp_name*/
    sizeof(PysSprite),         /*tp_basicsize*/
    0,                         /*tp_itemsize*/
    (destructor)pysSpriteDealloc, /*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 */
    PysSpriteMethods,          /* tp_methods */
    PysSpriteMembers,          /* tp_members */
    0,                         /* tp_getset */
    0,                         /* tp_base */
    0,                         /* tp_dict */
    0,                         /* tp_descr_get */
    0,                         /* tp_descr_set */
    0,                         /* tp_dictoffset */
    (initproc)pysSpriteInit,   /* tp_init */
    0,                         /* tp_alloc */
    pysSpriteNew,                 /* tp_new */
};

int pysSpriteCheck(PyObject* o)
{
    return PyObject_TypeCheck(o, &PysSpriteType);
}
void sgpyInitGraphicsSprite(PyObject* parent)
{
    PysSpriteType.tp_new = PyType_GenericNew;
    if(PyType_Ready(&PysSpriteType) < 0)
        return;

    Py_INCREF(&PysSpriteType);
    PyModule_AddObject(parent, "Sprite", (PyObject*)&PysSpriteType);
}
