/* $Id: casu_tfits.c,v 1.4 2015/09/14 18:45:51 jim Exp $
 *
 * This file is part of the CASU Pipeline utilities
 * Copyright (C) 2015 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: jim $
 * $Date: 2015/09/14 18:45:51 $
 * $Revision: 1.4 $
 * $Name:  $
 */

/* Includes */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdio.h>
#include <math.h>
#include <string.h>

#include <cpl.h>
#include "casu_utils.h"
#include "casu_tfits.h"

/**
    \defgroup casu_tfits casu_tfits
    \ingroup casu_routines

    \brief
    These are methods for manipulating the casu_tfits object

    \author
    Jim Lewis, CASU
*/

/**@{*/

/*---------------------------------------------------------------------------*/
/**
    \par Name:
        casu_tfits_load
    \par Purpose:
        Load an input table into a casu_tfits object
    \par Description:
        A table from an input cpl_frame is loaded into a casu_tfits object.
        Only the table for a given extension number is loaded. The rest
        of the object properties are initialised
    \par Language:
        C
    \param table
        The input cpl_frame object
    \param nexten
        The image extension that you want to load.
    \return
        The output casu_tfits object.
    \author
        Jim Lewis, CASU
 */
/*---------------------------------------------------------------------------*/

extern casu_tfits *casu_tfits_load(cpl_frame *table, int nexten) {
    casu_tfits *p;
    cpl_table *tab;
    int nf;
    const char *fctid = "casu_tfits_load";

    /* Check for nonsense input */

    if (table == NULL)
        return(NULL);

    /* See if you can load the table */

    tab = cpl_table_load(cpl_frame_get_filename(table),nexten,0);
    if (tab == NULL) {
        cpl_msg_error(fctid,"Unable to load %s -- %s",
                      cpl_frame_get_filename(table),cpl_error_get_message());
        cpl_error_reset();
        return(NULL);
    }

    /* Get the casu_tfits structure */

    p = cpl_malloc(sizeof(casu_tfits));

    /* Load stuff in */

    p->table = tab;
    p->nexten = nexten;
    p->phu = NULL;
    p->ehu = NULL;
    p->fname = cpl_strdup(cpl_frame_get_filename(table));
    p->status = CASU_OK;
   
    /* Get the extension header and the extension name */

    (void)casu_tfits_get_ehu(p);
    if (cpl_propertylist_has(p->ehu,"EXTNAME")) {
        p->extname = cpl_strdup(cpl_propertylist_get_string(p->ehu,"EXTNAME"));
    } else {
        nf = 11 + (int)log10((double)nexten);
        p->extname = cpl_malloc(nf);
        (void)snprintf(p->extname,nf,"DET1.CHIP%d",nexten);
    }
    nf = strlen(p->extname) + strlen(p->fname) + 3;
    p->fullname = cpl_malloc(nf);
    (void)snprintf(p->fullname,nf,"%s[%s]",p->fname,p->extname);

    /* Get out of here */

    return(p);
}

/*---------------------------------------------------------------------------*/
/**
    \par Name:
        casu_tfits_extract
    \par Purpose:
        Extract selected rows from a casu_tfits table
    \par Description:
        A casu_tfits structure is passed in containing a table that has
        had some rows selected. A new casu_tfits table is returned with only
        the selected rows.
    \par Language:
        C
    \param in
        The input casu_tfits object
    \return
        The output casu_tfits object.
    \author
        Jim Lewis, CASU
 */
/*---------------------------------------------------------------------------*/

extern casu_tfits *casu_tfits_extract(casu_tfits *in) {
    casu_tfits *p;

    /* Check for nonsense input */

    if (in == NULL)
        return(NULL);

    /* Get the casu_tfits structure */

    p = cpl_malloc(sizeof(casu_tfits));

    /* Load stuff in */

    p->table = cpl_table_extract_selected(casu_tfits_get_table(in));
    p->nexten = casu_tfits_get_nexten(in);
    p->phu = NULL;
    p->ehu = NULL;
    p->fname = cpl_strdup(casu_tfits_get_filename(in));
   
    /* Get out of here */

    return(p);
}

/*---------------------------------------------------------------------------*/
/**
    \par Name:
        casu_tfits_duplicate
    \par Purpose:
        Copy a casu_tfits structure into another one.
    \par Description:
        An input casu_tfits structure is duplcated and returned
    \par Language:
        C
    \param in
        The input casu_tfits object
    \return
        The output casu_tfits object.
    \author
        Jim Lewis, CASU
 */
/*---------------------------------------------------------------------------*/

