/* $Id: sinfo_pfits.c,v 1.14 2012-05-04 08:11:07 amodigli Exp $
 *
 * This file is part of the SINFONI Pipeline
 * Copyright (C) 2002,2003 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, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/*
 * $Author: amodigli $
 * $Date: 2012-05-04 08:11:07 $
 * $Revision: 1.14 $
 * $Name: not supported by cvs2svn $
 */

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif
/*----------------------------------------------------------------------------
                                   Includes
 ----------------------------------------------------------------------------*/
#include <ctype.h>
#include <cpl.h>
#include "sinfo_pfits.h"
#include "sinfo_key_names.h"
#include "sinfo_utils_wrappers.h"
#include "sinfo_msg.h"
#include <string.h>

/*---------------------------------------------------------------------------*/
#define ASCIILINESZ                         1024
#define PAF_MAGIC_SZ               13
#define PAF_MAGIC       "PAF.HDR.START"

/*-----------------------------------------------------------------------------
                              Function codes
 ----------------------------------------------------------------------------*/
char * sinfo_paf_query(
                char    *   filename,
                char    *   key) ;

static int sinfo_is_paf_file(char * filename) ;

static char * sinfo_strcrop(char * s);


/**@{*/
/**
 * @defgroup sinfo_pfits In/Out on propertylist cards
 *
 * TBD
 */


/*---------------------------------------------------------------------------*/
/**
  @brief    Remove blanks at the end of a string.
  @param    s   String to parse.
  @return   ptr to statically allocated string.

  This function returns a pointer to a statically allocated string,
  which is identical to the input string, except that all blank
  characters at the end of the string have been removed.
  Do not free or modify the returned string! Since the returned string
  is statically allocated, it will be modified at each function call
  (not re-entrant).
 */
/*---------------------------------------------------------------------------*/
static char * sinfo_strcrop(char * s)
{
    static char l[ASCIILINESZ+1];
    char * last ;

    if (s==NULL) return NULL ;
    memset(l, 0, ASCIILINESZ+1);
    strcpy(l, s);
    last = l + strlen(l);
    while (last > l) {
        if (!isspace((int)*(last-1)))
            break ;
        last -- ;
    }
    *last = (char)0;
    return l ;
}

/*---------------------------------------------------------------------------*/
/**
  @brief    returns 1 if file is in PAF format, 0 else
  @param    filename name of the file to check
  @return    int 0, 1, or -1
  Returns 1 if the file name corresponds to a valid PAF file. Returns
  0 else. If the file does not exist, returns -1. Validity of the PAF file 
  is checked with the presence of PAF.HDR.START at the beginning
 */
/*---------------------------------------------------------------------------*/
static int sinfo_is_paf_file(char * filename)
{
    FILE    *    fp ;
    int            is_paf ;
    char        line[ASCIILINESZ] ;

    if (filename==NULL) return -1 ;

    /* Initialize is_paf */
    is_paf = 0 ;

    /* Open file */
    if ((fp = fopen(filename, "r"))==NULL) {
        sinfo_msg_error("cannot open file [%s]", filename) ;
        return -1 ;
    }

    /* Parse file */
    while (fgets(line, ASCIILINESZ, fp) != NULL) {
        if (line[0] != '#') {
            if (!strncmp(line, PAF_MAGIC, PAF_MAGIC_SZ)) is_paf = 1 ;
            (void)fclose(fp) ;
            return is_paf ;
        }
    }

    (void)fclose(fp) ;
    return is_paf ;
}

/*---------------------------------------------------------------------------*/
/**
  @brief    find out the character string associated to DET.MODE.NAME
  @param    plist   pointer to propertylist
  @return   pointer to statically allocated character string
 */
/*---------------------------------------------------------------------------*/
char * sinfo_pfits_get_mode(const cpl_propertylist * plist)
{

    return (char*) cpl_propertylist_get_string(plist,"ESO DET MODE NAME");

}

/*---------------------------------------------------------------------------*/
/**
  @brief    find out the value of the EXPTIME keyword
  @param    plist    pointer to propertylist 
  @return   keyword value
 */
/*---------------------------------------------------------------------------*/
double sinfo_pfits_get_exp_time(const cpl_propertylist* plist)
{

    return cpl_propertylist_get_double(plist,"EXPTIME");

}





