
/* LitTexTri object
 */

#include "Python.h"
#include "GL/gl.h"

typedef struct {
	PyObject_HEAD
    PyObject *vertexes_obj;
	double vertexes[3][3];
	double normals[3][3];
	double texcoords[3][2];
    int rendered;
} LitTexTriObject;

staticforward PyTypeObject LitTexTri_Type;

#define LitTexTriObject_Check(v)	((v)->ob_type == &LitTexTri_Type)

static LitTexTriObject *newLitTexTriObject(PyObject *args) {
	LitTexTriObject *self;
    PyObject *vertexes, *normals, *texcoords, *tuple;
    int n, length;

	if (!(self = PyObject_New(LitTexTriObject, &LitTexTri_Type))) return NULL;

	if (!PyArg_ParseTuple(args, "OOO:newLitTexTriObject", &vertexes,
        &normals, &texcoords)) return NULL;

    // vertexes
    self->vertexes_obj = vertexes;
    Py_INCREF(self->vertexes_obj);
    length = PySequence_Size(vertexes);
    for (n=0; n<length; n++) {
        tuple = PySequence_GetItem(vertexes, n);
        self->vertexes[n][0] = PyFloat_AsDouble(PyTuple_GET_ITEM(tuple, 0));
        self->vertexes[n][1] = PyFloat_AsDouble(PyTuple_GET_ITEM(tuple, 1));
        self->vertexes[n][2] = PyFloat_AsDouble(PyTuple_GET_ITEM(tuple, 2));
    }

    // normals
    length = PySequence_Size(normals);
    for (n=0; n<length; n++) {
        tuple = PySequence_GetItem(normals, n);
        self->normals[n][0] = PyFloat_AsDouble(PyTuple_GET_ITEM(tuple, 0));
        self->normals[n][1] = PyFloat_AsDouble(PyTuple_GET_ITEM(tuple, 1));
        self->normals[n][2] = PyFloat_AsDouble(PyTuple_GET_ITEM(tuple, 2));
    }

    // texcoords
    length = PySequence_Size(texcoords);
    for (n=0; n<length; n++) {
        tuple = PySequence_GetItem(texcoords, n);
        self->texcoords[n][0] = PyFloat_AsDouble(PyTuple_GET_ITEM(tuple, 0));
        self->texcoords[n][1] = PyFloat_AsDouble(PyTuple_GET_ITEM(tuple, 1));
    }

	return self;
}

/* LitTexTri methods */
static void LitTexTri_dealloc(LitTexTriObject *self) {
    Py_DECREF(self->vertexes_obj);
	PyObject_Del(self);
}

/*
This must be called in a GL_TRIANGLES context
*/
static PyObject *render(LitTexTriObject *self, PyObject *args) {
    int n;

    if (!self->rendered) {
        for (n=0; n<3; n++) {
            glTexCoord2dv(self->texcoords[n]);
            glNormal3dv(self->normals[n]);
            glVertex3dv(self->vertexes[n]);
        }
        self->rendered = 1;
    }
    Py_INCREF(Py_None);
    return Py_None;
}

static PyMethodDef LitTexTri_methods[] = {
	{"render", (PyCFunction)render, METH_VARARGS},
	{NULL,		NULL}		/* sentinel */
};


static PyObject *LitTexTri_getattr(LitTexTriObject *self, char *name) {
    if (!strcmp(name, "rendered")) {
        return PyInt_FromLong(self->rendered);
    }
    if (!strcmp(name, "vertexes")) {
        Py_INCREF(self->vertexes_obj);
        return self->vertexes_obj;
    }
	return Py_FindMethod(LitTexTri_methods, (PyObject *)self, name);
}

static int LitTexTri_setattr(LitTexTriObject *self, char *name, PyObject *v) {
    if (strcmp(name, "rendered")) {
        PyErr_Format(PyExc_AttributeError, "cannot set '%s' attribute", name);
        return -1;
    }
    if (v == NULL) {
        PyErr_SetString(PyExc_AttributeError,
            "cannot delete 'rendered' attribute");
        return -1;
    }
    self->rendered = PyInt_AsLong(v);
    if (PyErr_Occurred()) return -1;
    return 0;
}

statichere PyTypeObject LitTexTri_Type = {
	PyObject_HEAD_INIT(NULL)
	0,			/*ob_size*/
	"LitTexTri",			/*tp_name*/
	sizeof(LitTexTriObject),	/*tp_basicsize*/
	0,			/*tp_itemsize*/
	/* methods */
	(destructor)LitTexTri_dealloc, /*tp_dealloc*/
	0,			/*tp_print*/
	(getattrfunc)LitTexTri_getattr, /*tp_getattr*/
	(setattrfunc)LitTexTri_setattr, /*tp_setattr*/
	0,			/*tp_compare*/
	0,			/*tp_repr*/
	0,			/*tp_as_number*/
	0,			/*tp_as_sequence*/
	0,			/*tp_as_mapping*/
	0,			/*tp_hash*/
};

/* module */


static PyObject *littextri_new(PyObject *self, PyObject *args) {
	return (PyObject *)newLitTexTriObject(args);
}

static PyMethodDef triangle_methods[] = {
	{"LitTexTri",		littextri_new,		METH_VARARGS},
	{NULL,		NULL}		/* sentinel */
};

DL_EXPORT(void) init_triangle(void) {
	LitTexTri_Type.ob_type = &PyType_Type;
	Py_InitModule("_triangle", triangle_methods);
}
