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

#include "Mesh.h"
#include "Erreur.h"

/********************************************
 * SCILAB function : SegmentationTopo       *
 ********************************************/

int gtw_SegmentationTopo ( char * fname )
{
	int HandleFlowDir,HandleRaster,exu,nconstrain,nnodes;
	double cumul;
	int * NODES, * CONSTRAIN;
	double * WEIGHTS ;
	int m, n, l;
	int un=1;

	CheckRhs(5,5);
	CheckLhs(2,2);

	/* Variable HandleFlowDir */

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

	/* Variable HandleRaster */

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

	GetRhsVar(3,"i",&m,&n,&l);
	CheckScalar(3, m, n);
	exu = *istk(l);
	
	/* Variable cumul */

	GetRhsVar(4,"d",&m,&n,&l);
	CheckScalar(4, m, n);
	cumul = *stk(l);

	/* Variable CONSTRAIN */

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

	if ( SegmentationTopo ( HandleFlowDir , HandleRaster , exu , cumul , CONSTRAIN , nconstrain , & nnodes , & NODES , & WEIGHTS ) )	
		Scierror (999, GetErreur());

	/* Création de la variable de sortie sur le stack : liste de noeuds de la segmentation */

	CreateVarFromPtr ( Rhs + 1 , "i", & un , & nnodes , & NODES );
	LhsVar(1) = Rhs + 1;

	CreateVarFromPtr ( Rhs + 2 , "d", & un , & nnodes , & WEIGHTS );
	LhsVar(2) = Rhs + 2;
	
	free(NODES);
	free(WEIGHTS);
	
	return(0);
	
}

/***********************************************
 * SCILAB function : MakeFlowLineThroughPoint  *
 ***********************************************/

int gtw_MakeFlowLineThroughPoint ( char * fname )
{
	int HandleFlowDir,HandleRaster,exu,throughpoint,length;
	int * FlowLine;
	int m, n, l;
	int un=1;

	CheckRhs(4,4);
	CheckLhs(1,1);

	/* Variable HandleFlowDir */

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

	/* Variable HandleRaster */

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

	GetRhsVar(3,"i",&m,&n,&l);
	CheckScalar(3, m, n);
	exu = *istk(l);
	
	/* Variable throughpoint */

	GetRhsVar(4,"i",&m,&n,&l);
	CheckScalar(4, m, n);
	throughpoint = *istk(l);
	
	/* Appel à l'API */

	if ( MakeFlowLineThroughPoint ( HandleFlowDir , HandleRaster , exu , throughpoint , & FlowLine , & length ) )	
		Scierror (999, GetErreur());

	/* Création de la variable de sortie sur le stack : liste de noeuds de la segmentation */

	CreateVarFromPtr ( Rhs + 1 , "i", & length , & un , & FlowLine );
	LhsVar(1) = Rhs + 1;

	free(FlowLine);
	
	return(0);	
}

/********************************************
 * SCILAB function : sci_GetCatchmentSum    *
 ********************************************/

int gtw_GetCatchmentSum ( char * fname )
{
	int m, n, l;
	int un = 1;
    int HandleFlowDir,HandleRaster,cell,nupnodes,nixupnodes;
	float Sum;
	int * UPNODES , * IXUPNODES ;
	int	* BB;
	int bbsize = 4;
	
	CheckRhs(4,4);
	CheckLhs(1,3);

	/* Variable HandleFlowDir */

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

	/* Variable cell */

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

	GetRhsVar(3,"i",&m,&n,&l);
	nupnodes = m*n;
    UPNODES = istk(l);
	
	/* Variable HandleRaster */

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

	BB = (int *) malloc ( bbsize * sizeof(int) );
	
        /* Appel a l'API */

        if ( GetCatchmentSum ( HandleFlowDir , HandleRaster , cell , nupnodes , UPNODES , & BB , & Sum , & IXUPNODES , & nixupnodes ) )
            Scierror(999,GetErreur());

    CreateVar(Rhs + 1,"r",&un,&un,&l);
	*sstk(l) = Sum ;
	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);
	FreePtr(UPNODES);
	
    return(0);
}

/********************************************
 * SCILAB function : sci_GetCatchmentSum1   *
 ********************************************/

int gtw_GetCatchmentSum1 ( char * fname )
{
	int m, n, l;
	int un = 1;
    int HandleFlowDir,cell,nupnodes,nixupnodes;
	float Sum;
	int * UPNODES , * IXUPNODES ;
	int	* BB;
	int bbsize = 4;
	
	CheckRhs(3,3);
	CheckLhs(1,3);

	/* Variable HandleFlowDir */

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

	/* Variable cell */

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

	GetRhsVar(3,"i",&m,&n,&l);
	nupnodes = m*n;
    UPNODES = istk(l);

	BB = (int *) malloc ( bbsize * sizeof(int) );
	
        /* Appel a l'API */

        if ( GetCatchmentSum1 ( HandleFlowDir , cell , nupnodes , UPNODES , & BB , & Sum , & IXUPNODES , & nixupnodes ) )
            Scierror(999,GetErreur());

    CreateVar(Rhs + 1,"r",&un,&un,&l);
	*sstk(l) = Sum ;
	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);
	FreePtr(UPNODES);
	
    return(0);
}

/********************************************
 * SCILAB function : sci_OptimMeshVariance  *
 ********************************************/