/*----------------------------------------------------------------------------
   Function     :       sinfo_pfits_get_ditndit()
   In           :       fits file name
   Out          :       total integration time in sec
   Job          :       reads the product dit*ndit from the FITS-header 
 ---------------------------------------------------------------------------*/
double sinfo_pfits_get_ditndit(const char* name)
{
    double dit;
    int ndit=0;
    cpl_propertylist* plist=NULL;
    plist=cpl_propertylist_load(name,0);

    dit = cpl_propertylist_get_double(plist,"ESO DET DIT");
    ndit = cpl_propertylist_get_int(plist,"ESO DET NDIT");
    sinfo_free_propertylist(&plist);
    return dit*ndit ;

}


/*---------------------------------------------------------------------------*/
/**
  @brief    find out the character string associated to the EXPTIME keyword
  @param    filename    sinfoni FITS file name
  @return   pointer to statically allocated character string
 */
/*---------------------------------------------------------------------------*/
double sinfo_pfits_get_exptime(const char * filename)
{
    double exptime ;
    cpl_propertylist* plist=NULL;
    plist=cpl_propertylist_load(filename,0);
    exptime = cpl_propertylist_get_double(plist,"EXPTIME");
    sinfo_free_propertylist(&plist);

    return exptime;
}




/*---------------------------------------------------------------------------*/
/**
  @brief    find out the character string associated to the DET.NCORRS key.
  @param    plist  input propertylist
  @return   pointer to statically allocated character string
 */
/*---------------------------------------------------------------------------*/
int sinfo_pfits_get_rom(const cpl_propertylist * plist)
{

    return  cpl_propertylist_get_int(plist,"ESO DET NCORRS");

}



/*---------------------------------------------------------------------------*/
/**
  @brief    find out the airmass start 
  @param    plist   FITS header
  @return   pointer to statically allocated character string
 */
/*---------------------------------------------------------------------------*/
double sinfo_pfits_get_airmass_start(const cpl_propertylist * plist)
{

    return cpl_propertylist_get_double(plist,"ESO TEL AIRM START");

}

/*---------------------------------------------------------------------------*/
/**
  @brief    find out the airmass end 
  @param    plist   FITS header
  @return   pointer to statically allocated character string
 */
/*---------------------------------------------------------------------------*/
double sinfo_pfits_get_airmass_end(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_double(plist,"ESO TEL AIRM END");

}

/*---------------------------------------------------------------------------*/
/**
  @brief    find out the targ alpha angle
  @param    plist   FITS header
  @return   pointer to statically allocated character string
 */
/*---------------------------------------------------------------------------*/
double sinfo_pfits_get_targ_alpha(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_double(plist,"ESO INS TARG ALPHA");
}


/*---------------------------------------------------------------------------*/
/**
  @brief    find out the targ delta angle
  @param    plist   FITS header
  @return   pointer to statically allocated character string
 */
/*---------------------------------------------------------------------------*/
double sinfo_pfits_get_targ_delta(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_double(plist,"ESO INS TARG DELTA");
}


/*---------------------------------------------------------------------------*/
/**
  @brief    find out the number of chopping cycles
  @param    plist   FITS header
  @return   pointer to statically allocated character string
 */
/*---------------------------------------------------------------------------*/
double sinfo_pfits_get_pixscale(const cpl_propertylist * plist)
{
    const char* val=NULL;
    val=cpl_propertylist_get_string(plist,"ESO INS OPTI1 NAME");
    return atof(val);
}

/*---------------------------------------------------------------------------*/
/**
  @brief    find out the value of the CUMOFFSETX keyword in a header
  @param    plist   FITS header
  @return   keyword value
 */
/*---------------------------------------------------------------------------*/
double sinfo_pfits_get_posangle(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_double(plist,"ESO ADA POSANG");
}

/*---------------------------------------------------------------------------*/
/**
  @brief    find out the value of the CUMOFFSETX keyword in a header
  @param    plist   iput propertylist
  @return   pointer to statically allocated character string
 */
/*---------------------------------------------------------------------------*/
double sinfo_pfits_get_cumoffsetx(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_double(plist,"ESO SEQ CUMOFFSETX");
}

/*---------------------------------------------------------------------------*/
/**
  @brief    find out the value of the CUMOFFSETY keyword in a header
  @param    plist  input propertylist 
  @return   pointer to statically allocated character string
 */
/*---------------------------------------------------------------------------*/
double sinfo_pfits_get_cumoffsety(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_double(plist,"ESO SEQ CUMOFFSETY");
}


