//
// This file is part of MorphoGraphX - http://www.MorphoGraphX.org
// Copyright (C) 2012-2015 Richard S. Smith and collaborators.
//
// If you use MorphoGraphX in your work, please cite:
//   http://dx.doi.org/10.7554/eLife.05864
//
// MorphoGraphX is free software, and is licensed under under the terms of the 
// GNU General (GPL) Public License version 2.0, http://www.gnu.org/licenses.
// 
#ifndef PYTHONPROCESS_HPP
#define PYTHONPROCESS_HPP

#include <Process.hpp>

#if defined(WIN64) && defined(__GNUC__)
#  define Py_InitModule4 Py_InitModule4_64
#endif
#include <Python.h>
#include <string>

namespace mgx 
{
  class PythonProcess;
  
  struct mgxPython_EXPORT mgx_Factory 
  {
    PythonProcess* process;
  };
  
  struct mgxPython_EXPORT mgx_Factory_Python 
  {
    PyObject_HEAD;
    mgx_Factory intern;
    PyObject* fact_dict;
  };
  
  struct mgxPython_EXPORT mgx_Process 
  {
    QString name;
    int numParms;
    PythonProcess* process;
  };
  
  struct mgxPython_EXPORT mgx_Process_Python 
  {
    PyObject_HEAD;
    PyObject* descr;
    mgx_Process intern;
  };
  
  extern mgxPython_EXPORT PyTypeObject factory_type;
  extern mgxPython_EXPORT PyTypeObject process_type;
  
  /**
   * \class PythonProcess PythonProcess.hpp <PythonProcess.hpp>
   *
   * This process evaluate a Python script from which other processes can be called.
   *
   * \ingroup MiscellaneousProcess
   */
  class mgxPython_EXPORT PythonProcess : public Process 
  {
  public:
    PythonProcess(const Process& process) : Process(process)
    {
      setName("Misc/Python/Python Script");
      setDesc("Run python script");
      setIcon(QIcon(":/images/Python.png"));

      addParm("Script","Script to run","");
    }
  
    bool initialize(QWidget* parent);
  
    bool run()
    { 
      return run(parm("Script"));
    }

    bool run(QString filename); 

    mgx_Process_Python* createProcess(const QString& name);
  
  protected:
    bool initPython(const QString& filename);
    bool finalizePython();
    bool addFactory(char* name);
    bool removeFactory(char* name);
    QString getTraceBack(PyObject* tb, int limit);
  
    PyObject* module, *main, *main_dict;
  };
}
#endif
