/*                                                                            *
 *   This file is part of the ESO SINFO Pipeline                              *
 *   Copyright (C) 2004,2005 European Southern Observatory                    *
 *                                                                            *
 *   This library is free software; you can redistribute it and/or modify     *
 *   it under the terms of the GNU General Public License as published by     *
 *   the Free Software Foundation; either version 2 of the License, or        *
 *   (at your option) any later version.                                      *
 *                                                                            *
 *   This program is distributed in the hope that it will be useful,          *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of           *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
 *   GNU General Public License for more details.                             *
 *                                                                            *
 *   You should have received a copy of the GNU General Public License        *
 *   along with this program; if not, write to the Free Software              *
 *   Foundation, 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA     *
 *                                                                           */
 
/*
 * $Author: amodigli $
 * $Date: 2009-06-05 06:06:11 $
 * $Revision: 1.5 $
 * $Name: not supported by cvs2svn $
 *
 */

/*-----------------------------------------------------------------------------
                                Includes
 -----------------------------------------------------------------------------*/

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif
#include<sinfo_msg.h>
#include<sinfo_absolute.h>
#include <cpl.h>
/*-----------------------------------------------------------------------------
                                Defines
 -----------------------------------------------------------------------------*/
static float  sqrarg ;
#define SQR(a) (sqrarg = (a) , sqrarg*sqrarg)
/*-----------------------------------------------------------------------------
                            Functions prototypes
 -----------------------------------------------------------------------------*/


/*----------------------------------------------------------------------------*/
/**
 * @defgroup sinfo_absolute_test  SINFO library unit tests
 */
/*----------------------------------------------------------------------------*/
/**@{*/

static cpl_error_code
sinfo_test_edge(void){

    /*Test all possible NULL param options */
    float* xdat = NULL;
    float* parlist = NULL;
    const int ndat=4;
    float slope=0;

    /* 1st test both null input: */
    slope=sinfo_new_edge(NULL, NULL) ;
    cpl_test_eq(slope, 0);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    parlist=cpl_calloc(ndat,sizeof(float)) ;
    slope=sinfo_new_edge(NULL, parlist) ;
    cpl_test_eq(slope, 0);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    xdat=cpl_calloc(ndat,sizeof(float)) ;
    slope=sinfo_new_edge(xdat, NULL) ;
    cpl_test_eq(slope, 0);
    cpl_test_error(CPL_ERROR_NULL_INPUT);


    /* For defined values we have the following cases:
     */

    /* case 1:
     * if ( xdat[0] <= parlist[0] ) return_parlist[2] ;
     * */
    xdat[0]=0;
    xdat[1]=1;
    xdat[2]=2;
    xdat[3]=3;

    parlist[0]=1;
    parlist[1]=2;
    parlist[2]=10;
    parlist[3]=20;

    slope=sinfo_new_edge(xdat, parlist) ;
    cpl_test_eq(slope, parlist[2]);
    cpl_test_error(CPL_ERROR_NONE);

    /* case 2:
     * if ( xdat[0] >  parlist[1] ) return_parlist[3] ;
     * */
    xdat[0]=3;
    xdat[1]=4;
    xdat[2]=5;
    xdat[3]=6;

    parlist[0]=1;
    parlist[1]=2;
    parlist[2]=10;
    parlist[3]=20;

    slope=sinfo_new_edge(xdat, parlist) ;
    cpl_test_eq(slope, parlist[3]);
    cpl_test_error(CPL_ERROR_NONE);


    /* case 3:
     *  if ( xdat[0] > parlist[0] && xdat[0] <= parlist[1] )
           return (xdat[0] - parlist[0]) * slope1 + parlist[2] ;
       * */
      xdat[0]=1;
      xdat[1]=0.5;
      xdat[2]=2;
      xdat[3]=3;

      parlist[0]=0;
      parlist[1]=1;
      parlist[2]=10;
      parlist[3]=20;
      float slope1=( parlist[3] - parlist[2] ) / ( parlist[1] - parlist[0] ) ;
      float result=(xdat[0] - parlist[0]) * slope1 + parlist[2] ;
      slope=sinfo_new_edge(xdat, parlist) ;
      cpl_test_eq(slope, result);
      cpl_test_error(CPL_ERROR_NONE);

      /* case 4:
          *  else I think this case is never found!!
          * */

    /* free memory */
    cpl_free(xdat);
    cpl_free(parlist);

    return cpl_error_get_code();

}

