/*
 * 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_badnorm_ini_by_cpl.c
   Author       :   Andrea Modigliani
   Created on   :   Jun 16, 2004
   Description  :   parse cpl input for the search of static bad pixels

 ---------------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif
/*---------------------------------------------------------------------------
                                Includes
 ---------------------------------------------------------------------------*/

#include <string.h>
#include "sinfo_badnorm_ini_by_cpl.h"
#include "sinfo_raw_types.h"
#include "sinfo_pro_types.h"
#include "sinfo_hidden.h"
#include "sinfo_globals.h"
#include "sinfo_functions.h"
#include "sinfo_file_handling.h"
/*---------------------------------------------------------------------------
                    Functions private to this module
 ---------------------------------------------------------------------------*/

static void  parse_section_frames(bad_config * cfg, 
cpl_frameset* sof, const char* procatg, cpl_frameset** raw, int* status);
static void parse_section_badpix(bad_config * cfg, cpl_parameterlist* cpl_cfg);
static void parse_section_thresh(bad_config * cfg, cpl_parameterlist* cpl_cfg);

/**@{*/
/**
 * @addtogroup sinfo_bad_pix_search Bad Pixel Search
 *
 * TBD
 */

/**
  @name     sinfo_parse_cpl_input_badnorm
  @memo     Parse input from CPL (parameters and set of input frames) 
            to create a blackboard.
  @param    config    cpl parameter list
  @param    sof       cpl frames list
  @return   1 newly allocated bad_config blackboard structure.
  @doc The requested cpl input is parsed and a blackboard object is created, 
       then updated accordingly. Returns NULL in case of error.
 */



bad_config * 
sinfo_parse_cpl_input_badnorm(cpl_parameterlist * cpl_cfg, 
                                     cpl_frameset* sof,
                                     const char* procatg,
                                     cpl_frameset** raw) 
{
  bad_config    *       cfg ;
  int status = 0;
        /* Removed check on ini_file */
        /* Removed load of ini file */

  cfg = sinfo_bad_cfg_create();

        /*
         * Perform sanity checks, fill up the structure with what was
         * found in the ini file
         */

  parse_section_badpix   (cfg, cpl_cfg);
  parse_section_thresh   (cfg, cpl_cfg);
  parse_section_frames   (cfg, sof, procatg, raw,&status);
  if(status>0) {
               sinfo_msg_error("parsing cpl input");
                sinfo_bad_cfg_destroy(cfg);
                cfg = NULL ;
                return NULL ;
  }
  return cfg ;

}


/**
  @name     parse_section_frames
  @memo     Parse input frames 
  @param    cfg   pointer to bad_config
  @param    sof   cpl frames list
  @param    procatg  PRO.CATG of product
  @param    raw  raw set of frames
  @param    status  status of operation
  @return   void.
 */


