/* A small note on how the arithmetic is being done.
The integers are stored as 16.16 numbers with the first 16 bits representing the integer part and the last 16 bits
representing the fractional part.
To convert from normal fraction to our format LSHFT by 16
To convert from our format to normal mode--right shift by 16
The Features are all fractional number.Hence they are defined as unisgned shorts and can simply take the lower 16 bits of the 
integer that we have defined above.(the features are all normalized and thus lie between zero and one
The Hidden node outputs are also between zero and one--since we have used a sigmoid thresholding function
The Outputs are however not between zero and one--and so they are stored as integers

The original points that we get from the glyph and those that are stored in the pointinfo structure are not in this format--they are in
the normal integer format.
This comment probably needs to move elsewhere
*/

#include "common.h"
#include "solefeat.h"
#include "runnet.h"

//This stores the number of supported characters

extern const int g_cSupportChar ;

extern int * RunSoleNets(int * pMem,BOOL bGuide);

BOOL GetSoleAltList(int *aProb, ALTERNATES *pAlt);

BOOL GetSoleNetValues(int *icSoleNetMem,int *icSoleFeat,int *icSoleOutput,int bGuide);


/**********************************************************************\
* SoleRecog--Top Level Function for Calling Sole
*
* 
*
* History:
*  Originally written  -by- Angshuman Guha aguha
* Changed by Manish Goyal--mango--09/15/2001
*Explanation of parameters
*pGlyph--Pointer to the glpyh of ink being passed
*pGuide--Pointer to guide being passed--used only if the bGuide flag is set
*pAlt--returns the final character alt list from Sole Recognition
*bGuide--Boolean indicating that the guide has been set.If the guide is set,Sole 
		  calls the net for the guide(using the guide features)If not set,the Net without
		  the guide features is called.
\**************************************************************************/


BOOL SoleRecog(GLYPH *pGlyph, GUIDE *pGuide, ALTERNATES *pAlt,BOOL bGuide)
{
	int cStroke; //Counts the total number of strokes in the glyph being passed
	RREAL *pOutput=NULL; //Denotes the output nodes of the sole net
	int icSoleNetMem;  //Memory required by the Sole Net
	int  icSoleFeat;    //Number of features for the Sole Net
	int icSoleOutput;        //Number of outputs in the net supported by sole
	int nFeat; //Number of features that are generated by the featurizer
	RREAL *pMem; //Pointer to the Sole Net inputs/outputs
	BOOL retval=FALSE; //Stores the return value of the function
	
	// sanity check
	if (!pGlyph || !pAlt)
		return FALSE;

	//First we need to get the memory required and the number of input features for the Sole Nets

	if (!GetSoleNetValues(&icSoleNetMem,&icSoleFeat,&icSoleOutput,bGuide))
			return FALSE;

	//Allocate space for the net to be run

	if (!(pMem = ExternAlloc(icSoleNetMem * sizeof(*pMem))))
		    goto fail;



	//Depending on whether or not the guide is present the number of input features will vary
	//We now call the function to figure out what the net parameters are

	//Count the number of strokes
	cStroke=CframeGLYPH(pGlyph);

	if (cStroke <= 0)
		goto fail;

	// featurize!
	nFeat=SoleFeaturize(pGlyph, pGuide, pMem,bGuide);

	if (!nFeat)
		goto fail;

	//We now need to make sure that we are running the correct net

	
	//First,make sure that the number of feature vectors are equal to the number of input features for the Net
	ASSERT(nFeat == icSoleFeat);


	//Second,make sure that the number of outputs match
	ASSERT(g_cSupportChar==icSoleOutput); 

	//Run the sole net 

	pOutput=RunSoleNets(pMem,bGuide);


	if (!pOutput)
		goto fail;
	

	// put the results in the passed in alt-list
	if (!GetSoleAltList(pOutput, pAlt))
		goto fail;

	//The function has succeeded--the return value has to be set to 1
	retval=TRUE;

fail:
	ExternFree(pMem);
	return retval;

}
