#include "include/pyengine.h"
#include "include/pyobjects.h"
#include "include/pylights.h"
#include "include/pyscriptobj.h"
#include "include/interface.h"
#include "config.h"

PyEngine::PyEngine( app_objs *appref)
{
	app_ref = appref;
	app_ref->python_engine = this;
	Py_Initialize();
	filename = NULL;
	default_path = NULL;
}

PyEngine::~PyEngine()
{
	if(Py_IsInitialized())
		Py_Finalize();

}
int
PyEngine::initialize(char* fname, PyObject* obj, int _mode)
{
	if(!initialize())
		return 0;

	if ( obj != NULL ) {
		Py_INCREF(obj);
		PyModule_AddObject( my_module, "my_cobject", obj );
	}

	PyModule_AddStringConstant(	my_module, "filename", fname);
	PyModule_AddIntConstant( my_module, "run_mode", _mode );
	return 1;
}
int
PyEngine::initialize()
{
#ifndef PACKAGE_PYTHON_DIR
	printf("PACKAGE_PYTHON_DIR not defined\n");fflush(stdout);
#endif
	char* pyclasses = (char*)malloc((size_t)strlen(PACKAGE_PYTHON_DIR) + strlen("tv_classes.py")+3);
	pyclasses = strcpy(pyclasses, PACKAGE_PYTHON_DIR);
	pyclasses = strcat(pyclasses, "/tv_classes.py");
	FILE *fp = NULL;
		
	if(Py_IsInitialized())
		Py_Finalize();
	
	Py_Initialize();
	
	my_module = Py_InitModule("_App", PyApp::python_methods);
	Py_InitModule("_Object3D", PyObject3D::python_methods);
	Py_InitModule("_Object3DMaterial", PyObject3DMaterial::python_methods);
	Py_InitModule("_Box", PyBox::python_methods);
	Py_InitModule("_Disc", PyDisc::python_methods);
	Py_InitModule("_Superellipsoid", PySuperEllipsoid::python_methods);
	Py_InitModule("_Sphere", PySphere::python_methods);
	Py_InitModule("_Cone", PyCone::python_methods);
	Py_InitModule("_Cylinder", PyCylinder::python_methods);
	Py_InitModule("_Torus", PyTorus::python_methods);
	Py_InitModule("_Plane", PyPlane::python_methods);
	Py_InitModule("_ObjCSG", PyCSGObject::python_methods);
	Py_InitModule("_CSGCutAway", PyCSGCutAway::python_methods);
	Py_InitModule("_CSGDifference", PyCSGDifference::python_methods);
	Py_InitModule("_CSGUnion", PyCSGUnion::python_methods);
	Py_InitModule("_CSGMerge", PyCSGMerge::python_methods);
	Py_InitModule("_CSGIntersection", PyCSGIntersection::python_methods);
	Py_InitModule("_Layer", PyLayer::python_methods);
	Py_InitModule("_Scene", PyScene::python_methods);
	Py_InitModule("_Bicubic", PyBicubic::python_methods);
	Py_InitModule("_PointLight", PyPointLight::python_methods);
	Py_InitModule("_AreaLight", PyAreaLight::python_methods);
	Py_InitModule("_SpotLight", PySpotLight::python_methods);
	Py_InitModule("_CylindricalLight", PyCylindricalLight::python_methods);
	Py_InitModule("_ScriptObj", PyScriptObj::python_methods);
	if( my_module == NULL ) {
		printf("my_module is NULL!\n\n");fflush(stdout);
	}
	Py_INCREF(my_module);
	
	PyRun_SimpleString("import _App");
	PyRun_SimpleString("import _Object3D");
	PyRun_SimpleString("import _Object3DMaterial");
	PyRun_SimpleString("import _Box");
	PyRun_SimpleString("import _Disc");
	PyRun_SimpleString("import _Superellipsoid");
	PyRun_SimpleString("import _Sphere");
	PyRun_SimpleString("import _Cone");
	PyRun_SimpleString("import _Cylinder");
	PyRun_SimpleString("import _Torus");
	PyRun_SimpleString("import _Plane");
	PyRun_SimpleString("import _ObjCSG");
	PyRun_SimpleString("import _CSGUnion");
	PyRun_SimpleString("import _CSGCutAway");
	PyRun_SimpleString("import _CSGDifference");
	PyRun_SimpleString("import _CSGMerge");
	PyRun_SimpleString("import _CSGIntersection");
	PyRun_SimpleString("import _Layer");
	PyRun_SimpleString("import _Scene");
	PyRun_SimpleString("import _Bicubic");
	PyRun_SimpleString("import _PointLight");
	PyRun_SimpleString("import _AreaLight");
	PyRun_SimpleString("import _SpotLight");
	PyRun_SimpleString("import _CylindricalLight");
	PyRun_SimpleString("import _ScriptObj");
			
	if((fp = fopen( pyclasses, "r" )) == NULL){
		printf("Error: Could not find Python classes: %s!\n", pyclasses);fflush(stdout);
		return 0;
	}
	
	PyRun_SimpleFile(fp, pyclasses);
	fclose(fp);
	return 1;
}


void
PyEngine::execute_script()
{
	FILE *fp = NULL;
	char* fname= filename;

	if ( !initialize() )
		return;
	
	if((fp = fopen( fname, "r" )) == NULL){
		printf("Error: Could not open file: %s!\n", fname);fflush(stdout); return;}
	
	PyRun_SimpleFile(fp, fname);
	fclose(fp);
}

void
PyEngine::execute_script(char* fname, PyObject *obj, int _mode)
{
	FILE *fp = NULL;

	if ( !initialize( fname, obj, _mode ) ) {
		printf("Could not initialize PyEngine! Run mode: %d\n", _mode);fflush(stdout);
		return;
	}
	
	if((fp = fopen( fname, "r" )) == NULL){
		printf("Error: Could not open file: %s!\n", fname);fflush(stdout); return;}
	
	PyRun_SimpleFile(fp, fname);
	fclose(fp);
}

void
PyEngine::load_as()
{
	GtkFileFilter *filter1 = gtk_file_filter_new();
	gtk_file_filter_add_pattern( filter1, "*.py" );	
	gtk_file_filter_set_name( filter1, "Python file" );	
	GtkFileFilter *filter2 = gtk_file_filter_new();
	gtk_file_filter_add_pattern( filter2, "*.*" );	
	gtk_file_filter_set_name( filter2, "All files" );	

	INTERF_DEF
	filebox = gtk_file_chooser_dialog_new( _("Open script..."), (GtkWindow*)interf->get_gtkwin(), 
	GTK_FILE_CHOOSER_ACTION_OPEN,  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
	GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,  NULL);
	gtk_file_chooser_add_filter( GTK_FILE_CHOOSER(filebox), filter1 );
	gtk_file_chooser_add_filter( GTK_FILE_CHOOSER(filebox), filter2 );

	if (gtk_dialog_run (GTK_DIALOG (filebox)) == GTK_RESPONSE_ACCEPT) {
		char *fname;
		fname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filebox));
		if ( fname == NULL ) {
			interf->set_hourglass( false );
			gtk_widget_destroy( filebox );
			return;
		}
	execute_script( fname, NULL, PY_MODE_REGISTER );	
  	g_free (fname);
  	}
	gtk_widget_destroy( filebox );	
}
