/** @file  pmFPAview.h
*
*  @brief Tools to manipulate the FPA structure elements.
*
*  @ingroup AstroImage
*
*  @author EAM, IfA
*
*  @version $Revision: 1.1.2.12 $ $Name: not supported by cvs2svn $
*  @date $Date: 2006-04-14 21:43:59 $
*
*  Copyright 2004-2005 Institute for Astronomy, University of Hawaii
*/

#ifndef PM_FPA_FILE_H
#define PM_FPA_FILE_H

#include "pslib.h"
#include "pmConfig.h"
#include "pmFPA.h"
#include "pmFPAview.h"

typedef enum {
    PM_FPA_BEFORE,
    PM_FPA_AFTER,
} pmFPAfilePlace;

typedef enum {
    PM_FPA_FILE_NONE,
    PM_FPA_FILE_SX,
    PM_FPA_FILE_OBJ,
    PM_FPA_FILE_CMP,
    PM_FPA_FILE_CMF,
    PM_FPA_FILE_RAW,
    PM_FPA_FILE_IMAGE,
    PM_FPA_FILE_PSF,
    PM_FPA_FILE_JPEG,
} pmFPAfileType;

typedef enum {
    PM_FPA_MODE_NONE,
    PM_FPA_MODE_READ,
    PM_FPA_MODE_WRITE,
    PM_FPA_MODE_INTERNAL,
} pmFPAfileMode;

typedef enum {
    PM_FPA_STATE_OPEN,
    PM_FPA_STATE_CLOSED,
} pmFPAfileState;

typedef struct
{
    pmFPAfileMode mode;   // is this file read, written, or only used internally?
    pmFPAfileType type;   // what type of data is read from / written to disk?
    pmFPAfileState state;  // have we opened the file, etc?

    pmFPAdepth fileDepth;  // what depth in the FPA hierarchy represents a unique file?
    pmFPAdepth dataDepth;  // at what depth do we read/write the data segment?

    pmFPA *fpa;    // for I/O files, we carry a pointer to the complete fpa
    psFits *fits;   // for I/O files of fits type (IMAGE, CMP, CMF), we carry a file handle

    psMetadata *phu;   // pointer (view) to the current phu header
    psMetadata *header;   // pointer (view) to the current hdu header

    pmReadout *readout;   // for internal files, we only carry a single readout

    psMetadata *names;   // filenames supplied by the cmdline or detdb are saved here

    char *filerule;   // rule for constructing a filename when needed
    char *filextra;   // additional information used to define filenames (context dependent)
    char *extrule;   // rule for constructing an extension name when needed
    char *extxtra;   // additional information used to define extension names (context dependent)

    char *name;    // the name of the rule (useful for debugging / tracing)
    char *filename;   // the current name of an active file
    char *extname;   // the current name of an active file extension

    // the following elements are used for WRITE-mode IMAGE-type pmFPAfiles to inform
    // the creation of a new image based on an existing image
    pmFPA *src;    // if an output FPA, inherit from this FPA
    int xBin;    // desired binning in x direction
    int yBin;    // desired binning in y direction
    psMetadata *format;
}
pmFPAfile;

// allocate an empty pmFPAfile structure
pmFPAfile *pmFPAfileAlloc ();

// load the pmFPAfile information from the camera configuration data
pmFPAfile *pmFPAfileDefine (psMetadata *files, psMetadata *camera, pmFPA *fpa, char *name);

// load the pmFPAfile information from the camera configuration data, constructing the needed fpa structure
// XXX deprecate this function?
// pmFPAfile *pmFPAfileConstruct (psMetadata *files, psMetadata *format, psMetadata *camera, char *name);

// open the real file corresponding to the given pmFPAfile appropriate to the current view
bool pmFPAfileOpen (pmFPAfile *file, const pmFPAview *view);

// read from the real file corresponding to the given pmFPAfile for the current view
bool pmFPAfileRead (pmFPAfile *file, const pmFPAview *view);

bool pmFPAfileCreate (pmFPAfile *file, const pmFPAview *view);

// write to the real file corresponding to the given pmFPAfile for the current view
bool pmFPAfileWrite (pmFPAfile *file, const pmFPAview *view);

// close the real file corresponding to the given pmFPAfile appropriate to the current view
bool pmFPAfileClose (pmFPAfile *file, const pmFPAview *view);

// examine all pmFPAfiles listed in the files and perform the needed I/O operations (open,read,write,close)
bool pmFPAfileIOChecks (psMetadata *files, const pmFPAview *view, pmFPAfilePlace place);

// return an image corresponding to the current readout, from the specified file.  if the pmFPAfile does not
// exist, construct the image using the given size and type (save it in a pmFPAfile??)
// psImage *pmFPAfileReadoutImage (psMetadata *files, const pmFPAview *view, char *name, int Nx, int Ny, int type);

// select the readout from the named pmFPAfile; if the named file does not exist,
pmReadout *pmFPAfileThisReadout (psMetadata *files, const pmFPAview *view, const char *name);

// create a file with the given name, assign it type "INTERNAL", and supply it with an image
// of the requested dimensions. (image only, mask and weight are ignored)
pmReadout *pmFPAfileCreateInternal (psMetadata *files, char *name, int Nx, int Ny, int type);

// delete the INTERNAL file of the given name (if it exists)
bool pmFPAfileDropInternal (psMetadata *files, char *name);

// read an image into the current view
bool pmFPAviewReadFitsImage (const pmFPAview *view, pmFPAfile *file);

// write the components for the specified view
bool pmFPAviewWriteFitsImage (const pmFPAview *view, pmFPAfile *file);

// look for the given argname on the argument list.  find the give filename from the file rules
pmFPAfile *pmFPAfileFromArgs (bool *found, pmConfig *config, char *filename, char *argname);

// look for the given argname on the argument list.  find the give filename from the file rules
pmFPAfile *pmFPAfileFromConf (bool *found, pmConfig *config, char *filename, pmFPA *input);

// create a new output pmFPAfile based on an existing FPA
pmFPAfile *pmFPAfileFromFPA (pmConfig *config, pmFPA *src, int xBin, int yBin, char *filename);

// add the specified filename info (value) to the files of the given mode using the given reference name
bool pmFPAfileAddFileNames (psMetadata *files, char *name, char *value, int mode);

// convert the rule to a name based on the current view
char *pmFPAfileNameFromRule (char *rule, pmFPAfile *file, const pmFPAview *view);

bool pmFPAfileCopyView (pmFPA *out, pmFPA *in, const pmFPAview *view);

bool pmFPAfileCopyStructureView (pmFPA *out, pmFPA *in, psMetadata *format, int xBin, int yBin, const pmFPAview *view);

# endif
