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

#define MAXNUM 3 /* maximum length of the array of function */

typedef int (**pfuncArr_t)(int num); /* function pointer type */
static ChInterp_t interp;
static int (*setarrayfunc_chdl_funarg[MAXNUM])(int num);
static int (*setarrayfunc_chdl_funptr[MAXNUM])(int num);

static int setarrayfunc_chdl_funarg0(int num);
static int setarrayfunc_chdl_funarg1(int num);
static int setarrayfunc_chdl_funarg2(int num);

EXPORTCH int setarrayfunc_chdl(void *varg) {
  ChVaList_t ap;
  int retval;
  int i, n;
  pfuncArr_t parr_ch, parr_c = NULL;

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

  /* get Ch array */
  parr_ch = Ch_VaArg(interp, ap, pfuncArr_t);
  if(parr_ch != NULL) {
    /* save Ch array */
    for(i = 0; i < n; i++) {
      setarrayfunc_chdl_funptr[i] = (int (*)(int))parr_ch[i];
    }

    /* assign C function to the C array */
    setarrayfunc_chdl_funarg[0] = setarrayfunc_chdl_funarg0;
    setarrayfunc_chdl_funarg[1] = setarrayfunc_chdl_funarg1;
    setarrayfunc_chdl_funarg[2] = setarrayfunc_chdl_funarg2;
    /* ... up to MAXNUM */

    /* replace the Ch array with the C one,
       the NULL pointer can't be replaced */
    parr_c = (pfuncArr_t)setarrayfunc_chdl_funarg;
  }

  /* pass the C array with members of pointers to C functions
     instead of the Ch one, the NULL pointer will not be replaced */
  retval = setarrayfunc(n, parr_c);

  Ch_VaEnd(interp, ap);
  return retval;
}

static int setarrayfunc_chdl_funarg0(int num) {
  int retval;

  Ch_CallFuncByAddr(interp, (void*)setarrayfunc_chdl_funptr[0], &retval, num);
  return retval;
}

static int setarrayfunc_chdl_funarg1(int num) {
  int retval;

  Ch_CallFuncByAddr(interp, (void*)setarrayfunc_chdl_funptr[1], &retval, num);
  return retval;
}

static int setarrayfunc_chdl_funarg2(int num) {
  int retval;

  Ch_CallFuncByAddr(interp, (void*)setarrayfunc_chdl_funptr[2], &retval, num);
  return retval;
}
