/*
 * This file is part of the ESO SINFONI Pipeline
 * Copyright (C) 2004,2005 European Southern Observatory
 *
 * This program 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
 */
/*----------------------------------------------------------------------------
   
   File name    :   sinfo_focus_ini_by_cpl.c
   Author       :   Andrea Modigliani
   Created on   :   May 20, 2004
   Description  :   cpl input handling for SPIFFI
 ---------------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif
/*---------------------------------------------------------------------------
                                Includes
 ---------------------------------------------------------------------------*/
#include <string.h>
#include "sinfo_focus_ini_by_cpl.h"
#include "sinfo_pro_types.h"
#include "sinfo_functions.h"
#include "sinfo_file_handling.h"
/*---------------------------------------------------------------------------
                    Functions private to this module
 ---------------------------------------------------------------------------*/
static void 
parse_section_frames(focus_config *, cpl_parameterlist* cpl_cfg, 
                   cpl_frameset* sof,cpl_frameset** stk, int* status);
static void 
parse_section_reconstruction(focus_config *, cpl_parameterlist* cpl_cfg);
static void 
parse_section_gauss2dfit(focus_config *, cpl_parameterlist* cpl_cfg);

/**@{*/
/**
 * @addtogroup sinfo_focus Focus determination functions
 *
 * TBD
 */



/**
  @name     sinfo_parse_cpl_input_focus
  @memo     Parse input frames and parameters and create a blackboard.
  @param    cpl_cfg pointer to parameterlist
  @param    sof pointer to input set of frames
  @param    stk pointer to input set of stacked frames
  @return   1 newly allocated focus_config blackboard structure.
  @doc

  The requested ini file is parsed and a blackboard object is created, then
  updated accordingly. Returns NULL in case of error.
 */

focus_config * 
sinfo_parse_cpl_input_focus(cpl_parameterlist * cpl_cfg, cpl_frameset* sof,
                     cpl_frameset** stk)
{
        focus_config  *       cfg = sinfo_focus_cfg_create();
  int status=0;
        /*
         * Perform sanity checks, fill up the structure with what was
         * found in the ini file
         */

        parse_section_reconstruction   (cfg, cpl_cfg);
        parse_section_gauss2dfit       (cfg, cpl_cfg);
        parse_section_frames           (cfg, cpl_cfg,sof,stk,&status);
        if (status > 0) {
                sinfo_msg_error("parsing cpl input");
                sinfo_focus_cfg_destroy(cfg);
                cfg = NULL ;
                return NULL ;
        }
        return cfg ;
}

/**
  @name     parse_section_frames
  @memo     Parse input frames.
  @param    cfg pointer to focus_config structure
  @param    cpl_cfg pointer to parameterlist
  @param    sof pointer to input set of frames
  @param    raw pointer to input set of raw frames
  @param    status status of function
  @return   void
 */
static void   
parse_section_frames(focus_config * cfg,
                     cpl_parameterlist* cpl_cfg,
                     cpl_frameset* sof,
                     cpl_frameset** raw, 
                     int* status)
{


   char            *       name ;
    int nframes=0;
   int nraw=0;
   cpl_frame* frame   = NULL;
   cpl_parameter *p; 


   char spat_res[FILE_NAME_SZ];
   char lamp_status[FILE_NAME_SZ];
   char band[FILE_NAME_SZ];
   int ins_set=0;


   char * tag;
   int i=0;
   nframes = cpl_frameset_get_size(sof);
    /* Get the raw and the calibration files */
    /* Labelise the input frames according to their tags */

  *raw=cpl_frameset_new();
   sinfo_extract_raw_frames_type(sof,raw,PRO_FOCUS_STACKED);


   nraw=cpl_frameset_get_size(*raw);
   if (nraw < 1) {
      sinfo_msg_error("Too few (%d) raw frames (%s) present in"
            "frameset!Aborting...",nraw,PRO_FOCUS_STACKED);
          (*status)++;
          return;
   }
   /* Allocate structures to go into the blackboard */
   cfg->inFrameList     = cpl_malloc(nraw * sizeof(char*));
 
   /* Browse through the charmatrix to get names and file types */
   for (i=0 ; i<nraw ; i++) {
      frame = cpl_frameset_get_frame(*raw,i);
      name= (char*) cpl_frame_get_filename(frame);
      if(sinfo_file_exists(name)==1) {
    /* to go on the file must exist */
    if(cpl_frame_get_tag(frame) != NULL) {
      /* If the frame has a tag we process it. Else it is an object */ 
      tag= (char*) cpl_frame_get_tag(frame);
          if(sinfo_is_stack(tag)) 
        {
             cfg->inFrameList[i]=cpl_strdup(cpl_frame_get_filename(frame));
        }
          else {
            sinfo_msg_error("No good frame tag %s in input frame set",tag);
        (*status)++;
            return;
      }
    }
      }
      /* Store file name into inFrameList */
   }

   /* Copy relevant information into the blackboard */
   cfg->nframes = nraw ;


   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.focus.output_filename");
   strcpy(cfg -> outName, cpl_parameter_get_string(p));

   if(NULL != cpl_frameset_find(sof,PRO_FIRST_COL)) {
      frame = cpl_frameset_find(sof,PRO_FIRST_COL);
      strcpy(cfg -> firstCol,cpl_strdup(cpl_frame_get_filename(frame)));
   } else {
      sinfo_msg_error("Frame %s not found! Exit!", PRO_FIRST_COL);
        (*status)++;
      return;
   }

   if(NULL != cpl_frameset_find(sof,PRO_SLITLETS_DISTANCE)) {
      frame = cpl_frameset_find(sof,PRO_SLITLETS_DISTANCE);
      strcpy(cfg -> poslist,cpl_strdup(cpl_frame_get_filename(frame)));
   } else {
      sinfo_msg_error("Frame %s not found! Exit!", PRO_SLITLETS_DISTANCE);
        (*status)++;
      return;
   }



   frame = cpl_frameset_get_frame(*raw,0);
   sinfo_get_spatial_res(frame,spat_res);
 
   switch(sinfo_frame_is_on(frame)) 
     {
   case 0: 
      strcpy(lamp_status,"on");
      break;
    case 1: 
      strcpy(lamp_status,"off");
      break;
    case -1:
      strcpy(lamp_status,"undefined");
      break;
    default: 
      strcpy(lamp_status,"undefined");
      break;
     }

   sinfo_get_band(frame,band);
   sinfo_msg("Spatial resolution: %s lamp_status: %s band: %s \n",
                     spat_res,    lamp_status,    band);


   sinfo_get_ins_set(band,&ins_set);
   return;
}

