/*                                                                            *
 *   This file is part of the ESO X-shooter Pipeline                          *
 *   Copyright (C) 2006 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: 2012-12-07 16:51:34 $
 * $Revision: 1.22 $
 * $Name: not supported by cvs2svn $
 */
#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

/*--------------------------------------------------------------------------*/
/**
 * @defgroup test_xsh_test_order     Test Data type ORDER functions
 * @ingroup unit_tests
 *
 */
/*--------------------------------------------------------------------------*/
/**@{*/

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


#include <xsh_data_order.h>
#include <xsh_error.h>
#include <xsh_msg.h>
#include <xsh_data_instrument.h>
#include <xsh_dfs.h>
#include <xsh_pfits.h>
#include <tests.h>
#include <xsh_utils_table.h>
#include <cpl.h>
#include <math.h>
#include <getopt.h>

/*---------------------------------------------------------------------------
                            Defines
 ---------------------------------------------------------------------------*/
#define MODULE_ID "XSH_DATA_ORDER"

#define SYNTAX "Test the order table\n"\
  "usage : ./the_xsh_data_order [options] ORDER_TAB \n"\
  "ORDER_TAB   => the order table\n"\
  "Options:\n"\
  " --binx=<n>     : binning in X (default 1)\n"\
  " --biny=<n>     : binning in Y (default 1)\n"\
  " --point=<str>  : Point Type (cross, x, diamond, ...)\n"\
  "                  Default is 'cross'\n"\
  " --size=<n>     : Point size (pixels). Default is default DS9 value\n"\
  " --step=<nn>    : Step in pixels. Default '8'\n"


static const char * Options = "?" ;

enum {
  POINT_OPT, SIZE_OPT, STEP_OPT, C_COLOR_OPT,BINX_OPT,BINY_OPT
} ;

static struct option LongOptions[] = {
  {"point", required_argument, 0, POINT_OPT},
  {"size", required_argument, 0, SIZE_OPT},
  {"step",  required_argument, 0, STEP_OPT},
  {"c-color", required_argument, 0, C_COLOR_OPT},
  {"binx", required_argument, 0, BINX_OPT},
  {"biny", required_argument, 0, BINY_OPT},
  {NULL, 0, 0, 0}
} ;

static char PointType[16] ;
static char PointSize[8] ;
static int PointStep = 8 ;
static char CentralColor[32] ;
int binx =1;
int biny =1;
/*--------------------------------------------------------------------------
  Implementation
  --------------------------------------------------------------------------*/

static void HandleOptions( int argc, char ** argv )
{
  int opt ;
  int option_index = 0;

  /* Set default values */
  strcpy( PointType, "cross" ) ;
  strcpy( PointSize, "" ) ;
  strcpy( CentralColor, "green" ) ;

  while( (opt = getopt_long( argc, argv, Options,
			     LongOptions, &option_index )) != EOF )
    switch( opt ) {
    case POINT_OPT:
      strcpy( PointType, optarg ) ;
      break ;
    case SIZE_OPT:
      strcpy( PointSize, optarg ) ;
      break ;
    case STEP_OPT:
      sscanf( optarg, "%64d", &PointStep ) ;
      break ;
    case C_COLOR_OPT:
      strcpy( CentralColor, optarg ) ;
    case  BINX_OPT:
      binx = atoi(optarg);
    case BINY_OPT:
      biny = atoi(optarg);
      break ;
    default:
      printf( SYNTAX ) ;
      TEST_END();
      exit( 0 ) ;
    }
}