static cpl_error_code
sinfo_test_edge_deriv(void){


    /*Test all possible NULL param options */
    float* xdat = NULL;
    float* parlist = NULL;
    float* dervs = NULL;
    const int ndat=4;
    float slope=0;

    /* 1st test both null input: */
    sinfo_new_edge_deriv(NULL, NULL,NULL) ;
    cpl_test_eq(slope, 0);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    parlist=cpl_calloc(ndat,sizeof(float)) ;
    xdat=cpl_calloc(ndat,sizeof(float)) ;
    dervs=cpl_calloc(ndat,sizeof(float)) ;

    sinfo_new_edge_deriv(NULL, parlist,dervs) ;
    cpl_test_eq(slope, 0);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    sinfo_new_edge_deriv(xdat, NULL,dervs) ;
    cpl_test_eq(slope, 0);
    cpl_test_error(CPL_ERROR_NULL_INPUT);

    sinfo_new_edge_deriv(xdat, parlist,NULL) ;
    cpl_test_eq(slope, 0);
    cpl_test_error(CPL_ERROR_NULL_INPUT);


    /* For defined values we have the following cases:
     */

    /* case 1:
     * if ( xdat[0] <= parlist[0] ) return
     *  dervs[0] = 0. ;
        dervs[1] = 0. ;
        dervs[2] = 1. ;
        dervs[3] = 0. ;
     * ;
     * */
    xdat[0]=0;
    xdat[1]=1;
    xdat[2]=2;
    xdat[3]=3;

    parlist[0]=1;
    parlist[1]=2;
    parlist[2]=10;
    parlist[3]=20;

    sinfo_new_edge_deriv(xdat, parlist,dervs) ;
    cpl_test_eq(dervs[0], 0);
    cpl_test_eq(dervs[1], 0);
    cpl_test_eq(dervs[2], 1);
    cpl_test_eq(dervs[3], 0);
    cpl_test_error(CPL_ERROR_NONE);


    /* case 2:
     * if ( xdat[0] > parlist[0] ) return
     *  dervs[0] = 0. ;
        dervs[1] = 0. ;
        dervs[2] = 0. ;
        dervs[3] = 1. ;

     *  if ( xdat[0] > parlist[0] && xdat[0] <= parlist[1] )
           return (xdat[0] - parlist[0]) * slope1 + parlist[2] ;
     * */


    xdat[0]=3;
    xdat[1]=4;
    xdat[2]=5;
    xdat[3]=6;

    parlist[0]=1;
    parlist[1]=2;
    parlist[2]=10;
    parlist[3]=20;

    sinfo_new_edge_deriv(xdat, parlist,dervs) ;
    cpl_test_eq(dervs[0], 0);
    cpl_test_eq(dervs[1], 0);
    cpl_test_eq(dervs[2], 0);
    cpl_test_eq(dervs[3], 1);
    cpl_test_error(CPL_ERROR_NONE);


    /* case 3:
     * else if ( xdat[0] > parlist[0] && xdat[0] <= parlist[1] )
            return:
            dervs[0] = ( xdat[0] - parlist[1] ) * deriv1_slope1  ;
            dervs[1] = ( parlist[0] - xdat[0] ) * deriv1_slope1 ;
            dervs[2] = ( parlist[0] - xdat[0] ) / ( parlist[1] - parlist[0] ) + 1.;
            dervs[3] = ( xdat[0] - parlist[0] ) / ( parlist[1] - parlist[0] ) ;
     * */

    xdat[0]=1;
    xdat[1]=0.5;
    xdat[2]=2;
    xdat[3]=3;

    parlist[0]=0;
    parlist[1]=1;
    parlist[2]=10;
    parlist[3]=20;
    float deriv_slope1 =( parlist[3] - parlist[2] ) / SQR(parlist[1] - parlist[0]) ;
    float* result=cpl_calloc(ndat,sizeof(float)) ;
    result[0] = ( xdat[0] - parlist[1] ) * deriv_slope1  ;
    result[1] = ( parlist[0] - xdat[0] ) * deriv_slope1 ;
    result[2] = ( parlist[0] - xdat[0] ) / ( parlist[1] - parlist[0] ) + 1.;
    result[3] = ( xdat[0] - parlist[0] ) / ( parlist[1] - parlist[0] ) ;

    sinfo_new_edge_deriv(xdat, parlist,dervs) ;

    cpl_test_eq(dervs[0], result[0]);
    cpl_test_eq(dervs[1], result[1]);
    cpl_test_eq(dervs[2], result[2]);
    cpl_test_eq(dervs[3], result[3]);



    cpl_test_error(CPL_ERROR_NONE);

    /* case 4:
     *  else I think this case is never found!!
     * */

    /* free memory */
    cpl_free(xdat);
    cpl_free(parlist);
    cpl_free(dervs);
    cpl_free(result);

    return cpl_error_get_code();
}



