/*
 * This file is part of the GIRAFFE Pipeline
 * Copyright (C) 2002-2019 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#ifndef GIUTILS_H
#define GIUTILS_H

#include <cxtypes.h>

#include <cpl_macros.h>
#include <cpl_image.h>
#include <cpl_propertylist.h>
#include <cpl_parameterlist.h>
#include <cpl_frameset.h>


#ifdef __cplusplus
extern "C" {
#endif

    enum GiInstrumentMode {
        GIMODE_NONE   = 0,
        GIMODE_MEDUSA = 1,
        GIMODE_IFU    = 2,
        GIMODE_ARGUS  = 3
    };

    typedef enum GiInstrumentMode GiInstrumentMode;


    enum GiBadPixelFlags {
        /* Good pixel */
        GI_BPIX_OK   = 0x00000,

        /* CCD bad pixel */
        GI_BPIX_CCD  = 0x00001,

        /* CCD hot pixel */
        GI_BPIX_HOT  = 0x00003,

        /* CCD dark pixel */
        GI_BPIX_COLD = 0x00005,

        /* Pixel rejected by dark processing */
        GI_RPIX_DARK = 0x00100,

        /* Pixel rejected by bias processing */
        GI_RPIX_BIAS = 0x00200,

        /* Pixel rejected by multiple CR detection */
        GI_RPIX_CRHM = 0x00400,

        /* Pixel rejected by single CR detection */
        GI_RPIX_CRHS = 0x00800,

        /* Pixel rejected by estimation */
        GI_RPIX_ESTM = 0x01000,

        /* Pixel rejected by optimal extraction */
        GI_RPIX_EXTO = 0x02000,

        /* 2D growing in both directions */
        GI_APIX_ESTM = 0x10000
    };

    typedef enum GiBadPixelFlags GiBadPixelFlags;


    enum GiBadPixelMasks {
        /* CCD bad pixels */
        GI_M_PIX_BAD    = 0x000ff,

        /* Pixels rejected by processing */
        GI_M_PIX_REJECT = 0x0ff00,

        /* Any bad pixel */
        GI_M_PIX_SET    = 0x0ffff
    };

    typedef enum GiBadPixelMasks GiBadPixelMasks;


    struct GiRecipeInfo {
        cxchar* recipe;
        cxint sequence;
        cxchar* start;
        cpl_parameterlist *options;
    };

    typedef struct GiRecipeInfo GiRecipeInfo;


    struct GiGroupInfo {
        const cxchar* tag;
        cpl_frame_group group;
    };

    typedef struct GiGroupInfo GiGroupInfo;


    /*
     * Static information retrieval
     */

    const cxchar* giraffe_get_license(void);


    /*
     * Miscellaneous
     */

    GiInstrumentMode giraffe_get_mode(cpl_propertylist* properties);

    cxchar* giraffe_path_get_basename(const cxchar* path);

    cxchar* giraffe_localtime_iso8601(void);

    cxint giraffe_add_recipe_info(cpl_propertylist* plist,
                                const GiRecipeInfo* info);
    cxint giraffe_add_frameset_info(cpl_propertylist* plist,
                                    const cpl_frameset* set,
                                    cxint sequence);

    cxint giraffe_propertylist_update(cpl_propertylist* self,
                                    cpl_propertylist* properties,
                                    const cxchar* hint);
    cxint giraffe_propertylist_copy(cpl_propertylist* self,
                                    const cxchar* name,
                                    const cpl_propertylist* other,
                                    const cxchar* othername);

    cxint giraffe_frameset_set_groups(cpl_frameset* set, GiGroupInfo* groups);

    cxint giraffe_propertylist_update_wcs(cpl_propertylist* properties,
                                          cxsize naxis,
                                          const cxdouble* crpix,
                                          const cxdouble* crval,
                                          const cxchar** ctype,
                                          const cxchar** cunit,
                                          const cpl_matrix* cd);

    cxdouble giraffe_propertylist_get_conad(const cpl_propertylist* properties);

    cxdouble giraffe_propertylist_get_ron(const cpl_propertylist* properties);

#ifdef __cplusplus
}
#endif

#endif /* GIUTILS_H */