extern casu_tfits *casu_tfits_duplicate(casu_tfits *in) {
    casu_tfits *p;

    /* Check for nonsense input */

    if (in == NULL)
        return(NULL);

    /* Get the casu_tfits structure */

    p = cpl_malloc(sizeof(casu_tfits));

    /* Now copy everything over */

    p->table = cpl_table_duplicate(in->table);
    p->phu = cpl_propertylist_duplicate(casu_tfits_get_phu(in));
    p->ehu = cpl_propertylist_duplicate(casu_tfits_get_ehu(in));
    p->fname = cpl_strdup(in->fname);
    p->extname = cpl_strdup(in->extname);
    p->fullname = cpl_strdup(in->fullname);
    p->nexten = in->nexten;
    p->status = in->status;
   
    /* Get out of here */

    return(p);
}

/*---------------------------------------------------------------------------*/
/**
    \par Name:
        casu_tfits_load_list
    \par Purpose:
        Load a input tables into a casu_tfits object array
    \par Description:
        Tables from an input cpl_frameset are loaded into a list of 
        casu_tfits objects. Only the tables for a given extension number are
        loaded. The rest of the object properties are initialised
    \par Language:
        C
    \param f
        The input cpl_frameset object
    \param exten
        The image extension that you want to load.
    \return
        The output casu_tfits object list.
    \author
        Jim Lewis, CASU
 */
/*---------------------------------------------------------------------------*/

extern casu_tfits **casu_tfits_load_list(cpl_frameset *f, int exten) {
    int i;
    casu_tfits **p;

    /* Check for nonsense input */

    if (f == NULL)
        return(NULL);

    /* Get some workspace */

    p = cpl_malloc(cpl_frameset_get_size(f)*sizeof(casu_tfits *));
    
    /* Now load each of the frames... */

    for (i = 0; i < cpl_frameset_get_size(f); i++) {
        p[i] = casu_tfits_load(cpl_frameset_get_position(f,i),exten);
        if (p[i] == NULL) {
            casu_tfits_delete_list(p,i-1);
            return(NULL);
        }
    }

    /* Now return the array */

    return(p);
}

/*---------------------------------------------------------------------------*/
/**
    \par Name:
        casu_tfits_delete
    \par Purpose:
        Free all the workspace associated with a casu_tfits object
    \par Description:
        Free all the workspace associated with a casu_tfits object
    \par Language:
        C
    \param p
        The input casu_tfits object
    \author
        Jim Lewis, CASU
 */
/*---------------------------------------------------------------------------*/

extern void casu_tfits_delete(casu_tfits *p) {

    /* Check for nonsense input */

    if (p == NULL)
        return;

    /* Free up workspace if it's been used */

    freetable(p->table);
    freepropertylist(p->phu);
    freepropertylist(p->ehu);
    freespace(p->fname);
    freespace(p->extname);
    freespace(p->fullname);
    cpl_free(p);
}

/*---------------------------------------------------------------------------*/
/**
    \par Name:
        casu_tfits_delete_list
    \par Purpose:
        Free all the workspace associated with a list of casu_tfits objects
    \par Description:
        Free all the workspace associated with a list of casu_tfits objects
    \par Language:
        C
    \param p
        The input list of casu_tfits objects
    \param n
        The number of casu_tfits objects in the above array
    \author
        Jim Lewis, CASU
 */
/*---------------------------------------------------------------------------*/

extern void casu_tfits_delete_list(casu_tfits **p, int n) {
    int i;

    /* Check for nonsense input */

    if (p == NULL)
        return;

    /* Free up workspace if it's been used */

    for (i = 0; i < n; i++)
        casu_tfits_delete(p[i]);
    cpl_free(p);
}

/*---------------------------------------------------------------------------*/
/**
    \par Name:
        casu_tfits_get_table
    \par Purpose:
        Get the CPL table from the casu_tfits object
    \par Description:
        Return the CPL table from the input casu_tfits object. This table is
        suitable for use in all cpl_table routines.
    \par Language:
        C
    \param p
        The input casu_tfits object
    \return 
        The cpl_image object. NULL if there was an error.
    \author
        Jim Lewis, CASU
 */
/*---------------------------------------------------------------------------*/

extern cpl_table *casu_tfits_get_table(casu_tfits *p) {
    
    /* Check for nonsense input */

    if (p == NULL)
        return(NULL);

    /* Return it */

    return(p->table);
}

/*---------------------------------------------------------------------------*/
/**
    \par Name:
        casu_tfits_get_nexten
    \par Purpose:
        Get the FITS extension number for the current image in a casu_tfits 
        object
    \par Description:
        Get the FITS extension number for the current image in a casu_tfits 
        object
    \par Language:
        C
    \param p
        The input casu_tfits object
    \return 
        The extension number (-1 in case of error)
    \author
        Jim Lewis, CASU
 */
/*---------------------------------------------------------------------------*/

extern int casu_tfits_get_nexten(casu_tfits *p) {
    
    /* Check for nonsense input */

    if (p == NULL)
        return(-1);

    /* Return it */

    return(p->nexten);
}

