#include <stdlib.h>
#include "stack-c.h"
#include "api_scilab.h"
#include "Scierror.h"
#include "sciprint.h"
#include <limits.h>

#include "RasterCalc.h"
#include "Erreur.h"


/********************************************
 * SCILAB function : RasterFindTransition   *
 ********************************************/

int gtw_RasterFindTransition ( char * fname )
{
    int m,n,l;
    int HandleFlowDir,HandleRaster,root,nitmax;
    float a, b;
    int nfound;
    int * CELLS;
    int un=1;

    CheckRhs(6,6);
    CheckLhs(1,1);
    
    /* Variable HandleRaster */

    GetRhsVar(1,"i",&m,&n,&l);
    CheckScalar(1,m,n);
    HandleRaster = *istk(l);

    /* Variable HandleFlowDir */

    GetRhsVar(2,"i",&m,&n,&l);
    CheckScalar(2,m,n);
    HandleFlowDir = *istk(l);

    /* Variable a */

    GetRhsVar(3,"r",&m,&n,&l);
    CheckScalar(3,m,n);
    a = *sstk(l);

    /* Variable b */

    GetRhsVar(4,"r",&m,&n,&l);
    CheckScalar(4,m,n);
    b = *sstk(l);

    /* Variable root */

    GetRhsVar(5,"i",&m,&n,&l);
    CheckScalar(5,m,n);
    root = *istk(l);

    /* Variable nitmax */

    GetRhsVar(6,"i",&m,&n,&l);
    CheckScalar(6,m,n);
    nitmax = *istk(l);

    if(nitmax<=0)
        nitmax = INT_MAX;

    /* Appel a l'API */

	nfound = 0;
	
    if( !(CELLS = (int *) malloc(nfound*sizeof(int)) ) )
        Scierror(999,"gtw_RasterFindTransition : echec de l'allocation dans l'interface\n");

    if ( RasterFindTransition ( HandleRaster ,
                               HandleFlowDir ,
                               & a,
                               & b,
                               & root,
                               & nitmax,
                               & nfound,
                               & CELLS ) )
        Scierror (999, GetErreur());

    CreateVarFromPtr ( Rhs + 1 , "i", & nfound , & un , & CELLS );
    LhsVar(1) = Rhs + 1;

    free(CELLS);

    return(0);
}

/********************************************
 * SCILAB function : GetRasterValue         *
 ********************************************/

int gtw_GetRasterValue ( char * fname )
{
    int m,n,l;
    int HandleRaster,ncells;
    int * CELLS;
    float * VALUES ;

    CheckRhs(2,2);
    CheckLhs(1,1);

    /* Variable HandleRaster */

    GetRhsVar(1,"i",&m,&n,&l);
    CheckScalar(1,m,n);
    HandleRaster = *istk(l);

    /* Variable CELLS */

    GetRhsVar(2,"i",&m,&n,&l);
    CELLS = istk(l);

    ncells = m*n;

    if( !(VALUES = (float *) malloc(ncells*sizeof(float)) ) )
        Scierror(999,"gtw_GetRasterValue : echec de l'allocation dans l'interface\n");

    /* Appel ÃƒÂ  l'API */

    if ( GetRasterValue ( HandleRaster , CELLS , ncells , & VALUES ) )
        Scierror(999,GetErreur());

    /* CrÃƒÂ©ation de la variable VALUES sur le stack */

    CreateVarFromPtr ( Rhs + 1 , "r", & m, & n , & VALUES );
    LhsVar(1) = Rhs + 1;

    free(VALUES);

    return(0);
}

/********************************************
 * SCILAB function : GetRasterRow           *
 ********************************************/