/*---------------------------------------------------------------------------*/
/** 
  @brief    find out the DEC keyword in a SINFONI header
  @param    plist   FITS header
  @return   pointer to statically allocated character string
 */
/*---------------------------------------------------------------------------*/
double  sinfo_pfits_get_dec(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_double(plist,"DEC");
}

/*---------------------------------------------------------------------------*/
/**
  @brief    find out the character string associated to the DIT keyword
            in an sinfoni header
  @param    plist   FITS header 
  @return   dit value
 */
/*---------------------------------------------------------------------------*/
double sinfo_pfits_get_dit(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_double(plist,"ESO DET DIT");
}
/*---------------------------------------------------------------------------*/
/**
  @brief    find out the value of the INS OPTI1 NAME keyword in a header
  @param    name   filename 
  @return   pixel scale
 */
/*---------------------------------------------------------------------------*/
float sinfo_pfits_get_pixelscale(const char * name)
{
    cpl_propertylist* plist=NULL;
    float pixscale=0;
    const char* scale=NULL;
    plist=cpl_propertylist_load(name,0);
    scale= cpl_propertylist_get_string(plist,"ESO INS OPTI1 NAME");
    pixscale=atof(scale);
    sinfo_free_propertylist(&plist);
    return pixscale;
}

/*---------------------------------------------------------------------------*/
/**
  @brief    find out the mjd-obs keyword 
  @param    plist   FITS header
  @return   pointer to statically allocated character string
 */
/*---------------------------------------------------------------------------*/
double sinfo_pfits_get_mjdobs(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_double(plist,"MJD-OBS");
}

/*---------------------------------------------------------------------------*/
/**
  @brief    find out the character string associated to the NDIT keyword
  @param    plist   FITS header
  @return   value of NDIT keyword
 */
/*---------------------------------------------------------------------------*/
int sinfo_pfits_get_ndit(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_int(plist,"ESO DET NDIT");
}

/*---------------------------------------------------------------------------*/
/**
  @brief    find out the character string associated to the NAXIS1 keyword
  @param    plist    FITS header
  @return   keyword value
 */
/*---------------------------------------------------------------------------*/
int sinfo_pfits_get_naxis1(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_int(plist,"NAXIS1");
}


/*---------------------------------------------------------------------------*/
/**
  @brief    find out the character string associated to the NAXIS2 keyword
  @param    plist    FITS header
  @return   keyword value
 */
/*---------------------------------------------------------------------------*/
int sinfo_pfits_get_naxis2(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_int(plist,"NAXIS2");
}


/*---------------------------------------------------------------------------*/
/**
  @brief    find out the character string associated to the NAXIS3 keyword
  @param    plist    FITS header
  @return   keyword value
 */
/*---------------------------------------------------------------------------*/
int sinfo_pfits_get_naxis3(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_int(plist,"NAXIS3");
}

/*---------------------------------------------------------------------------*/
/**
  @brief    find out the character string associated to the CRPIX2 keyword
  @param    plist    FITS header
  @return   keyword value
 */
/*---------------------------------------------------------------------------*/
double sinfo_pfits_get_crpix2(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_double(plist,"CRPIX2");
}



/*---------------------------------------------------------------------------*/
/**
  @brief    find out the character string associated to the CRPIX3 keyword
  @param    plist    FITS header
  @return   keyword value
 */
/*---------------------------------------------------------------------------*/
double sinfo_pfits_get_crpix3(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_double(plist,"CRPIX3");
}


/*---------------------------------------------------------------------------*/
/**
  @brief    find out the character string associated to the CDELT1 keyword
  @param    plist    FITS header
  @return   keyword value
 */
/*---------------------------------------------------------------------------*/
double sinfo_pfits_get_cdelt1(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_double(plist,"CDELT1");
}



/*---------------------------------------------------------------------------*/
/**
  @brief    find out the character string associated to the CDELT2 keyword
  @param    plist    FITS header
  @return   keyword value
 */
/*---------------------------------------------------------------------------*/
double sinfo_pfits_get_cdelt2(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_double(plist,"CDELT2");
}



/*---------------------------------------------------------------------------*/
/**
  @brief    find out the character string associated to the CDELT3 keyword
  @param    plist    FITS header
  @return   keyword value
 */
/*---------------------------------------------------------------------------*/
double sinfo_pfits_get_cdelt3(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_double(plist,"CDELT3");
}



