//*****************************************************************************************
// Truevision - a 3d modeler for gnome and povray
//
// pyscriptobj.cc
//
// Christian Spoer <spoer@users.sourceforge.net>
// Copyright (C) 2000-2005 Vincent LE PRINCE
// This file is part of the TRUEVISION Package

//   This program is free software; you can redistribute it and/or modify
//   it under the terms of the GNU General Public License as published by
//   the Free Software Foundation; either version 2 of the License, or
//   (at your option) any later version.
//
//   This program is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU General Public License for more details.
//
//   You should have received a copy of the GNU General Public License
//   along with this program; if not, write to the Free Software
//   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
//*******************************************************************************************

#include "include/pyutils.h"
#include "include/pyscriptobj.h"
#include "include/main.h"

#include <string>

////////////////////////////////////////////////////////////////////
// PyScriptObj::
PyObject*
PyScriptObj::new_scriptobject(PyObject* self, PyObject* args)
{
	PyObject *obj;
    ScriptObj *result;	
	static int box_cnt = 0;
	char new_name[16];
	sprintf(new_name, "ScriptObj#%d",box_cnt++);	
    result = (ScriptObj*)new ScriptObj(tv_get_obj_ref());
	result->set_name(new_name);
	obj = PyCObject_FromVoidPtr( result, NULL );
    return obj;
}

PyObject*
PyScriptObj::get_location(PyObject* self, PyObject* args)
{
	Vector3D vec;
	ScriptObj* c = NULL;
	PyObject *object;
	PyObject *result = PYVAL_NONE;

	PyArg_ParseTuple(args, "O", &object);
	Py_INCREF(object);
	if (PyCObject_Check(object)) {
		c = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		vec = c->get_location();
		result = ConvertTuple3( vec );
	}
	return result;
}

PyObject*
PyScriptObj::set_location(PyObject* self, PyObject* args)
{
	ScriptObj* c = NULL;
	PyObject *object;
	PyObject *pyvec;

	float vec[3];
	PyArg_ParseTuple(args, "OO", &object, &pyvec);
	Py_INCREF(object);
	Py_INCREF(pyvec);
	if (PyCObject_Check(object)){
		c = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		ConvertVector3DV( pyvec, &vec[0], &vec[1], &vec[2] );
		c->set_location( vec );
	}
	Py_INCREF(PYVAL_NONE);
	return PYVAL_NONE;
}

PyObject*
PyScriptObj::add_triangle(PyObject* self, PyObject* args)
{
	ScriptObj* c = NULL;
	PyObject *object;
	float x1, x2, x3, y1, y2, y3, z1, z2, z3;
	PyArg_ParseTuple(args, "Offfffffff", &object, &x1, &y1, &z1, &x2, &y2, &z2, &x3, &y3, &z3);
	Py_INCREF(object);
	if (PyCObject_Check(object)){
		c = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		c->add_triangle( x1, y1, z1,
						 x2, y2, z2,
						 x3, y3, z3 );
	}
	Py_INCREF(PYVAL_NONE);
	return PYVAL_NONE;
}

PyObject*
PyScriptObj::add_quad(PyObject* self, PyObject* args)
{
	ScriptObj* c = NULL;
	PyObject *object;
	float x1, x2, x3, x4, y1, y2, y3, y4, z1, z2, z3, z4;
	PyArg_ParseTuple(args, "Offffffffffff", &object, &x1, &y1, &z1, &x2, &y2, &z2, &x3, &y3, &z3, &x4, &y4, &z4);
	Py_INCREF(object);
	if (PyCObject_Check(object)){
		c = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		c->add_quad( x1, y1, z1,
						 x2, y2, z2,
						 x3, y3, z3,
						 x4, y4, z4 );
	}
	Py_INCREF(PYVAL_NONE);
	return PYVAL_NONE;
}