/*--------------------------------------------------------------------------*/
/**
  @brief
    Unit test of xsh_data_order
  @return
    0 if success

*/
/*--------------------------------------------------------------------------*/
int main(int argc, char** argv)
{
  int ret = 0;
  xsh_instrument * instrument = NULL ;
  XSH_INSTRCONFIG* iconfig = NULL;

  char* order_tab_name = NULL;
  cpl_frame* order_tab_frame = NULL;
  cpl_table* table = NULL;
  int nbcol;
  xsh_order_list* order_tab = NULL;
  int order_tab_size = 0;
  int iy, iorder;
  int ny;
  FILE* order_tab_file = NULL;
  cpl_propertylist *header = NULL;
  const char* pro_catg = NULL;

  /* Initialize libraries */
  TESTS_INIT(MODULE_ID);
  cpl_msg_set_level(CPL_MSG_DEBUG);
  xsh_debug_level_set(XSH_DEBUG_LEVEL_MEDIUM) ;

  HandleOptions( argc, argv );

  /* Analyse parameters */
  if ( optind < argc ) {
    order_tab_name = argv[optind] ;
  }
  else{
    printf(SYNTAX);
    TEST_END();
    return 0;
  }

  /* Create frames */
  XSH_ASSURE_NOT_NULL( order_tab_name);
  order_tab_frame = cpl_frame_new();
  cpl_frame_set_filename( order_tab_frame, order_tab_name) ;
  cpl_frame_set_level( order_tab_frame, CPL_FRAME_LEVEL_TEMPORARY);
  cpl_frame_set_group( order_tab_frame, CPL_FRAME_GROUP_RAW );
  
  XSH_TABLE_LOAD( table, order_tab_name);
  check( nbcol =  cpl_table_get_nrow(table));
  instrument = xsh_instrument_new() ;
  xsh_instrument_set_arm( instrument, XSH_ARM_UVB);
  
  XSH_ASSURE_NOT_NULL( instrument);

  check (iconfig = xsh_instrument_get_config( instrument));
  iconfig->orders = nbcol;

  ny = iconfig->ny;
  check( order_tab = xsh_order_list_load( order_tab_frame, instrument));
  order_tab_size = order_tab->size;
  xsh_order_list_set_bin_x( order_tab, binx);
  xsh_order_list_set_bin_y( order_tab, biny);
  check ( header = cpl_propertylist_load( order_tab_name, 0));
  check( pro_catg = xsh_pfits_get_pcatg( header));

  xsh_msg( "Order Table of type %s bin %dx%d",pro_catg, binx, biny);

  xsh_msg("Save order tab in ORDER_TAB.reg");
  order_tab_file = fopen( "ORDER_TAB.reg", "w");
  fprintf( order_tab_file, "# Region file format: DS9 version 4.0\n"\
    "global color=red font=\"helvetica 10 normal\""\
    "select=1 highlite=1 edit=1 move=1 delete=1 include=1 fixed=0 "\
    "source\nimage\n");
  fprintf( order_tab_file, 
    "# GREEN center_x center_y (pixels)\n"\
    "# RED low_x low_y (pixels)\n"\
    "# BLUE up_x up_y (pixels)\n");

  xsh_msg("Using step %d", PointStep);
  for( iorder=0; iorder< order_tab_size; iorder++){
    int starty, endy, absorder;

    check( starty = xsh_order_list_get_starty( order_tab, iorder));
    check( endy =  xsh_order_list_get_endy( order_tab, iorder));

    absorder = order_tab->list[iorder].absorder;
     xsh_msg(" Dump order %d (%d => %d)", absorder, starty, endy);
    if (starty == 0 && endy == 0){
      xsh_msg("Warning starty and endy equal zero, put endy to %d",ny);
      starty =1;
      endy = ny;
    }
    for( iy=starty; iy<=endy; iy= iy+PointStep){
      float dx;

      check ( dx = xsh_order_list_eval( order_tab, order_tab->list[iorder].cenpoly, 
        iy));

      if (iy==starty){
        fprintf( order_tab_file, "point(%f,%d) #point=%s %s color=%s font="\
          "\"helvetica 10 normal\" text={absorder %d}\n", dx, iy, PointType, 
          PointSize, CentralColor, absorder);
      } else if (iy==endy){
        fprintf( order_tab_file, "point(%f,%d) #point=%s %s color=%s font="\
          "\"helvetica 10 normal\" text={absorder %d}\n", dx, iy, PointType, 
          PointSize, CentralColor, absorder);
      }
      else{
        fprintf( order_tab_file, "point(%f,%d) #point=%s %s color=%s font="\
          "\"helvetica 10 normal\"\n", dx, iy, PointType, PointSize, 
          CentralColor);
      }
      if ( XSH_CMP_TAG_LAMP( pro_catg, XSH_ORDER_TAB_EDGES)|| XSH_CMP_TAG_MODE( pro_catg, XSH_ORDER_TAB_AFC)){
        check ( dx = xsh_order_list_eval( order_tab, order_tab->list[iorder].edglopoly,
        iy));

        fprintf( order_tab_file, "point(%f,%d) #point=cross color=red font="\
          "\"helvetica 10 normal\"\n", dx, iy);
        check ( dx = xsh_order_list_eval( order_tab, order_tab->list[iorder].edguppoly,
        iy));
        fprintf( order_tab_file, "point(%f,%d) #point=cross color=blue font="\
          "\"helvetica 10 normal\"\n", dx, iy);
	/* Check if IFU */
	if ( order_tab->list[iorder].slicuppoly != NULL ) {
          check ( dx = xsh_order_list_eval( order_tab, order_tab->list[iorder].slicuppoly,
            iy));
	  fprintf( order_tab_file,
		   "point(%f,%d) #point=diamond color=blue font="	\
		   "\"helvetica 10 normal\"\n", dx, iy);
	}
	if ( order_tab->list[iorder].sliclopoly != NULL ) {
          check ( dx = xsh_order_list_eval( order_tab, order_tab->list[iorder].sliclopoly,
            iy));
	  fprintf( order_tab_file,
		   "point(%f,%d) #point=diamond color=red font="	\
		   "\"helvetica 10 normal\"\n", dx, iy);
	}
      }
      /* force to do last point */
      if ( (iy+PointStep > endy) && (iy != endy)){
        iy=endy-PointStep;
      }
    }
  }


  cleanup:
    if (cpl_error_get_code() != CPL_ERROR_NONE) {
      xsh_error_dump(CPL_MSG_ERROR);
      ret  = 1;
    }
    if ( NULL != order_tab_file ) {
      fclose( order_tab_file);
    }
    xsh_free_frame( &order_tab_frame);
    xsh_instrument_free( &instrument);
    xsh_free_propertylist( &header);
    xsh_order_list_free( &order_tab);
    XSH_TABLE_FREE( table);
    TEST_END();
    return ret ;
}

/**@}*/
