#include <formatio.h>
 
#include <utility.h>
 
#include <python.h>
 
#include <ansi_c.h>
 
#include <cvirte.h>             
 
#include <userint.h>
 
#include "TestGui.h"
 
#include "ExportCVIFunctions.h" 
 
// http://www.linuxjournal.com/node/8497/print
 
 
 
 
 
 
 
static int pTSQData[2];
 
static int tfID;
 
CmtThreadPoolHandle threadHandle = 0;
 
CmtTSQHandle  queueHandle;
 
int panelHandle;
 
 
 
int ProcessUserEvent(int pID, int rID,int mode);
 
 
 
char strbuf[0xFF];
 
int mprintf(const char *format, ...) {
 
  va_list aptr;
 
  FILE *flog;
 
 
 
  SetCtrlVal(panelHandle,PANEL_STDIO,strbuf);
 
  return(ret);
 
}
 
 
 
// map uir controls ....
 
#define MAX_UIRCTRLMAP_SIZE 1000
 
typedef struct {
 
  char name[32];
 
  int id;
 
  int handle;
 
} UirCtrlMap;
 
UirCtrlMap gUirCtrlMap[MAX_UIRCTRLMAP_SIZE];
 
int gNUirCtrlMap=0;
 
 
 
int GetControlID(const char *ctrl) {
 
  for (int i=0; i<gNUirCtrlMap; i++) {
 
    if (strcmp(ctrl
,gUirCtrlMap
[i
].
name)==0) return ctrl
,gUirCtrlMap
[i
].
id;  
  }
 
  return -1;
 
}
 
 
 
int GetPanelHandle(const char *ctrl) {
 
 
 
  if ( strstr(ctrl
, "PANEL_")!= NULL 
) return panelHandle
;  
 
 
  return 0;
 
}
 
 
 
DLLEXPORT int pySetPanelHandle(int handle) {
 
 
 
  panelHandle = handle;
 
  return 0;
 
}
 
 
 
DLLEXPORT int pySetQueueHandle(int handle) {
 
 
 
  queueHandle = handle;
 
  return 0;
 
}
 
 
 
DLLEXPORT int pySetThreadHandle(int handle) {
 
 
 
  threadHandle = handle;
 
  return 0;
 
}
 
 
 
 
 
DLLEXPORT int pyLoadUirHeader(const char *fname) {
 
  int ndim=MAX_PATHNAME_LEN;
 
  char line[MAX_PATHNAME_LEN];
 
  char cmd[MAX_PATHNAME_LEN];
 
  FILE *fp = NULL;
 
  ssize_t size;
 
  int n0= gNUirCtrlMap;
 
  if ( GetFileInfo
(fname
,&size
) ) fp 
= fopen(fname
,"r");  
  if (!fp) {
 
    mprintf("Error! Cannot open header file %s\n",fname);
 
    return -1;
 
  }
 
 
 
  while (fgets(line
,ndim
,fp
)!=NULL 
) {  
    char ctrl[32];
 
    int ctrlid;
 
    int nb 
= sscanf(line
,"%s%s%d",cmd
, ctrl
, &ctrlid
);  
    if (strstr(cmd
,"#define")!=NULL 
&& nb
==3) {  
      strcpy(gUirCtrlMap
[gNUirCtrlMap
].
name, ctrl 
);  
      if (gNUirCtrlMap<MAX_UIRCTRLMAP_SIZE) {
 
        gUirCtrlMap[gNUirCtrlMap].id     = ctrlid;
 
        gUirCtrlMap[gNUirCtrlMap].handle = GetPanelHandle(ctrl);
 
        mprintf("%s= Ctrl '%d' Panel'%d'\n", ctrl,ctrlid, gUirCtrlMap[gNUirCtrlMap].handle);  
 
        gNUirCtrlMap++;
 
      } else {
 
        mprintf("ERROR: Increase gNUirCtrlMap\n");
 
      }
 
    }
 
  }
 
  mprintf("Number of Controls loaded from File %s = %d \n", fname,gNUirCtrlMap-n0);
 
  return 0;
 
}
 
 
 
