#include "stdafx.h"
#include "PyBind.h"

#define ENABLE_PYTHON_BIND 0

#if ENABLE_PYTHON_BIND

#include <iostream>
using namespace std;

#include "View3D.h"
#include "View2D.h"

#define BOOST_PYTHON_STATIC_LIB
#include <boost/python.hpp>
#include <boost/ref.hpp>

#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

namespace bpy = boost::python;
using namespace boost;
using namespace boost::python;



typedef std::vector< lm::vec3f > VertAry;
typedef std::vector< lib_geo::VertAdj > VertAdjAry;
typedef std::vector< lib_geo::BaseFace > FaceAry;


BOOST_PYTHON_MODULE(CppExport)
{
	bpy::class_<lm::vec3f, boost::noncopyable>("vec3f")
		.def_readwrite("x", &lm::vec3f::x)
		.def_readwrite("y", &lm::vec3f::y)
		.def_readwrite("z", &lm::vec3f::z)
		;

	bpy::class_<lib_geo::VertAdj, boost::noncopyable>("VertAdj")
		;
	
	bpy::class_<lib_geo::BaseFace, boost::noncopyable>("BaseFace")
		;

	bpy::class_<lib_geo::BasePolyline, boost::noncopyable>("BasePolyline")
		;

	bpy::class_<VertAry, boost::noncopyable>("VertAry")
		//.def(vector_indexing_suite<VertAry>() )
		;

	bpy::class_<VertAdjAry, boost::noncopyable>("VertAdjAry")
		.def("size", &VertAdjAry::size)
		//.def("at", &VertAdjAry::at)
		;

	bpy::class_<FaceAry, boost::noncopyable>("FaceAry")
		.def("size", &FaceAry::size)
		//.def("at", &FaceAry::at)
		;

	bpy::class_<lib_geo::BaseMesh, boost::noncopyable>("BaseMesh")
		.def_readwrite("m_Verts", &lib_geo::BaseMesh::m_Verts)
		.def_readwrite("m_Normals", &lib_geo::BaseMesh::m_Normals)
		.def_readwrite("m_Faces", &lib_geo::BaseMesh::m_Faces)
		.def_readwrite("m_Polylines", &lib_geo::BaseMesh::m_Polylines)
		;

	bpy::class_<MeshBuf, boost::noncopyable>("MeshBuf")
		.def("SetVertSelect", &MeshBuf::SetVertSelect)
		.def("GetVertSelect", &MeshBuf::GetVertSelect)
		.def_readwrite("m_Mesh", &MeshBuf::m_Mesh)
		;

	bpy::class_<GeomObject, boost::noncopyable>("GeomObject")
		//.def_readwrite("m_MeshAry", &GeomObject::m_MeshAry)
		;

	bpy::class_<View3D, boost::noncopyable>("View3D")
		.def("RepaintParent", &View3D::RepaintParent)
		;

	bpy::class_<View2D, boost::noncopyable>("View2D")
		.def("RepaintParent", &View2D::RepaintParent)
		;
}


#endif


void PyBind::Run(const QString& script)
{
#if ENABLE_PYTHON_BIND
	if( PyImport_AppendInittab( "CppExport" , initCppExport ) == -1 )
	{
		cout << "Failed" << endl;
		getchar();
		return;
	}

	Py_Initialize();

	PyObject* sys = PyImport_ImportModule("sys");
	PyObject* pystdout = PyFile_FromString("CONOUT$", "wt");
	if (-1 == PyObject_SetAttrString(sys, "stdout", pystdout))
	{
		cout << "error to assign python stdout to console" << endl;
	}
	Py_DECREF(sys);
	Py_DECREF(pystdout);

	try
	{
		// CppExport以下をPythonにインポート
		bpy::object global_ns = bpy::import("__main__").attr("__dict__");
		bpy::exec
		(
			"from CppExport import *\n"
			, global_ns , global_ns
		);

		GeomObject* obj = m_Scene->GetPrimaryObject();

		// C++のオブジェクトへの参照をPythonに登録
		// この処理を実行する前に, Python内でSampleClassのインポートを行う必要有.
		global_ns["obj"] = boost::ref(obj);
		global_ns["view3d"] = boost::ref(m_View3d);
		global_ns["view2d"] = boost::ref(m_View2d);

		bpy::exec(script.toLocal8Bit().data(), global_ns, global_ns);
	}
	catch(const bpy::error_already_set&)
	{
		PyErr_Print();
	}

	Py_Finalize();
#endif
}
