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

/*
 * WFDB_annopen.c
 *
 * Open WFDB annotation files
 *
 */
 
/* Define order of input variables */
#define RECORD_INPUT 0
#define ANNINFO_INPUT 1

void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[] )
{

  int err_code;
  char *record;
  unsigned int record_length, i, namefield, statfield, anninfo_size;
  WFDB_Anninfo *a;
  mxArray *field;
  unsigned int field_size;
  char *field_text;

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

  /* RECORD input must be a string. */
  if (mxIsChar(prhs[RECORD_INPUT]) != 1)
    mexErrMsgTxt("RECORD must be a string.");

  /* Get the length of the RECORD string and allocate memory. */
  record_length = (mxGetM(prhs[RECORD_INPUT]) *
		   mxGetN(prhs[RECORD_INPUT])) + 1;
  record = mxCalloc(record_length, sizeof(char));

  /* Get the RECORD string */
  mxGetString(prhs[RECORD_INPUT], record, record_length);

  /* ANNINFO input must be a structure. */
  if (!mxIsStruct(prhs[ANNINFO_INPUT]))
    mexErrMsgTxt("ANNINFO must be a structure.");

  /* Get the size of the ANNINFO structure and allocate memory. */
  anninfo_size = (mxGetM(prhs[ANNINFO_INPUT]) *
		  mxGetN(prhs[ANNINFO_INPUT]));
  a = (WFDB_Anninfo *)mxCalloc(anninfo_size, sizeof(WFDB_Anninfo));

  /* Make Anninfo structures from ANNINFO */
  namefield = mxGetFieldNumber(prhs[ANNINFO_INPUT], "name");
  statfield = mxGetFieldNumber(prhs[ANNINFO_INPUT], "stat");
  for (i = 0; i < anninfo_size; i++)
    {
      field = mxGetFieldByNumber(prhs[ANNINFO_INPUT], i, namefield);
      field_size = mxGetM(field) * mxGetN(field) + 1;
      a[i].name = mxCalloc(field_size, sizeof(char));
      mxGetString(field, a[i].name, field_size);
      field = mxGetFieldByNumber(prhs[ANNINFO_INPUT], i, statfield);
      field_size = mxGetM(field) * mxGetN(field) + 1;
      field_text = mxCalloc(field_size, sizeof(char));
      mxGetString(field, field_text, field_size);
      if (strcmp(field_text, "WFDB_WRITE") == 0)
	a[i].stat = WFDB_WRITE;
      else if (strcmp(field_text, "WFDB_READ") == 0)
	a[i].stat = WFDB_READ;
      else if (strcmp(field_text, "WFDB_AHA_READ") == 0)
	a[i].stat = WFDB_AHA_READ;
      else if (strcmp(field_text, "WFDB_AHA_WRITE") == 0)
	a[i].stat = WFDB_AHA_WRITE;
      else
	{
	  mexPrintf("%s\n", field_text);
	  mexErrMsgTxt("Unknown stat");
	}
    }

  /* Open annotator file(s) */
  err_code = annopen(record, a, anninfo_size);
  if (err_code < 0)
    switch(err_code)
      {
      case -3:
	mexErrMsgTxt("Failure: unable to open input annotation file");
      case -4:
	mexErrMsgTxt("Failure: unable to open output annotation file");
      case -5:
	mexErrMsgTxt("Failure: illegal stat specified for annotation file");
      default :
	mexErrMsgTxt("Failure. Unknown error.");
      } 

}