PyObject*
PyScriptObj::new_int(PyObject* self, PyObject* args)
{
	ScriptObj* c = NULL;
	PyObject *object;
	int _i;
	char* _name;
	PyArg_ParseTuple(args, "Osi", &object, &_name, &_i);
	Py_INCREF(object);
	if (PyCObject_Check(object)){
		c = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		c->new_int( _name, _i );
	}
	Py_INCREF(PYVAL_NONE);
	return PYVAL_NONE;
}

PyObject*
PyScriptObj::new_float(PyObject* self, PyObject* args)
{
	ScriptObj* c = NULL;
	PyObject *object;
	float _f;
	char* _name;
	PyArg_ParseTuple(args, "Osf", &object, &_name, &_f);
	Py_INCREF(object);
	if (PyCObject_Check(object)){
		c = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		c->new_float( _name, _f );
	}
	Py_INCREF(PYVAL_NONE);
	return PYVAL_NONE;
}

PyObject*
PyScriptObj::new_double(PyObject* self, PyObject* args)
{
	ScriptObj* c = NULL;
	PyObject *object;
	double _d;
	char* _name;
	PyArg_ParseTuple(args, "Osd", &object, &_name, &_d);
	Py_INCREF(object);
	if (PyCObject_Check(object)){
		c = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		c->new_double( _name, _d );
	}
	Py_INCREF(PYVAL_NONE);
	return PYVAL_NONE;
}

PyObject*
PyScriptObj::new_string(PyObject* self, PyObject* args)
{
	ScriptObj* c = NULL;
	PyObject *object;
	char *_name, *_str;
	PyArg_ParseTuple(args, "Oss", &object, &_name, &_str);
	Py_INCREF(object);
	if (PyCObject_Check(object)){
		c = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		c->new_string( _name, _str );
	}
	Py_INCREF(PYVAL_NONE);
	return PYVAL_NONE;
}

PyObject*
PyScriptObj::get_int(PyObject* self, PyObject* args)
{
	ScriptObj* obj3d;
	PyObject *retobj, *object;
	gpointer _i;
	char *_name;
	ScriptValue *val = NULL;
	
	retobj = PYVAL_NONE;

	PyArg_ParseTuple(args, "Os", &object, &_name);
	Py_INCREF(object);
	if (PyCObject_Check(object)) {
		obj3d = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		val = obj3d->get_value( _name );
		if ( val == NULL ) {
				Py_INCREF(PYVAL_NONE);
				return PYVAL_NONE;
		} else {
			_i = val->value;
			retobj = Py_BuildValue("i", *((int*)_i));
		}
	}
	else {
		printf("ScriptObj::get_int: PyCObject_Check failed!\n");fflush(stdout);
	}

	return retobj;	
}

PyObject*
PyScriptObj::get_float(PyObject* self, PyObject* args)
{
	ScriptObj* obj3d;
	PyObject *retobj, *object;
	gpointer _f;
	char *_name;
	ScriptValue *val;
	
	retobj = PYVAL_NONE;

	PyArg_ParseTuple(args, "Os", &object, &_name);
	Py_INCREF(object);
	if (PyCObject_Check(object)) {
		obj3d = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		val = obj3d->get_value( _name );
		if ( val == NULL ) {
				Py_INCREF(PYVAL_NONE);
				return PYVAL_NONE;
		} else {
			_f = val->value;
			retobj = Py_BuildValue("f", *((float*)_f));
		}
	}
	else {
		printf("ScriptObj::get_float: PyCObject_Check failed!\n");fflush(stdout);
	}
	return retobj;	
}

PyObject*
PyScriptObj::get_double(PyObject* self, PyObject* args)
{
	ScriptObj* obj3d;
	PyObject *retobj, *object;
	gpointer _d;
	char *_name;
	ScriptValue *val;
	
	retobj = PYVAL_NONE;

	PyArg_ParseTuple(args, "Os", &object, &_name);
	Py_INCREF(object);
	if (PyCObject_Check(object)) {
		obj3d = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		val = obj3d->get_value( _name );
		if ( val == NULL ) {
				Py_INCREF(PYVAL_NONE);
				return PYVAL_NONE;
		} else {
			_d = val->value;
			retobj = Py_BuildValue("d", *((double*)_d));
		}
	}
	else {
		printf("ScriptObj::get_double: PyCObject_Check failed!\n");fflush(stdout);
	}
	return retobj;	
}