/**
  @name     parse_section_reconstruction
  @memo     Parse reconstruction parameters.
  @param    cfg pointer to focus_config structure
  @param    cpl_cfg pointer to parameterlist
  @return   void
 */
static void     
parse_section_reconstruction(focus_config * cfg,cpl_parameterlist * cpl_cfg)
{


  cpl_parameter* p;

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.focus.lower_rejection");
   cfg -> lo_reject = cpl_parameter_get_double(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.focus.higher_rejection");
   cfg -> hi_reject =  cpl_parameter_get_double(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.focus.north_south_index");
   cfg -> northsouthInd = cpl_parameter_get_bool(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.focus.nslits");
   cfg -> nslits = cpl_parameter_get_int(p);
 
   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.focus.method");
   strcpy(cfg->method, cpl_parameter_get_string(p));

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.focus.order");
   cfg -> order= cpl_parameter_get_int(p);

}

/**
  @name     parse_section_gauss2dfit
  @memo     Parse gauss2dfit parameters.
  @param    cfg pointer to focus_config structure
  @param    cpl_cfg pointer to parameterlist
  @return   void
 */
static void     
parse_section_gauss2dfit(focus_config * cfg,cpl_parameterlist * cpl_cfg)
{
 cpl_parameter* p;
   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.focus.llx");
   cfg -> llx = cpl_parameter_get_int(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.focus.lly");
   cfg -> lly = cpl_parameter_get_int(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.focus.halfbox_x");
   cfg -> halfbox_x =  cpl_parameter_get_int(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.focus.halfbox_y");
   cfg -> halfbox_y = cpl_parameter_get_int(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.focus.mpar0");
   cfg -> mpar0 = cpl_parameter_get_int(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.focus.mpar1");
   cfg -> mpar1 = cpl_parameter_get_int(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.focus.mpar2");
   cfg -> mpar2 = cpl_parameter_get_int(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.focus.mpar3");
   cfg -> mpar3 = cpl_parameter_get_int(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.focus.mpar4");
   cfg -> mpar4 = cpl_parameter_get_int(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.focus.mpar5");
   cfg -> mpar5 = cpl_parameter_get_int(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.focus.mpar6");
   cfg -> mpar6 = cpl_parameter_get_int(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.focus.fit_list");
   strcpy(cfg -> fitlist, cpl_parameter_get_string(p));

   /* int or string ?*/
   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.focus.plot_gauss_ind");
   cfg -> plotGaussInd = cpl_parameter_get_bool(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.focus.gauss_plot_name");
   strcpy( cfg -> gaussplotName, cpl_parameter_get_string(p));

   return ;
}
/**
@name sinfo_free_focus
@memo free sinfo_config structure
@param cfg pointer to focus_config structure
@return void
*/
void
sinfo_free_focus(focus_config * cfg) {
   cpl_free(cfg->inFrameList);
   sinfo_focus_cfg_destroy (cfg);
  
   return;
}
/**@}*/