DLLEXPORT int pyGetCtrlVal(char *param, char *paramValue){
 
  int pID= GetPanelHandle(param);
 
  int rID= GetControlID(param);
 
  int datatype; 
 
  int retval=-1;
 
  if (rID>0 && pID>0) {
 
    GetCtrlAttribute (pID, rID, ATTR_DATA_TYPE, &datatype);
 
    retval =  GetCtrlVal(pID, rID, paramValue);
 
     switch (datatype) {
 
      case VAL_INTEGER:
 
        mprintf("[GetCtrlVal]  %s value=%d panel=%d control=%d\n",param, *(int *) paramValue,pID,rID);
 
        break;
 
      case VAL_UNSIGNED_INTEGER:
 
        mprintf("[GetCtrlVal]  %s value=%u panel=%d control=%d\n",param, *(unsigned int *) paramValue,pID,rID);
 
        break;
 
      case VAL_SHORT_INTEGER:
 
        mprintf("[GetCtrlVal]  %s value=%d panel=%d control=%d\n",param, *(short *) paramValue,pID,rID);    
 
        break;
 
      case VAL_UNSIGNED_SHORT_INTEGER:
 
        mprintf("[GetCtrlVal]  %s value=%d panel=%d control=%d\n",param, *(unsigned short *) paramValue,pID,rID);    
 
        break;
 
      case VAL_DOUBLE :
 
        mprintf("[GetCtrlVal]  %s value=%f panel=%d control=%d\n",param, *(double *) paramValue,pID,rID); 
 
        break;
 
      case VAL_STRING :
 
      default:  
 
        mprintf("[GetCtrlVal]  %s value=%s panel=%d control=%d\n",param, paramValue,pID,rID); 
 
        break;
 
        
 
     }   
 
  }  
 
  
 
  return retval;
 
}  
 
 
 
 
 
DLLEXPORT int pyQueueUserEvent(char *param){   
 
 
 
  int pID= GetPanelHandle(param);
 
  int rID= GetControlID(param);
 
  int retval=-1;
 
  mprintf("QueueUserEvent %s panelHandle %d controlID %d\n",param, pID, rID );
 
  
 
  if (rID>0 && pID>0) {
 
    int data[2] = {pID,rID};
 
    mprintf("queueHandle %d\n", queueHandle ); 
 
    retval = CmtWriteTSQData (queueHandle, data, 1, TSQ_INFINITE_TIMEOUT, NULL);
 
 
 
  }
 
  return retval;
 
}
 
 
 
 
 
DLLEXPORT int pyProcessUserEvent(char *param){   
 
 
 
  int pID= GetPanelHandle(param);
 
  int rID= GetControlID(param);
 
  int retval=-1;
 
  mprintf("ProcessUserEvent %s panelHandle %d controlID %d\n",param, pID, rID );
 
  if (rID>0 && pID>0) retval = ProcessUserEvent(pID, rID,0);
 
  return retval;
 
}
 
 
 
 
 
 
 
DLLEXPORT int pySetCtrlVal(char *param, char *paramValue)
 
{
 
  
 
 
 
  int pID= GetPanelHandle(param);
 
  int rID= GetControlID(param);
 
  int datatype;
 
  int ret=0;
 
  if (rID>0 && pID>0) {
 
    GetCtrlAttribute (pID, rID, ATTR_DATA_TYPE, &datatype);
 
 
 
    switch (datatype) {
 
      case VAL_INTEGER:
 
        ret
=SetCtrlVal 
(pID
, rID
, atoi(paramValue
)); 
        break;
 
      case VAL_UNSIGNED_INTEGER:
 
        ret
=SetCtrlVal 
(pID
, rID
, strtoul(paramValue
,NULL
,0)); 
        break;
 
      case VAL_SHORT_INTEGER:
 
        ret
=SetCtrlVal 
(pID
, rID
, atoi(paramValue
)); 
        break;
 
      case VAL_UNSIGNED_SHORT_INTEGER:
 
        ret
=SetCtrlVal 
(pID
, rID
, strtoul(paramValue
,NULL
,0)); 
        break;
 
      case VAL_DOUBLE :
 
        ret
=SetCtrlVal 
(pID
, rID
, atof(paramValue
)); 
        break;
 
      case VAL_STRING :
 
        ret=SetCtrlVal (pID, rID, paramValue      );
 
        break;
 
      default:
 
        mprintf("[SetCtrlVal] ATTR_DATA_TYPE of the %s not supported datatype %d\n", param, datatype);
 
    }
 
    mprintf("[SetCtrlVal]  %s %s panel=%d control=%d\n",param, paramValue,pID,rID);
 
  } else {
 
    mprintf("[SetCtrlVal] Invalid Ctrl %s %s panel=%d control=%d  nctrls=%d\n",param, paramValue,pID,rID,gNUirCtrlMap);
 
  }
 
 
 
 
 
  return  ret;
 
}
 
 
 
DLLEXPORT int pyPrint(int panel)
 
