#include <Python.h>

staticforward PyTypeObject figures_TriangleType;

typedef struct {
    PyObject_HEAD
    float a,b,c;
    char *name;
} figures_TriangleObject;

static PyObject* 
figures_triangle_new(PyTypeObject *type, PyObject *args){
	figures_TriangleObject *self;
	
	self = (figures_TriangleObject*)type->tp_alloc(type,0);
	return (PyObject *) self;
}

static int 
figures_triangle_init(PyObject *self, PyObject *args) {
	char *name; 
	float a,b,c;
	figures_TriangleObject* triangle;
	
	if (!PyArg_ParseTuple(args, "sfff", &name, &a,&b,&c))
        {
		PyErr_SetString( PyExc_TypeError,
			"Parameters: name string, a,b and c lenght"
		);
		return -1;
	}
	if (self != NULL) { 
		triangle = (figures_TriangleObject*) self; 
	} else {
		triangle = PyObject_New(figures_TriangleObject, 
				&figures_TriangleType);
	}
	triangle->a = a ; printf("%f\n",a) ;
	triangle->b = b ; 
	triangle->c = c ;
	triangle->name = name; printf("%s\n",name);
	return 0 ;
}

static PyObject* 
figures_triangle_create(PyObject *self, PyObject *args){
	figures_TriangleObject *new; 

	figures_TriangleType.tp_new = PyType_GenericNew;
	PyType_Ready(&figures_TriangleType);
	new = PyObject_New(figures_TriangleObject, &figures_TriangleType);  
	if (figures_triangle_init( (PyObject *)new , args) == 0) 
		return (PyObject *)new;
	else 
		return Py_None;
}

static void
figures_triangle_dealloc(figures_TriangleObject* self)
{
	self->ob_type->tp_free((PyObject*)self);
}

static PyObject* 
figures_triangle_area(figures_TriangleObject *self, 
			PyObject *value, void *closure)
{
	float area;
	
	area  = self->a * self->b / 2;
	return (Py_BuildValue("f",area));
}

static PyObject* 
figures_triangle_get_a(figures_TriangleObject *self, void* p )
{
    return Py_BuildValue("f", self->a);
}

static int
figures_triangle_set_a(figures_TriangleObject *self, 
			PyObject *value, void *closure)
{
	float a;

	if (value == NULL) {
		PyErr_SetString(PyExc_TypeError, 
			"Cannot delete the first attribute");
		return -1;
	}
	if (PyArg_Parse(value,"f", &a )) self->a = a ;
	else {
	 	PyErr_SetString(PyExc_TypeError,
			"The first attribute value must be float");
		return -1;
	}
	Py_INCREF(value);
	return 0;
}

static PyGetSetDef figures_triangle_getset[] = {
	{ "a", 	(getter)figures_triangle_get_a, 
		(setter)figures_triangle_set_a, 
		"a lenght", NULL },
	{ NULL }
};

static PyMethodDef figures_triangle_methods[] = {
	{ "area", (PyCFunction)figures_triangle_area, 
		METH_NOARGS , "calculates area"},
	{NULL, NULL, 0, NULL}   
};

static PyMethodDef figures_methods[] = {
	{"Triangle", (PyCFunction)figures_triangle_create, 
		METH_VARARGS,"Create a new Triangle object."},
	{NULL, NULL, 0, NULL}
};

static PyTypeObject figures_TriangleType = {
    PyObject_HEAD_INIT(NULL)
    0,
    "figures.Triangle",
    sizeof(figures_TriangleObject),
    0,
    (destructor)figures_triangle_dealloc, /*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,0,0,
    0,0,
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
    "Triangle objects",
    0,0,0,0,0,0,
    figures_triangle_methods,
    0,
    figures_triangle_getset,        
    0,0,0,0,0,
    (initproc)figures_triangle_init,
    0,
    (newfunc)figures_triangle_new,
};

DL_EXPORT(void)

initfigures(void) 
{
    PyObject* m;
    figures_TriangleType.ob_type = &PyType_Type;
    m = Py_InitModule("figures", figures_methods);
}
