/*
 * ReadCategory.c
 *
 *  Created on: 2009/03/04
 *      Author: H.Shouno
 *  This is a wrapper program for read part of the rwcon() in Neocog.c by Prof.Fukushima.
 *
 */

#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include "mex.h"
#include "neocog_proto.h"

void mexFunction( int nlhs, mxArray *lhs[], int nrhs, const mxArray *rhs[] );

/*
 * Input & Output Arguments
 */

#define CAT_MAP_OUT	lhs[0] // output CELL matrix a{nKs, nKc}
#define FNAME_IN	rhs[0] // file name

#define MAXSTRING 65536
#define KSMAX 512 // upper limit of Us Planes
#define LMAX 32   // upper limit of stages.
#define LH   4    // recongition layer (assumed in Neocog.c) : Todo 

//
// Size information is lacked in  'connect.dat'. Thus we should assume size for reading connection.
// Todo: size information should be embedded in data format
//
static	double	As[]	= {     3.4,  3.4,  3.4,  4.9   };	// radius of connect. as, As[L]
//
//                            UG S1 C1 S2 C2 S3 C3 S4 C4
//
static	int	Nc[]	= {   71,   37,   21,   13,    1};	// size of Uc(or U0) cell-plane, Nc[L+1]
static	int	Ns[]	= {      68,   38,   22,    5   };	// size of Us cell-planes,  Ns[L]


// Gateway function
void mexFunction( int nlhs, mxArray *lhs[], int nrhs, const mxArray *rhs[] )
{
	char fname[MAXSTRING];
	double ****a[LH];
	double *b[LH];
	int *coefp; // Assume 32bit int class
	int Mas[LH], *cat;
	int Na[LMAX];           // size of coefficients a[]
	int Kc[LMAX], Ks[LMAX]; // number of Uc[], and Us[] planes.
	int i, j, l, ll;
	FILE *ifp; // may be dummy, since fopen() and fclose() pair procedure is carried out.
	struct stat st;

	if( nlhs != 1 )		mexErrMsgTxt( "ReadCategory() requires 1 output: Cat = ReadConnect( fname )" );
	if( nrhs != 1 )		mexErrMsgTxt( "ReadCategory() requires 1 input: Cat = ReadConnect( fname )" );

	if( mxIsChar( FNAME_IN ) != 1 )	mexErrMsgTxt( "File name must be a string" );
	mxGetString( FNAME_IN, fname, MAXSTRING-1 );
	if( stat( fname, &st ) != 0 ){
		mexPrintf( "File '%s' does not exist. ", fname );
		mexErrMsgTxt( "stat() was failed." );
	}
	l = LH;
	ll = 0; // Read All layers for rwcon().
	
	for( i = 0 ; i <= l ; i++ ){
		// from Neocog.c
		if ((Nc[i] + Ns[i]) % 2 == 0) {					// alligned (Na is odd)
			Na[i] = ((int) As[i]) * 2 + 1;
		} else {							// staggered (Na is even)
			Na[i] = ((int) (As[i] + 0.5)) * 2;
			// Exactly, Na should be: (na-0.5)^2 + 0.5^2 = A^2;  na = 0.5 + sqrt(A^2 - 0.5^2);  Na = na * 2;
		}
	}

	rwcon( ifp, fname, a, b, &cat, Na, Kc, Ks, Mas, LH, ll );

	CAT_MAP_OUT = mxCreateNumericMatrix( Ks[LH-1], 1, mxINT32_CLASS, mxREAL );
	coefp = (int*)mxGetPr( CAT_MAP_OUT );   // assume 32bit int class
	memmove( coefp, cat, Ks[LH-1] * sizeof(int) );

	return;
}