{
 
  
 
  mprintf("Hi! %d\n", panel);
 
  //return  SetCtrlVal(panel, ctrl,text );  
 
  return 0;
 
}
 
 
 
 
 
 
 
void CVICALLBACK QueueUserEventCallback (CmtTSQHandle queueHandle, unsigned int event, int value, void *callbackData) {
 
  int *data= (int *)  callbackData;
 
  int mdata[2];
 
  CmtReadTSQData (queueHandle, mdata, 1, 0, 0);
 
  mprintf("QueueUserEvent --->Thread Safe Queue  %d %d\n", mdata[0],mdata[1]);
 
  QueueUserEvent (1001, mdata[0], mdata[1]);
 
}
 
 
 
 
 
 
 
 
 
int CVICALLBACK Test(void *functionData) 
 
{
 
  
 
  mprintf("Test\n");
 
 
 
  return 0;
 
}
 
 
 
 
 
int CVICALLBACK ExecPython(void *functionData) 
 
{
 
  
 
  char *argv="testgui.py";
 
  int argc=1;
 
  Py_Initialize();
 
  mprintf("Py_Main() %d\n", Py_Main(argc, &argv));
 
  Py_Finalize();
 
  return 0;
 
}
 
 
 
 
 
 
 
int cRunPython = 0;
 
 
 
int CVICALLBACK RunPython(void *functionData) 
 
{
 
  
 
  char *fname="testgui.py";
 
  
 
  char handles[0xFF];
 
        
 
  int argc=0, merr=0;
 
  char *argv = "TestGui.exe";
 
 
 
  while ( cRunPython ) {
 
    mprintf("RunPython not finished yet... Waiting ....\n");
 
    Delay(0.5);// To Ensure only one python interpreter is running    
 
  }
 
  cRunPython = 1;
 
  Py_Initialize();
 
 
 
  mprintf("Py_IsInitialized(); %d\n", Py_IsInitialized());
 
  mprintf("Py_GetVersion() %s\n",   Py_GetVersion() );
 
 
 
  PyRun_SimpleString("import sys\n");
 
  PyRun_SimpleString("sys.stdout = sys.stderr = open(\"log_file.txt\", \"w\")\n" );
 
  sprintf(handles
, "panel=%d\nqueue=%d\n", panelHandle
, (int) queueHandle
);  
  mprintf(handles);
 
  PyRun_SimpleString(handles);
 
  PyRun_SimpleString(
 
    "print('Example , how to use python from NI LWCVI')\n"
 
    "from time import time,ctime\n"
 
    "print( 'Today is',ctime(time()))\n"
 
  );
 
 
 
 
 
  PyObject *obj = Py_BuildValue("s", fname);
 
  FILE *fp = _Py_fopen_obj(obj, "r+");
 
  //fp = fopen(fname,"r");  // tole ne dela
 
  if(fp != NULL) merr = PyRun_SimpleFile(fp, fname);
 
  mprintf("PyRun_SimpleFile(%s) %d ---->output\n",fname, merr);
 
 
 
  Py_Finalize();
 
  char line[MAX_PATHNAME_LEN];
 
  FILE 
*fpout
= fopen("log_file.txt","r"); 
  if (fpout) {
 
    while (fgets(line
,MAX_PATHNAME_LEN
,fpout
)!=NULL
) mprintf
(line
);  
  }
 
 
 
  cRunPython = 0;
 
 
 
        return 0;
 
}
 
 
 
void SetDimming(int state) {
 
  mprintf("SetDimming %d\n", state);  
 
  SetCtrlAttribute (panelHandle, PANEL_START, ATTR_DIMMED, state);
 
  SetCtrlAttribute (panelHandle, PANEL_INTERPRETER, ATTR_DIMMED, state);   
 
  SetCtrlAttribute (panelHandle, PANEL_TEST, ATTR_DIMMED, state);   
 
}
 
 
 
int nthreads=0;
 
void CVICALLBACK EndOfThread ( CmtThreadPoolHandle poolhandle,
 
                               CmtThreadFunctionID functionID, unsigned int event,
 
                               int value, void *callbackData  ) {
 
  mprintf("%d End of Thread handle=%d functionID=%d\n", nthreads, (int)poolhandle, functionID);
 
  
 
  nthreads--;
 
  if (!nthreads) SetDimming(0); 
 
  return ;
 
 
 
}
 
 
 
 
 
 
 
 
 