PyObject*
PyScriptObj::get_string(PyObject* self, PyObject* args)
{
	ScriptObj* obj3d;
	PyObject *retobj, *object;
	gpointer _s;
	char *_name;
	ScriptValue *val;
	
	retobj = PYVAL_NONE;

	PyArg_ParseTuple(args, "Os", &object, &_name);
	Py_INCREF(object);
	if (PyCObject_Check(object)) {
		obj3d = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		val = obj3d->get_value( _name );
		if ( val == NULL ) {
				Py_INCREF(PYVAL_NONE);
				return PYVAL_NONE;
		} else {
			_s = val->value;
			retobj = StringToPyVal( (char*)_s );
		}
	}
	else {
		printf("ScriptObj::get_string: PyCObject_Check failed!\n");fflush(stdout);		
	}
	return retobj;	
}

PyObject*
PyScriptObj::set_int(PyObject* self, PyObject* args)
{
	ScriptObj* c = NULL;
	PyObject *object;
	int _i;
	char* _name;
	PyArg_ParseTuple(args, "Osi", &object, &_name, &_i);
	Py_INCREF(object);
	if (PyCObject_Check(object)){
		c = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		c->set_int( _name, _i );
	}
	Py_INCREF(PYVAL_NONE);
	return PYVAL_NONE;
}

PyObject*
PyScriptObj::set_float(PyObject* self, PyObject* args)
{
	ScriptObj* c = NULL;
	PyObject *object;
	float _f;
	char* _name;
	PyArg_ParseTuple(args, "Osf", &object, &_name, &_f);
	Py_INCREF(object);
	if (PyCObject_Check(object)){
		c = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		c->set_float( _name, _f );
	}
	Py_INCREF(PYVAL_NONE);
	return PYVAL_NONE;
}

PyObject*
PyScriptObj::set_double(PyObject* self, PyObject* args)
{
	ScriptObj* c = NULL;
	PyObject *object;
	double _d;
	char* _name;
	PyArg_ParseTuple(args, "Osd", &object, &_name, &_d);
	Py_INCREF(object);
	if (PyCObject_Check(object)){
		c = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		c->set_double( _name, _d );
	}
	Py_INCREF(PYVAL_NONE);
	return PYVAL_NONE;
}

PyObject*
PyScriptObj::set_string(PyObject* self, PyObject* args)
{
	ScriptObj* c = NULL;
	PyObject *object;
	char *_name, *_str;
	PyArg_ParseTuple(args, "Oss", &object, &_name, &_str);
	Py_INCREF(object);
	if (PyCObject_Check(object)){
		c = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		c->set_string( _name, _str );
	}
	Py_INCREF(PYVAL_NONE);
	return PYVAL_NONE;
}

PyObject*
PyScriptObj::set_script_path(PyObject* self, PyObject* args)
{
	ScriptObj* c = NULL;
	PyObject *object;
	char *_str;
	PyArg_ParseTuple(args, "Os", &object, &_str);
	Py_INCREF(object);
	if (PyCObject_Check(object)){
		c = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		c->set_script_path( strdup(_str) );
	}
	Py_INCREF(PYVAL_NONE);
	return PYVAL_NONE;
}

PyObject*
PyScriptObj::get_script_path(PyObject* self, PyObject* args)
{
	ScriptObj* obj3d;
	PyObject *retobj, *object;

	retobj = PYVAL_NONE;

	PyArg_ParseTuple(args, "O", &object);
	Py_INCREF(object);
	if (PyCObject_Check(object)) {
		obj3d = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		retobj = StringToPyVal( (char*)(obj3d->get_script_path()) );
	}
	else {
		printf("ScriptObj::get_script_path: PyCObject_Check failed!\n");fflush(stdout);		
	}
	return retobj;	
}