static void     
parse_section_frames(bad_config   * cfg,
                     cpl_frameset * sof,
                     const char         * procatg,          
                     cpl_frameset ** raw,
                     int* status)
{
   int                i=0;
   int                nraw = 0;
   //char *          tag=NULL;

   int  nraw_good = 0;
   cpl_frame* frame=NULL;
   char spat_res[FILE_NAME_SZ];
   char lamp_status[FILE_NAME_SZ];
   char band[FILE_NAME_SZ];
   int ins_set=0;
     if(strcmp(procatg,PRO_BP_MAP_DI) == 0 ) {

      sinfo_extract_raw_frames_type(sof,raw,PRO_MASTER_FLAT_LAMP);
      nraw=cpl_frameset_get_size(*raw);

   } else if(strcmp(procatg,PRO_BP_MAP_NO) == 0 ) {
      
      sinfo_extract_raw_frames_type(sof,raw,PRO_MASTER_FLAT_LAMP);
      nraw=cpl_frameset_get_size(*raw);

   } else {
      sinfo_extract_raw_frames_type(sof,raw,RAW_FLAT_LAMP);
      nraw=cpl_frameset_get_size(*raw);

      if (nraw==0) {
         sinfo_extract_raw_frames_type(sof,raw,RAW_FLAT_NS);
         nraw=cpl_frameset_get_size(*raw);
      }   

   }
    if (nraw==0) {
         sinfo_extract_raw_frames_type(sof,raw,RAW_FLAT_LAMP);
         nraw=cpl_frameset_get_size(*raw);
    }

    if (nraw==0) {
         sinfo_extract_raw_frames_type(sof,raw,RAW_FLAT_NS);
         nraw=cpl_frameset_get_size(*raw);
    }


   if (nraw < 1) {
      sinfo_msg_error("Too few (%d) raw frames (%s or %s or %s) present in"
             "frameset!Aborting...",nraw,
                         PRO_MASTER_FLAT_LAMP,RAW_FLAT_LAMP,RAW_FLAT_NS);
      (*status)++;
      return;
   }
        
   /* Removed: get "general:infile" read it, check input sinfo_matrix */
   /* Allocate structures to go into the blackboard */
   cfg->framelist     = cpl_malloc(nraw * sizeof(char*));

   /* read input frames */
   for (i=0 ; i<nraw ; i++) {
      frame = cpl_frameset_get_frame(*raw,i);
      //tag = (char*)cpl_frame_get_tag(frame) ;
      if(sinfo_file_exists((char*) cpl_frame_get_filename(frame))==1) 
    {
             /* Store file name into framelist */
             cfg->framelist[i]=(char*) cpl_frame_get_filename(frame);
             nraw_good++;
    }
   }

   if(nraw_good<1) {
     sinfo_msg_error("Error: no good raw frame in input, something wrong!");
     (*status)++;
     return;
   }

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

   /* Output */
          if (strcmp(procatg,PRO_BP_MAP_NO) == 0) {
      strcpy(cfg -> outName, BP_NORM_OUT_FILENAME);
   } else if (strcmp(procatg,PRO_BP_MAP_DI) == 0) {
      strcpy(cfg -> outName, BP_DIST_OUT_FILENAME);
   } else if (strcmp(procatg,PRO_DEFAULT) == 0) {
      strcpy(cfg -> outName, BP_NORM_OUT_FILENAME);
   } else {
      sinfo_msg_error("Error: PRO.CATG %s, not supported!",procatg);
      (*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_badpix
  @memo     Parse bad pixel parameters
  @param    cfg   pointer to bad_config
  @param    cpl_cfg input parameter list
  @return   void.
 */


static void     
parse_section_badpix(bad_config    * cfg, cpl_parameterlist *   cpl_cfg)
{
   cpl_parameter *p;     

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.bp_norm.sigma_factor");
   cfg -> sigmaFactor = cpl_parameter_get_double(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.bp_norm.method_index");
   cfg -> methodInd = cpl_parameter_get_int(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.bp_norm.factor");
   cfg -> factor = cpl_parameter_get_double(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.bp_norm.iterations");
   cfg -> iterations = cpl_parameter_get_int(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.bp_norm.low_rejection");
   cfg -> loReject = cpl_parameter_get_double(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.bp_norm.high_rejection");
   cfg -> hiReject = cpl_parameter_get_double(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.bp_norm.llx");
   cfg -> llx = cpl_parameter_get_int(p);

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

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.bp_norm.urx");
   cfg -> urx = cpl_parameter_get_int(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.bp_norm.ury");
   cfg -> ury = cpl_parameter_get_int(p);

}

/**
  @name     parse_section_thresh
  @memo     Parse threshold parameters
  @param    cfg   pointer to bad_config
  @param    cpl_cfg input parameter list
  @return   void.
 */


static void     
parse_section_thresh(bad_config    * cfg, cpl_parameterlist *   cpl_cfg)
{
   cpl_parameter *p;     

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.bp_norm.threshold_index");
   cfg -> threshInd  = cpl_parameter_get_bool(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.bp_norm.mean_factor");
   cfg -> meanfactor = cpl_parameter_get_double(p);


   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.bp_norm.min_cut");
   cfg -> mincut = cpl_parameter_get_double(p);

   p = cpl_parameterlist_find(cpl_cfg, "sinfoni.bp_norm.max_cut");
   cfg -> maxcut = cpl_parameter_get_double(p);

}
/**
@name sinfo_badnorm_free
@memo free a bad_config object
@param cfg pointer to bad_config structure
@return void
*/

void
sinfo_badnorm_free(bad_config ** cfg)
{  
  if((*cfg) != NULL) {
    if((*cfg)->framelist != NULL) {
       cpl_free((*cfg)->framelist);
       (*cfg)->framelist=NULL;
    }
    sinfo_bad_cfg_destroy((*cfg));
    *cfg =NULL;
  }
  return;

}
/**@}*/