int gtw_GetRasterRow ( char * fname )
{
    int m,n,l;
    int HandleRaster,row;
	int ncols;
    float * ptrRow;
	int un = 1;
	
    CheckRhs(2,2);
    CheckLhs(1,1);

    /* Variable HandleRaster */

    GetRhsVar(1,"i",&m,&n,&l);
    CheckScalar(1,m,n);
    HandleRaster = *istk(l);

    /* Variable row */

    GetRhsVar(2,"i",&m,&n,&l);
    row = *istk(l);
	
    /* Appel à l'API */

    if ( GetRasterRowAddr ( HandleRaster , row , & ncols , & ptrRow ) )
        Scierror(999,GetErreur());

    /* Création du vecteur ligne sur le stack */

    CreateVarFromPtr ( Rhs + 1 , "r", & un, & ncols , & ptrRow );
    LhsVar(1) = Rhs + 1;

    return(0);
}


/********************************************
 * SCILAB function : PutRasterValue         *
 ********************************************/

int gtw_PutRasterValue (   char * fname )
{
        int m, n, l,mc,nc,mv,nv,ncells;
        int HandleRaster;
        int * CELLS;
        float * VALUES;

    	CheckRhs(3,3);
		CheckLhs(0,1);

        /* Variable HandleRaster */

	GetRhsVar(1,"i",&m,&n,&l);
	CheckScalar(1, m, n);
	HandleRaster = *istk(l);

        /* Variable CELLS */

	GetRhsVar(2,"i",&mc,&nc,&l);
	CELLS = istk(l);
    ncells = mc*nc;

        /* Variable VALUES */

	GetRhsVar(3,"r",&mv,&nv,&l);
        CheckDimProp(2,3,mc!=mv);
        CheckDimProp(2,3,nc!=nv);
        VALUES = sstk(l);

        /* Appel Ã  l'API*/

        if( PutRasterValue ( HandleRaster, ncells, CELLS, VALUES ) )
            Scierror(999,GetErreur());

        return(0);
}

/********************************************
 * SCILAB function : PutRasterRow           *
 ********************************************/

int gtw_PutRasterRow ( char * fname )
{
    int m,n,l;
    int HandleRaster;
	int nv,row;
	float * VALUES;
	
    CheckRhs(3,3);
    CheckLhs(0,1);

    /* Variable HandleRaster */

    GetRhsVar(1,"i",&m,&n,&l);
    CheckScalar(1,m,n);
    HandleRaster = *istk(l);

    /* Variable row */

    GetRhsVar(2,"i",&m,&n,&l);
    row = *istk(l);
	
	/* Variable VALUES */
	
	GetRhsVar(3,"r",&m,&n,&l);
    CheckVector(3,m,n);
	nv=m*n;
    VALUES = sstk(l);
	
    /* Appel à l'API */

    if ( PutRasterRow ( HandleRaster , row , nv , VALUES ) )
        Scierror(999,GetErreur());

    return(0);
}


/********************************************
 * SCILAB function : sci_RasterCDF          *
 ********************************************/

int gtw_RasterCDF (   char * fname )
{
        int m, n, l,mf,nf,nfreq,N;
        int HandleRaster,HandleMask;
	int un=1;
        float * FREQ;
        float * FVALUES;

    	CheckRhs(3,3);
		CheckLhs(2,2);

        /* Variable HandleRaster */

	GetRhsVar(1,"i",&m,&n,&l);
	CheckScalar(1, m, n);
	HandleRaster = *istk(l);

	/* Variable HandleMask */

	GetRhsVar(2,"i",&m,&n,&l);
	CheckScalar(2, m, n);
	HandleMask = *istk(l);

	/* Variable FREQ */

	GetRhsVar(3,"r",&mf,&nf,&l);
	FREQ = sstk(l);
    nfreq = mf*nf;

    if( !(FVALUES = (float *) malloc(nfreq*sizeof(float)) ) )
        Scierror(999,"gtw_RasterCDF : echec de l'allocation dans l'interface\n");

    /* Appel Ã  l'API*/

    if( RasterCDF ( HandleRaster , HandleMask , nfreq , FREQ , & FVALUES , & N) )
		Scierror(999,GetErreur());
		
	/* Creation de la variable FVALUES sur le stack */

    CreateVarFromPtr ( Rhs + 1 , "r", & mf, & nf , & FVALUES );
    LhsVar(1) = Rhs + 1;

    CreateVar(Rhs + 2,"i",&un,&un,&l);
    *istk(l) = N ;
    LhsVar(2) = Rhs +2 ;

    free(FVALUES);

    return(0);
}