PyObject*
PyScriptObj::get_rotation(PyObject* self, PyObject* args)
{
	float vec[3];
	ScriptObj* b = NULL;
	PyObject *object;
	PyObject *result = PYVAL_NONE;

	PyArg_ParseTuple(args, "O", &object);
	Py_INCREF(object);
	if (PyCObject_Check(object)){
		b = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		b->get_rot( vec );
		result = ConvertTuple3( (float*)vec );
	}
	return result;
}
	
PyObject*
PyScriptObj::set_rotation(PyObject* self, PyObject* args)
{
	ScriptObj* b = NULL;
	PyObject *object;
	PyObject *pyvec;

	float vec[3];
	PyArg_ParseTuple(args, "OO", &object, &pyvec);
	Py_INCREF(object);
	Py_INCREF(pyvec);
	if (PyCObject_Check(object)){
		b = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		ConvertVector3DV( pyvec, &vec[0], &vec[1], &vec[2] );
		b->set_rotation( vec );
	}
	return PYVAL_NONE;
}

PyObject* 
PyScriptObj::get_size(PyObject* self, PyObject* args)
{
	Vector3D vec;
	ScriptObj* b = NULL;
	PyObject *object;
	PyObject *result = PYVAL_NONE;

	PyArg_ParseTuple(args, "O", &object);
	Py_INCREF(object);
	if (PyCObject_Check(object)){
		b = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		vec = b->get_size();
		result = ConvertTuple3( vec );
	}
	return result;
}

PyObject* 
PyScriptObj::set_size(PyObject* self, PyObject* args)
{
	ScriptObj* b = NULL;
	PyObject *object;
	PyObject *pyvec;

	float vec[3];
	PyArg_ParseTuple(args, "OO", &object, &pyvec);
	Py_INCREF(object);
	Py_INCREF(pyvec);
	if (PyCObject_Check(object)){
		b = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		ConvertVector3DV( pyvec, &vec[0], &vec[1], &vec[2] );
		b->set_size( vec );
	}
	return PYVAL_NONE;
}

PyObject*
PyScriptObj::set_pov_pass1(PyObject* self, PyObject* args)
{
	ScriptObj* c = NULL;
	PyObject *object;
	char *_str;
	PyArg_ParseTuple(args, "Os", &object, &_str);
	Py_INCREF(object);
	if (PyCObject_Check(object)){
		c = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		c->set_pov_pass1_string( strdup(_str) );
	}
	Py_INCREF(PYVAL_NONE);
	return PYVAL_NONE;
}

PyObject*
PyScriptObj::set_pov_pass2(PyObject* self, PyObject* args)
{
	ScriptObj* c = NULL;
	PyObject *object;
	char *_str;
	PyArg_ParseTuple(args, "Os", &object, &_str);
	Py_INCREF(object);
	if (PyCObject_Check(object)){
		c = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		c->set_pov_pass2_string( strdup(_str) );
	}
	Py_INCREF(PYVAL_NONE);
	return PYVAL_NONE;
}

PyObject*
PyScriptObj::set_has_rotation(PyObject* self, PyObject* args)
{
	ScriptObj* c = NULL;
	PyObject *object;
	bool b;
	PyArg_ParseTuple(args, "Oi", &object, &b);
	Py_INCREF(object);
	if (PyCObject_Check(object)){
		c = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		c->set_has_rotation( b );
	}
	Py_INCREF(PYVAL_NONE);
	return PYVAL_NONE;
}

PyObject*
PyScriptObj::set_has_location(PyObject* self, PyObject* args)
{
	ScriptObj* c = NULL;
	PyObject *object;
	bool b;
	PyArg_ParseTuple(args, "Oi", &object, &b);
	Py_INCREF(object);
	if (PyCObject_Check(object)){
		c = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		c->set_has_location( b );
	}
	Py_INCREF(PYVAL_NONE);
	return PYVAL_NONE;
}

