/* Copyright (c) 2001-2009 by SoftIntegration, Inc. All Rights Reserved */
#include <stdio.h>
#include "ptfun3_c.h" 
#include <ch.h>

/* The maximum number of ptfun3_setHandle()
   can be called */
#define MAXNUM   3 

/* C functions to replace the Ch one */
static ChInterp_t interp;
static void (*ptfun3_chdl_funarg[MAXNUM])(float, int);

/* function pointers to save Ch function pointers */
static void *ptfun3_chdl_funptr[MAXNUM]; 

/* index of pointer pairs, from 0 to MAXNUM-1 */
static int index = 0;   

EXPORTCH int ptfun3_setHandle_chdl(void *varg){
  int i;
  ChVaList_t ap;
  int id;
  funcHandle handle_ch, handle_c;
  int retval;

  Ch_VaStart(interp, ap, varg);
  id = Ch_VaArg(interp, ap, int);         
  handle_ch = Ch_VaArg(interp, ap, funcHandle);   

  if(handle_ch == NULL) {
    handle_c = NULL;
  }
  else {
    if(index == MAXNUM) {
      printf("Error: Only %d function pointers can be set\n", MAXNUM);
      return -1;
    }
    ptfun3_chdl_funptr[index] = (void *)handle_ch;
    handle_c = ptfun3_chdl_funarg[index];
    index++;
  }

  retval = ptfun3_setHandle(id, handle_c);

  Ch_VaEnd(interp, ap);
  return retval;
}

EXPORTCH funcHandle ptfun3_getHandle_chdl(void *varg){
  int i;
  ChVaList_t ap;
  int id;
  funcHandle retval_c = NULL, retval_ch = NULL;

  Ch_VaStart(interp, ap, varg);
  id = Ch_VaArg(interp, ap, int);         

  retval_c = ptfun3_getHandle(id);

  /* replace C pointer with corresponding Ch function pointer */
  if(retval_c == NULL)  {
    retval_ch = NULL;
  }
  else {
    for(i = 0; i < index; i++) {
      if(ptfun3_chdl_funarg[i] == retval_c) {
        retval_ch = (funcHandle)ptfun3_chdl_funptr[i];
      }
    }
  }
  Ch_VaEnd(interp, ap);
  return retval_ch;
}

/**** hundreds of functions can be here ****/

static void ptfun3_chdl_funarg0(float f, int i) {
  Ch_CallFuncByAddr(interp, ptfun3_chdl_funptr[0], NULL, f, i);
}

static void ptfun3_chdl_funarg1(float f, int i) {
  Ch_CallFuncByAddr(interp, ptfun3_chdl_funptr[1], NULL, f, i);
}

static void ptfun3_chdl_funarg2(float f, int i) {
  Ch_CallFuncByAddr(interp, ptfun3_chdl_funptr[2], NULL, f, i);
}

/********* initialization routine called in ptfun3.h **********/
EXPORTCH int ptfun3_setgetHandles_init() {
  /* from 0 to MAXNUM -1 */

   ptfun3_chdl_funarg[0] = ptfun3_chdl_funarg0;
   ptfun3_chdl_funarg[1] = ptfun3_chdl_funarg1;
   ptfun3_chdl_funarg[2] = ptfun3_chdl_funarg2;

   return 0;
}
