	/****************************/
	/*		  pyhandler.h		*/
	/****************************/

#ifndef PYHANDLER_H
#define PYHANDLER_H

#include <wx/string.h>
#include <wx/wxPython/wxPython.h>
#include <vector>

/* Use the boost library : */
#include <boost/python.hpp>

#include <Python.h>


class PyHandler
{

    typedef void (*initfunc_t )();

	private:
		static PyHandler * m_instance;
        bool m_ModulesLoaded;
        int m_current;
		PyThreadState* m_mainTState;

	protected:
		PyHandler();

		wxString m_appName;
 		void RunBaseScripts( const wxString & base );
 
        // Modules
        struct ModuleRecord
        {
            wxString name;
            std::vector< initfunc_t > registry;

            ModuleRecord( const wxString & modName ) : name(modName) {}
        };
        std::vector< ModuleRecord > m_ModuleRegistry;
        void DoInitModules();

        // Events
        struct Event
        {
            wxString key;
            std::vector< boost::python::object > functors;

            Event( const wxString & strKey ) : key( strKey ) {}
        };
        std::vector< Event > m_EventRegistry;

	public:
 		// Singletton handling:
		static PyHandler * GetInstance();

		~PyHandler();

		// Scope params/handling:
 		void SetAppName( const wxString & name );

		void AddToModule( const wxString & name, initfunc_t initfunc );
        int GetModuleIndex( const wxString & name ) const;

		// Script and direct call
		void RunScripts();
		bool RunScript( const wxString & name );
        bool RunSimpleString( const wxString & code );

 		// Common Informations
		const char * GetVersion();

		void InitNextModule();

        // Event triggering

        // - C++ interface
        void DeclareEvent( const wxString & key );
        void TriggerEvent( const wxString & key );
        void TriggerEvent( const wxString & key, const boost::python::object & param );
        int GetEventIndex( const wxString & key );

        // - Py Interface
        void RegisterCallback  ( const wxString & key, const boost::python::object & obj );
        void UnRegisterCallback( const wxString & key, const boost::python::object & obj );

        // Object conversions

        // - Py -> C++
        static wxString MakeStr( const boost::python::object & objStr );

        // - C++ -> Py
        static boost::python::object Convert( const wxString & wxStr );
};


#define KICAD_PY_BIND_MODULE( mod ) PyHandler::GetInstance()->AddModule( init#mod )

#endif	//PYHANDLER_H