/********************************************
 * SCILAB function : RasterMSE              *
 ********************************************/

int gtw_RasterMSE (   char * fname )
{
        int m, n, l;
        int HandleRaster1,HandleRaster2,HandleMask;
        float MSE ;
		int un = 1;

    	CheckRhs(3,3);
		CheckLhs(1,1);

        /* Variable HandleRaster1 */

	GetRhsVar(1,"i",&m,&n,&l);
	CheckScalar(1, m, n);
	HandleRaster1 = *istk(l);

     /* Variable HandleRaster2 */

	GetRhsVar(2,"i",&m,&n,&l);
	CheckScalar(2, m, n);
	HandleRaster2 = *istk(l);
	
	/* Variable HandleMask */

	GetRhsVar(3,"i",&m,&n,&l);
	CheckScalar(3, m, n);
	HandleMask = *istk(l);

    /* Appel à l'API */

    if( RasterMSE ( HandleRaster1 , HandleRaster2 , HandleMask , & MSE ) )
		Scierror(999,GetErreur());
		
	/* Creation de la variable MSE sur le stack */

    CreateVar(Rhs + 1,"r",&un,&un,&l);
    *sstk(l) = MSE ;
	LhsVar(1) = Rhs + 1;

    return(0);
}

/********************************************
 * SCILAB function : FlagCatchmentCells     *
 ********************************************/

int gtw_FlagCatchmentCells (   char * fname )
{
        int m, n, l;
        int HandleRaster,HandleFlowDir,nup,nnodes,nixupnodes;
		int * NODES , * IXUPNODES ;
		int	 * BB;
		int bbsize = 4;
		int un = 1;
        float flag ;
		int root ;

    	CheckRhs(5,5);
	CheckLhs(0,3);

	/* Variable HandleFlowDir */

	GetRhsVar(1,"i",&m,&n,&l);
	CheckScalar(1, m, n);
	HandleFlowDir = *istk(l);
	
	/* Variable root */

	GetRhsVar(2,"i",&m,&n,&l);
	CheckScalar(2, m, n);
	root = *istk(l);
	
	/* Variable HandleRaster */

	GetRhsVar(3,"i",&m,&n,&l);
	CheckScalar(3, m, n);
	HandleRaster = *istk(l);

	/* Variable flag */

	GetRhsVar(4,"r",&m,&n,&l);
	CheckScalar(4, m, n);
	flag = *sstk(l);
	
	/* Variable NODES */

	GetRhsVar(5,"i",&m,&n,&l);
	nnodes = m*n;
    NODES = istk(l);
	
	/* Appel à l'API */

	BB = (int *) malloc ( bbsize * sizeof(int) );
		
    if( FlagCatchmentCells ( HandleRaster , HandleFlowDir , root , flag , nnodes, NODES , & BB , & nup , & IXUPNODES , & nixupnodes ) )
		Scierror(999,GetErreur());
		
    CreateVar(Rhs + 1,"i",&un,&un,&l);
	*istk(l) = nup ;
	LhsVar(1) = Rhs +1 ;

    CreateVarFromPtr ( Rhs + 2 , "i", & un , & bbsize , & BB );
	LhsVar(2) = Rhs + 2;

	CreateVarFromPtr ( Rhs + 3 , "i", & un , & nixupnodes , & IXUPNODES );
	LhsVar(3) = Rhs + 3;
	
	free(IXUPNODES);
	free(BB);
		
	return(0);
	
}	
	 