int gtw_OptimMeshVariance ( char * fname )
{
	int m, n, l;
	int un = 1;
	int * NEWNODES , * NODES , * CNT ;
	double * WEIGHTS ;
	double damper ;
    int HandleFlowDir,HandleCumulRaster,HandlePkRaster,nnodes;
	
	CheckRhs(6,6);
	CheckLhs(2,2);

	/* Variable HandleFlowDir */

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

	/* Variable HandleCumulRaster */

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

	GetRhsVar(3,"i",&m,&n,&l);
	CheckScalar(3,m,n);
    HandlePkRaster = *istk(l);
	
	/* Variable NODES */

	GetRhsVar(4,"i",&m,&n,&l);
	CheckVector(4,m,n);
	nnodes = m*n ;
    NODES = istk(l);

	/* Variable CNT */

	GetRhsVar(5,"i",&m,&n,&l);
	CheckVector(5,m,n);
	CheckDimProp(4,5,m*n != nnodes) ;
    CNT = istk(l);

	/* Variable damper */

	GetRhsVar(6,"d",&m,&n,&l);
	CheckScalar(6,m,n);
    damper = *stk(l);
	
	/* Appel a l'API */

        if ( OptimMeshVariance ( HandleFlowDir , HandleCumulRaster , HandlePkRaster , nnodes , NODES , CNT , damper , & NEWNODES , & WEIGHTS ) )
            Scierror(999,GetErreur());
	
	/* Création du vecteur des nouveaux noeuds sur le stack */
	
	CreateVarFromPtr ( Rhs + 1 , "i", & un , & nnodes , & NEWNODES );
	LhsVar(1) = Rhs + 1;
	
	CreateVarFromPtr ( Rhs + 2 , "d", & un , & nnodes , & WEIGHTS );
	LhsVar(2) = Rhs + 2;	
	
	free(NEWNODES);
	free(WEIGHTS);
		
    return(0);
}

/********************************************
 * SCILAB function : sci_MapCatchmentMean   *
 ********************************************/

int gtw_MapCatchmentMean ( char * fname )
{
	int m, n, l;
	int un = 1;
    int HandleFlowDir,HandleWeightRaster,HandleCumulRaster;
	int outlet, ninlets;
	int * INLETS ;
	
	CheckRhs(5,5);
	CheckLhs(0,1);

	/* Variable HandleFlowDir */

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

	/* Variable outlet */

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

	GetRhsVar(3,"i",&m,&n,&l);
	ninlets = m*n;
    INLETS = istk(l);

	/* Variable HandleCumulRaster */

	GetRhsVar(4,"i",&m,&n,&l);
	CheckScalar(4,m,n);
    HandleCumulRaster = *istk(l);
	
	/* Variable HandleWeightRaster */

	GetRhsVar(5,"i",&m,&n,&l);
	CheckScalar(5,m,n);
    HandleWeightRaster = *istk(l);
	
    /* Appel a l'API */

        if ( MapCatchmentMean ( HandleFlowDir , HandleWeightRaster , outlet , HandleCumulRaster , ninlets , INLETS ) )
            Scierror(999,GetErreur());

    return(0);
}

/********************************************
 * SCILAB function : sci_MapCatchmentSum    *
 ********************************************/

int gtw_MapCatchmentSum ( char * fname )
{
	int m, n, l;
	int un = 1;
    int HandleFlowDir,HandleWeightRaster,HandleCumulRaster;
	int outlet, ninlets;
	int * INLETS ;
	
	CheckRhs(5,5);
	CheckLhs(0,1);

	/* Variable HandleFlowDir */

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

	/* Variable outlet */

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

	GetRhsVar(3,"i",&m,&n,&l);
	ninlets = m*n;
    INLETS = istk(l);

	/* Variable HandleCumulRaster */

	GetRhsVar(4,"i",&m,&n,&l);
	CheckScalar(4,m,n);
    HandleCumulRaster = *istk(l);
	
	/* Variable HandleWeightRaster */

	GetRhsVar(5,"i",&m,&n,&l);
	CheckScalar(5,m,n);
    HandleWeightRaster = *istk(l);
	
    /* Appel a l'API */

        if ( MapCatchmentSum ( HandleFlowDir , HandleWeightRaster , outlet , HandleCumulRaster , ninlets , INLETS ) )
            Scierror(999,GetErreur());

    return(0);
}

/********************************************
 * SCILAB function : sci_MapCatchmentSum1   *
 ********************************************/

int gtw_MapCatchmentSum1 ( char * fname )
{
	int m, n, l;
	int un = 1;
    int HandleFlowDir,HandleCumulRaster;
	int outlet, ninlets ;
	int * INLETS ;
	
	CheckRhs(4,4);
	CheckLhs(0,1);

	/* Variable HandleFlowDir */

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

	/* Variable outlet */

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

	GetRhsVar(3,"i",&m,&n,&l);
	ninlets = m*n;
    INLETS = istk(l);

	/* Variable HandleCumulRaster */

	GetRhsVar(4,"i",&m,&n,&l);
	CheckScalar(4,m,n);
    HandleCumulRaster = *istk(l);
	
    /* Appel a l'API */

        if ( MapCatchmentSum1 ( HandleFlowDir , outlet , HandleCumulRaster , ninlets , INLETS ) )
            Scierror(999,GetErreur());

    return(0);
}