/*---------------------------------------------------------------------------*/
/**
    \par Name:
        casu_tfits_get_phu
    \par Purpose:
        Get the propertylist for the primary header for a given casu_tfits 
        image.
    \par Description:
        Get the propertylist for the primary header for a given casu_tfits 
        image. This should only need to be read once and then can be used 
        to add things to the primary header.
    \par Language:
        C
    \param p
        The input casu_tfits object
    \return 
        The propertylist represeting the primary header of the input table
        (NULL if there is an error).
    \author
        Jim Lewis, CASU
 */
/*---------------------------------------------------------------------------*/

extern cpl_propertylist *casu_tfits_get_phu(casu_tfits *p) {

    /* Check for nonsense input */

    if (p == NULL)
        return(NULL);

    /* If the propertylist hasn't already been loaded, then do it now */

    if (p->phu == NULL) 
        p->phu = cpl_propertylist_load(p->fname,0);
    
    /* Return it */

    return(p->phu);
}

/*---------------------------------------------------------------------------*/
/**
    \par Name:
        casu_tfits_get_ehu
    \par Purpose:
        Get the propertylist for the extension header for a given casu_tfits 
        image.
    \par Description:
        Get the propertylist for the extension header for a given casu_tfits 
        image. This is the extension that is relevant of the image.
        This should only need to be read once and then can be used to add
        things to the primary header.
    \par Language:
        C
    \param p
        The input casu_tfits object
    \return 
        The propertylist represeting the extension header of the input table
        (NULL if there is an error).
    \author
        Jim Lewis, CASU
 */
/*---------------------------------------------------------------------------*/

extern cpl_propertylist *casu_tfits_get_ehu(casu_tfits *p) {

    /* Check for nonsense input */

    if (p == NULL)
        return(NULL);

    /* If the propertylist hasn't already been loaded, then do it now */

    if (p->ehu == NULL) 
        p->ehu = cpl_propertylist_load(p->fname,(cpl_size)(p->nexten));
    
    /* Return it */

    return(p->ehu);
}

/*---------------------------------------------------------------------------*/
/**
    \par Name:
        casu_tfits_get_filename
    \par Purpose:
        Get the filename from which the current casu_tfits object originated
    \par Description:
        Get the filename from which the current casu_tfits object originated. If
        this is null, then the image didn't originate in an FITS file.
    \par Language:
        C
    \param p
        The input casu_tfits object
    \return 
        The name of the file from which this table originated
    \author
        Jim Lewis, CASU
 */
/*---------------------------------------------------------------------------*/

extern char *casu_tfits_get_filename(casu_tfits *p) {

    /* Check for nonsense input */

    if (p == NULL)
        return(NULL);

    /* Return it */

    return(p->fname);
}
  
/*---------------------------------------------------------------------------*/
/**
    \par Name:
        casu_tfits_get_fullname
    \par Purpose:
        Get the fullname of the FITS extension from which the current
        casu_tfits object originated
    \par Description:
        Get the fullname of the FITS extension  from which the current
        casu_tfits object originated. If this is null, then the image didn't
        originate in an FITS file.
    \par Language:
        C
    \param p
        The input casu_tfits object
    \return
        The fullname name of the file from which this image originated
    \author
        Jim Lewis, CASU
 */
/*---------------------------------------------------------------------------*/

extern char *casu_tfits_get_fullname(casu_tfits *p) {

    /* Check for nonsense input */

    if (p == NULL)
        return(NULL);

    /* Return it */

    return(p->fullname);
}

/*---------------------------------------------------------------------------*/
/**
    \par Name:
        casu_tfits_get_status
    \par Purpose:
        Get the error status of the current object.
    \par Description:
        Get the error status of the current object.
    \par Language:
        C
    \param p
        The input casu_tfits object
    \return 
        The error status
    \author
        Jim Lewis, CASU
 */
/*---------------------------------------------------------------------------*/

extern int casu_tfits_get_status(casu_tfits *p) {
    
    /* Check for nonsense input */

    if (p == NULL)
        return(CASU_FATAL);

    /* Return it */
   
    return(p->status);
}
  
/*---------------------------------------------------------------------------*/
/**
    \par Name:
        casu_tfits_set_error
    \par Purpose:
        Set the error status and message for an object
    \par Description:
        The input status is checked to see if there has been a problem
        with the current object. If there has been, then the status is
        stored away and any error message from the cpl_error system is
        copied down.
    \par Language:
        C
    \param p
        The input casu_tfits object
    \param status
        The input error status
    \return 
        A flag to say whether the input status was fatal
    \author
        Jim Lewis, CASU
 */
/*---------------------------------------------------------------------------*/