int ProcessUserEvent(int pID, int rID,int mode){
 
 
 
  ThreadFunctionPtr thread = NULL;
 
  int retval=0;
 
  switch (rID) {
 
    case PANEL_START:
 
      thread=RunPython;
 
      break;
 
    case PANEL_INTERPRETER:
 
      thread=ExecPython;
 
      break;
 
    case PANEL_TEST:
 
      thread=Test;
 
      break;
 
    case PANEL_EXIT :
 
      return 1;
 
    default:
 
      mprintf("Unknown Event panel %d control %d\n",pID,rID);
 
      
 
  }
 
 
 
  if (thread!=NULL) {
 
    
 
    if (mode) {
 
      SetDimming(1);   
 
      mprintf("%d ProcessUserEvent in new Thread panel=%d button=%d mode=%d\n",nthreads, pID, rID, mode); 
 
      retval = CmtScheduleThreadPoolFunctionAdv (threadHandle, thread, &rID,
 
               DEFAULT_THREAD_PRIORITY,
 
               EndOfThread,
 
               EVENT_TP_THREAD_FUNCTION_END,
 
               NULL, RUN_IN_SCHEDULED_THREAD,
 
               &tfID);
 
      if (retval<0) {
 
        char txt[MAX_PATHNAME_LEN];
 
        CmtGetErrorMessage(retval, txt);
 
        MessagePopup("CmtScheduleThreadPoolFunctionAdv", txt);
 
      } else nthreads++;
 
    } else {
 
      mprintf("ProcessUserEvent panel=%d button=%d mode=%d\n", pID, rID, mode);
 
      thread(NULL);
 
    }
 
  }
 
  ProcessSystemEvents();
 
 
 
  return retval;
 
}  
 
 
 
 
 
 
 
int main (int argc, char *argv[])
 
{
 
        if (InitCVIRTE (0, argv, 0) == 0)
 
                return -1;      /* out of memory */
 
        if ((panelHandle = LoadPanel (0, "TestGui.uir", PANEL)) < 0)
 
                return -1;
 
  //pyLoadUirHeader("TestGui.h"); 
 
 
 
  int status=0;
 
  CmtNewThreadPool (10,  &threadHandle);  
 
  if ( status = CmtNewTSQ (1, 2*sizeof(int), OPT_TSQ_AUTO_FLUSH_ALL, &queueHandle) <0)
 
    mprintf("CmtNewTSQ cannot be installed\n");
 
  else {
 
    mprintf("CmtNewTSQ handle %d\n", (int) queueHandle ); 
 
  }
 
  if ( status = CmtInstallTSQCallback (queueHandle, EVENT_TSQ_ITEMS_IN_QUEUE, EVENT_TSQ_QUEUE_SIZE,
 
                                       QueueUserEventCallback, pTSQData, CmtGetCurrentThreadID(), NULL)  <0)
 
    mprintf("CmtInstallTSQCallback cannot be installed\n");  ;
 
  
 
        DisplayPanel (panelHandle);
 
        
 
  int pID, rID, retval;
 
  do {
 
    GetUserEvent (1, &pID, &rID);   
 
    retval = ProcessUserEvent(pID,rID,1);
 
  } while (!retval);
 
 
 
  CmtDiscardThreadPool (threadHandle);
 
        DiscardPanel (panelHandle);
 
        return 0;
 
}
 
 
 
 
 
 
 
 
 
  
 
/*
 
 
 
static PyObject * SetCtrlVal_wrapper(PyObject * self, PyObject * args)
 
{
 
  char * input;
 
  char result[0xFF];
 
  PyObject * ret;
 
 
 
  // parse arguments
 
  if (!PyArg_ParseTuple(args, "s", &input)) {
 
    return NULL;
 
  }
 
 
 
  // run the actual function
 
  int retval = SetCtrlVal(panelHandle, PANEL_TXT,input );
 
  sprintf(result,"%d", retval);
 
  // build the resulting string into a Python object.
 
  ret = PyBytes_FromString(result);
 
  free(result);
 
 
 
  return ret;
 
}
 
 
 
 
 
static PyMethodDef module_methods[] = {
 
    {"fib",(PyCFunction) SetCtrlVal_wrapper, METH_VARARGS,"Outputs the text to the PANEL_TXT"},
 
    {NULL,NULL,0,NULL}
 
};
 
 
 
static struct PyModuleDef cModPyDem =
 
{
 
    PyModuleDef_HEAD_INIT,
 
    "SetCtrlVal", // name of module 
 
    "",          // module documentation, may be NULL 
 
    -1,          // size of per-interpreter state of the module, or -1 if the module keeps state in global variables. 
 
    module_methods
 
};
 
 
 
 
 
PyMODINIT_FUNC PyInit_cModPyDem(void)
 
{
 
    return PyModule_Create(&cModPyDem);
 
}
 
 
 
*/