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

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

/* C functions to replace the Ch one */
static ChInterp_t interp;
static int (*ptfun2_chdl_funarg[MAXNUM])();

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

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

EXPORTCH int ptfun2_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;
    }
    ptfun2_chdl_funptr[index] = (void *)handle_ch;
    handle_c = ptfun2_chdl_funarg[index];
    index++;
  }

  retval = ptfun2_setHandle(id, handle_c);

  Ch_VaEnd(interp, ap);
  return retval;
}

EXPORTCH funcHandle ptfun2_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 = ptfun2_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(ptfun2_chdl_funarg[i] == retval_c) {
        retval_ch = (funcHandle)ptfun2_chdl_funptr[i];
      }
    }
  }

  Ch_VaEnd(interp, ap);
  return retval_ch;
}

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

static int ptfun2_chdl_funarg0() {
  int retval;

  Ch_CallFuncByAddr(interp, ptfun2_chdl_funptr[0], &retval);
  return retval;
}

static int ptfun2_chdl_funarg1() {
  int retval;

  Ch_CallFuncByAddr(interp, ptfun2_chdl_funptr[1], &retval);
  return retval;
}

static int ptfun2_chdl_funarg2() {
  int retval;

  Ch_CallFuncByAddr(interp, ptfun2_chdl_funptr[2], &retval);
  return retval;
}

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

   ptfun2_chdl_funarg[0] = ptfun2_chdl_funarg0;
   ptfun2_chdl_funarg[1] = ptfun2_chdl_funarg1;
   ptfun2_chdl_funarg[2] = ptfun2_chdl_funarg2;

   return 0;
}