PyObject*
PyScriptObj::set_has_scale(PyObject* self, PyObject* args)
{
	ScriptObj* c = NULL;
	PyObject *object;
	bool b;
	PyArg_ParseTuple(args, "Oi", &object, &b);
	Py_INCREF(object);
	if (PyCObject_Check(object)){
		c = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		c->set_has_scale( b );
	}
	Py_INCREF(PYVAL_NONE);
	return PYVAL_NONE;
}

PyObject*
PyScriptObj::set_has_material(PyObject* self, PyObject* args)
{
	ScriptObj* c = NULL;
	PyObject *object;
	bool b;
	PyArg_ParseTuple(args, "Oi", &object, &b);
	Py_INCREF(object);
	if (PyCObject_Check(object)){
		c = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		c->set_has_material( b );
	}
	Py_INCREF(PYVAL_NONE);
	return PYVAL_NONE;
}

PyObject*
PyScriptObj::set_has_editbutton(PyObject* self, PyObject* args)
{
	ScriptObj* c = NULL;
	PyObject *object;
	bool b;
	PyArg_ParseTuple(args, "Oi", &object, &b);
	Py_INCREF(object);
	if (PyCObject_Check(object)){
		c = reinterpret_cast<ScriptObj*>(PyCObject_AsVoidPtr(object));
		c->set_has_editbutton( b );
	}
	Py_INCREF(PYVAL_NONE);
	return PYVAL_NONE;
}

PyMethodDef
PyScriptObj::python_methods[] = {
	{"new_scriptobject", new_scriptobject, METH_VARARGS, "New scriptobject"},
	{"get_location", get_location, METH_VARARGS, "Get loacation" },
	{"set_location", set_location, METH_VARARGS, "Set loacation" },
	{"get_rotation", get_rotation, METH_VARARGS, "Get rotation" },
	{"set_rotation", set_rotation, METH_VARARGS, "Set rotation" },
	{"get_size", get_size, METH_VARARGS, "Get size" },
	{"set_size", set_size, METH_VARARGS, "Set size" },
	{"add_triangle", add_triangle, METH_VARARGS, "Add triangle to mesh" },
	{"add_quad", add_quad, METH_VARARGS, "Add quad to mesh" },
	{"new_int", new_int, METH_VARARGS, "New integer value" },
	{"new_float", new_float, METH_VARARGS, "New float value" },
	{"new_double", new_double, METH_VARARGS, "New double value" },
	{"new_string", new_string, METH_VARARGS, "New string value" },
	{"set_int", set_int, METH_VARARGS, "Set integer value" },
	{"set_float", set_float, METH_VARARGS, "Set float value" },
	{"set_double", set_double, METH_VARARGS, "Set double value" },
	{"set_string", set_string, METH_VARARGS, "Set string value" },
	{"get_int", get_int, METH_VARARGS, "Get integer value" },
	{"get_float", get_float, METH_VARARGS, "Get float value" },
	{"get_double", get_double, METH_VARARGS, "Get double value" },
	{"get_string", get_string, METH_VARARGS, "Get string value" },
	{"get_script_path", get_script_path, METH_VARARGS, "Get script pathvalue" },
	{"set_script_path", set_script_path, METH_VARARGS, "Set script pathvalue" },
	{"set_pov_pass1", set_pov_pass1, METH_VARARGS, "Set pov pass1 string" },
	{"set_pov_pass2", set_pov_pass2, METH_VARARGS, "Set pov pass2 string" },
	{"set_has_rotation", set_has_rotation, METH_VARARGS, "Rotation on/off" },
	{"set_has_location", set_has_location, METH_VARARGS, "Location on/off" },
	{"set_has_scale", set_has_scale, METH_VARARGS, "Scale on/off" },
	{"set_has_material", set_has_material, METH_VARARGS, "Material on/off" },
	{"set_has_editbutton", set_has_editbutton, METH_VARARGS, "Editbutton on/off" },
	{NULL, NULL, 0, NULL}
};
