#include "mex.h"
#include "matrix.h"
#include "wfdb/wfdb.h"
#include <string.h>

/*
 * WFDB_putann.c
 *
 */
 
/* Define order of input variables */
#define ANNOTATOR_INPUT 0
#define ANNOTATION_INPUT 1

void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{
  unsigned int mrows, ncols, err_code, nann;
  WFDB_Annotator annotator;
  WFDB_Annotation annotation;
  unsigned int timenum, anntypnum, subtypnum, channum, numnum, auxnum;
  mxArray *field;
  unsigned int aux_length;
  char *aux, *aux_field;

  /* Check for proper number of arguments. */
  if (nrhs != 2)
    mexErrMsgTxt("Two inputs required.");

  /* Get annotator number */
  annotator = (WFDB_Annotator)*mxGetPr(prhs[ANNOTATOR_INPUT]);

  /* Get size of annotation(s) */
  mrows = mxGetM(prhs[ANNOTATION_INPUT]);
  ncols = mxGetN(prhs[ANNOTATION_INPUT]);

  timenum = mxGetFieldNumber(prhs[ANNOTATION_INPUT], "time");
  anntypnum = mxGetFieldNumber(prhs[ANNOTATION_INPUT], "anntyp");
  subtypnum = mxGetFieldNumber(prhs[ANNOTATION_INPUT], "subtyp");
  channum = mxGetFieldNumber(prhs[ANNOTATION_INPUT], "chan");
  numnum = mxGetFieldNumber(prhs[ANNOTATION_INPUT], "num");
  auxnum = mxGetFieldNumber(prhs[ANNOTATION_INPUT], "aux");
  for (nann = 0; nann < (mrows*ncols); nann++)
    {
      field = mxGetFieldByNumber(prhs[ANNOTATION_INPUT], nann, timenum);
      annotation.time = *mxGetPr(field);

      field = mxGetFieldByNumber(prhs[ANNOTATION_INPUT], nann, anntypnum);
      annotation.anntyp = *mxGetPr(field);

      field = mxGetFieldByNumber(prhs[ANNOTATION_INPUT], nann, subtypnum);
      annotation.subtyp = *mxGetPr(field);

      field = mxGetFieldByNumber(prhs[ANNOTATION_INPUT], nann, channum);
      annotation.chan = *mxGetPr(field);

      field = mxGetFieldByNumber(prhs[ANNOTATION_INPUT], nann, numnum);
      annotation.num = *mxGetPr(field);

      field = mxGetFieldByNumber(prhs[ANNOTATION_INPUT], nann, auxnum);
      if ((mxGetM(field)*mxGetN(field)) == 0)
	annotation.aux = NULL;
      else
	{
	  aux_length = (mxGetM(field) * mxGetN(field)) + 1;
	  aux = mxCalloc(aux_length, sizeof(char));
	  mxGetString(field, aux, aux_length);
	  aux_field = mxCalloc(aux_length + 1, sizeof(char));
	  aux_field[0] = aux_length;
	  strcat(aux_field, aux);
	  annotation.aux = aux_field;
	}

      if ((err_code = putann(annotator, &annotation)) < 0)
	switch (err_code)
	  {
	  case -1:
	    mexErrMsgTxt("Failure: write error");
	  case -2:
	    mexErrMsgTxt("Failure: incorrect annotator number specified");
	  default:
	    mexPrintf("Error code: %d\n", err_code);
	    mexErrMsgTxt("Unknown error");
	  }
      if (annotation.aux != NULL) {
	  mxFree(aux);
	  mxFree(aux_field);
      }
    }

}