/*---------------------------------------------------------------------------*/
/**
  @brief    find out the character string associated to the CVRVAL1 keyword
  @param    plist    FITS header
  @return   keyword value
 */
/*---------------------------------------------------------------------------*/
double sinfo_pfits_get_crval1(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_double(plist,"CRVAL1");
}

/*---------------------------------------------------------------------------*/
/**
  @brief    find out the character string associated to the CVRVAL2 keyword
  @param    plist    FITS header
  @return   keyword value
 */
/*---------------------------------------------------------------------------*/
double sinfo_pfits_get_crval2(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_double(plist,"CRVAL2");
}

/*---------------------------------------------------------------------------*/
/**
  @brief    find out the character string associated to the CVRVAL3 keyword
  @param    plist    FITS header
  @return   keyword value
 */
/*---------------------------------------------------------------------------*/
double sinfo_pfits_get_crval3(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_double(plist,"CRVAL3");
}


/*---------------------------------------------------------------------------*/
/**
  @brief    find out the RA keyword in a SINFONI header
  @param    plist   FITS header
  @return   pointer to statically allocated character string
 */
/*---------------------------------------------------------------------------*/
double sinfo_pfits_get_ra(const cpl_propertylist * plist)
{
    return cpl_propertylist_get_double(plist,"RA");
}

/**
@brief set hdu keys 
@param plist input propertylist
@param hduclas1 hdu classification1 value
@param hduclas2 hdu classification2 value
@param hduclas3 hdu classification3 value
@return updated propertylist
 */
static cpl_error_code
sinfo_plist_set_extra_common_keys(cpl_propertylist* plist)
{

    cpl_propertylist_append_string(plist,"HDUCLASS", "ESO") ;
    cpl_propertylist_set_comment(plist,"HDUCLASS","hdu classification") ;

    cpl_propertylist_append_string(plist,"HDUDOC", "DICD") ;
    cpl_propertylist_set_comment(plist,"HDUDOC","hdu reference document") ;

    cpl_propertylist_append_string(plist,"HDUVERS", "DICD V6.0") ;
    cpl_propertylist_set_comment(plist,"HDUVERS","hdu reference document version") ;

    return cpl_error_get_code();
}

/**
@brief set hdu keys 
@param plist input propertylist
@param hduclas1 hdu classification1 value
@param hduclas2 hdu classification2 value
@param hduclas3 hdu classification3 value
@param scidata  name of data extension
@param errdata  name of errs extension
@param qualdata name of qual extension
@param type type of extension: 0 data, 1 errs, 2 qual
@return updated propertylist
 */
cpl_error_code
sinfo_plist_set_extra_keys(cpl_propertylist* plist,
                           const char* hduclas1,
                           const char* hduclas2,
                           const char* hduclas3,
                           const char* scidata,
                           const char* errdata,
                           const char* qualdata,
                           const int type)
{

    cpl_ensure_code(type<3,CPL_ERROR_ILLEGAL_INPUT);
    cpl_ensure_code(type>=0,CPL_ERROR_ILLEGAL_INPUT);

    sinfo_plist_set_extra_common_keys(plist);

    cpl_propertylist_append_string(plist,"HDUCLAS1",hduclas1) ;
    cpl_propertylist_set_comment(plist,"HDUCLAS1","hdu format classification") ;

    cpl_propertylist_append_string(plist,"HDUCLAS2",hduclas2) ;
    cpl_propertylist_set_comment(plist,"HDUCLAS2","hdu type classification") ;

    if(type!=0) {
        cpl_propertylist_append_string(plist,"HDUCLAS3",hduclas3) ;
        cpl_propertylist_set_comment(plist,"HDUCLAS3","hdu info classification") ;
        cpl_propertylist_append_string(plist,"SCIDATA",scidata) ;
        cpl_propertylist_set_comment(plist,"SCIDATA","name of data extension") ;
    }

    if(type!=1) {
        /* CASA prefers to have these not set if the extension actually does not
         * exist
        cpl_propertylist_append_string(plist,"ERRDATA",errdata) ;
        cpl_propertylist_set_comment(plist,"ERRDATA","name of errs extension") ;
         */
    }

    if(type!=2) {
        /* CASA prefers to have these not set if the extension actually does not
         * exist
        cpl_propertylist_append_string(plist,"QUALDATA",qualdata) ;
        cpl_propertylist_set_comment(plist,"QUALDATA","name of qual extension") ;
         */
    }

    return cpl_error_get_code();
}

/**@}*/