extern int casu_tfits_set_error(casu_tfits *p, int status) {

    /* Check for nonsense input */

    if (p == NULL)
        return(0);

    /* Get out of here if the status is OK */

    if (status == CASU_OK)
        return(0);

    /* Set the error message if there was an error */

    p->status = status;
    
    /* Reset the cpl error flag */

    cpl_error_reset();
    if (status == CASU_FATAL) 
        return(1);
    else
        return(0);
}

/*---------------------------------------------------------------------------*/
/**
    \par Name:
        casu_tfits_set_status
    \par Purpose:
        Set the error status
    \par Description:
        The input status is checked to see if there has been a problem
        with the current object. If there has been, then the status is
        stored.
    \par Language:
        C
    \param p
        The input casu_tfits object
    \param status
        The input error status
    \return 
        None
    \author
        Jim Lewis, CASU
 */
/*---------------------------------------------------------------------------*/

extern void casu_tfits_set_status(casu_tfits *p, int status) {

    /* Check for nonsense input */

    if (p == NULL)
        return;

    /* Update the status */

    p->status = status;

}

/*---------------------------------------------------------------------------*/
/**
    \par Name:
        casu_tfits_set_filename
    \par Purpose:
        Set the file name associated with a casu_tfits structure
    \par Description:
        Set the file name associated with a casu_tfits structure. This is
        useful if you have wrapped a cpl_table in a structure and you don't
        have a physical file to refer to. The name can be used to define
        an output file name if you ultimately decide to write this out.
        If a name already exists, it will be overwritten 
    \par Language:
        C
    \param p
        The input casu_tfits object
    \param fname
        The input file name.
    \return 
        Nothing
    \author
        Jim Lewis, CASU
 */
/*---------------------------------------------------------------------------*/

extern void casu_tfits_set_filename(casu_tfits *p, char *fname) {

    /* Check for nonsense input */

    if (p == NULL || fname == NULL)
        return;

    /* Set the name up and get out of here */

    freespace(p->fname);
    p->fname = cpl_strdup(fname);   
}
    
/*---------------------------------------------------------------------------*/
/**
    \par Name:
        casu_tfits_wrap
    \par Purpose:
        Wrap an table in a casu_tfits wrapper
    \par Description:
        The input table is inserted into a casu_tfits wrapper. A model
        casu_tfits object may be provided to give the new object 
        headers. If the phu and ehu parameters are not null then they will
        be used as the propertylists for the new object. If not, then
        an attempt will be made to copy the propertylists from the model.
    \par Language:
        C
    \param tab
        The input cpl_table
    \param model
        The input casu_tfits model object
    \param phu
        The input propertylist for the primary header for the new object.
    \param ehu
        The input propertylist for the extension header for the new object.
    \return
        The new casu_tfits structure.
    \author
        Jim Lewis, CASU
 */
/*---------------------------------------------------------------------------*/

extern casu_tfits *casu_tfits_wrap(cpl_table *tab, casu_tfits *model,
                                   cpl_propertylist *phu,
                                   cpl_propertylist *ehu) {
    casu_tfits *p;

    /* Check for nonsense input */

    if (tab == NULL)
        return(NULL);

    /* Get the casu_tfits structure */

    p = cpl_malloc(sizeof(casu_tfits));

    /* Load stuff in */

    p->table = tab;
    p->nexten = -1;
    if (phu != NULL)
        p->phu = phu;
    else if (model != NULL)
        p->phu = cpl_propertylist_duplicate(casu_tfits_get_phu(model));
    else
        p->phu = cpl_propertylist_new();
    if (ehu != NULL)
        p->ehu = ehu;
    else if (model != NULL)
        p->ehu = cpl_propertylist_duplicate(casu_tfits_get_ehu(model));
    else
        p->ehu = cpl_propertylist_new();
    p->fname = NULL;
    p->status = CASU_OK;
    p->extname = NULL;
    p->fullname = NULL;

    /* Get out of here */

    return(p);
}

/**@}*/

/*

$Log: casu_tfits.c,v $
Revision 1.4  2015/09/14 18:45:51  jim
replaced a free by cpl_free

Revision 1.3  2015/08/07 13:06:54  jim
Fixed copyright to ESO

Revision 1.2  2015/08/06 05:34:02  jim
Fixes to get rid of compiler moans

Revision 1.1.1.1  2015/06/12 10:44:32  jim
Initial import

Revision 1.7  2015/01/29 11:56:27  jim
modified comments

Revision 1.6  2015/01/09 12:13:15  jim
*** empty log message ***

Revision 1.5  2014/12/11 12:23:33  jim
new version

Revision 1.4  2014/03/26 15:59:47  jim
Removed calls to deprecated cpl routine

Revision 1.3  2013/11/21 09:38:14  jim
detabbed

Revision 1.2  2013-10-24 09:27:01  jim
added casu_tfits_set_status

Revision 1.1.1.1  2013-08-27 12:07:48  jim
Imported



*/