static cpl_error_code
sinfo_test_lsqfit_edge(void){

    /*
    int
    sinfo_new_lsqfit_edge ( float * xdat,
                      int   * xdim,
                      float * ydat,
                      float * wdat,
                      int   * ndat,
                      float * fpar,
                      float * epar,
                      int   * mpar,
                      int   * npar,
                      float * tol ,
                      int   * its ,
                      float * lab  ) ;
                      */
    return cpl_error_get_code();
}

static cpl_error_code
sinfo_test_fit_slits_edge(void){
/*
    int
    sinfo_new_fit_slits_edge( cpl_image   * lineImage,
                      FitParams ** par,
                      float     ** sinfo_slit_pos,
                      int          box_length,
                      float        y_box,
                      float        diff_tol ) ;
                      */

    return cpl_error_get_code();
}

static cpl_error_code
sinfo_test_fit_slits_edge_with_estimate(void){




/*
    int
    sinfo_new_fit_slits_edge_with_estimate ( cpl_image   * lineImage,
                                    float    ** sinfo_slit_pos,
                                    int         box_length,
                                    float       y_box,
                                    float       diff_tol,
                                    int         low_pos,
                                    int         high_pos ) ;
                                    */

    return cpl_error_get_code();
}

/* NOT USED FUNCTIONS
float
sinfo_new_hat1 ( float * xdat, float * parlist)
void
sinfo_new_hat_deriv1( float * xdat, float * parlist,
                      float * dervs)
void
sinfo_new_hat_deriv2(float * xdat, float * parlist,
                     float * dervs)

float
sinfo_new_hat2 ( float * xdat, float * parlist)

int
sinfo_new_fit_slits1( cpl_image   * lineImage,
                      FitParams ** par,
                      float     ** sinfo_slit_pos,
                      int          box_length,
                      float        y_box )


*/

/*----------------------------------------------------------------------------*/
/**
  @brief   SINFONI pipeline unit test for skycor

**/
/*----------------------------------------------------------------------------*/

int main(void)
{
    /* Initialize CPL + SINFO messaging */
  cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_WARNING);
  sinfo_test_edge();

  sinfo_test_edge_deriv();

/*
  sinfo_test_lsqfit_edge();
  sinfo_test_fit_slits_edge();
  sinfo_test_fit_slits_edge_with_estimate();
  */

  cpl_test_error(CPL_ERROR_NONE);
  return cpl_test_end(0);

}


/**@}*/
