/** @file  pmFPA_JPEG.c
 *
 * This file contains functions to write JPEG images.
 *
 *  @author EAM, IfA
 *
 *  @version $Revision: 1.1.2.1 $ $Name: not supported by cvs2svn $
 *  @date $Date: 2006-04-14 21:43:59 $
 *
 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
 *
 */

/*****************************************************************************/
/* INCLUDE FILES                                                             */
/*****************************************************************************/

#include <pslib.h>
# include "psImageJpeg.h"
# include "psImageUnbin.h"
# include "psAdditionals.h"

#include "pmHDU.h"
#include "pmFPA.h"
#include "pmFPAfile.h"
#include "pmFPAview.h"
#include "pmFPA_JPEG.h"


bool pmFPAviewWriteJPEG (const pmFPAview *view, pmFPAfile *file)
{

    pmFPA *fpa = file->fpa;

    if (view->chip == -1) {
        pmFPAWriteJPEG (fpa, view, file);
        return true;
    }

    if (view->chip >= fpa->chips->n) {
        return false;
    }
    pmChip *chip = fpa->chips->data[view->chip];

    if (view->cell == -1) {
        pmChipWriteJPEG (chip, view, file);
        return true;
    }

    if (view->cell >= chip->cells->n) {
        return false;
    }
    pmCell *cell = chip->cells->data[view->cell];

    if (view->readout == -1) {
        pmCellWriteJPEG (cell, view, file);
        return true;
    }

    if (view->readout >= cell->readouts->n) {
        return false;
    }
    pmReadout *readout = cell->readouts->data[view->readout];

    pmReadoutWriteJPEG (readout, view, file);
    return true;
}

// read in all chip-level JPEG files for this FPA
bool pmFPAWriteJPEG (pmFPA *fpa, const pmFPAview *view, pmFPAfile *file)
{

    for (int i = 0; i < fpa->chips->n; i++) {

        pmChip *chip = fpa->chips->data[i];
        pmChipWriteJPEG (chip, view, file);
    }
    return true;
}

// read in all cell-level JPEG files for this chip
bool pmChipWriteJPEG (pmChip *chip, const pmFPAview *view, pmFPAfile *file)
{

    for (int i = 0; i < chip->cells->n; i++) {

        pmCell *cell = chip->cells->data[i];
        pmCellWriteJPEG (cell, view, file);
    }
    return true;
}

// read in all readout-level JPEG files for this cell
bool pmCellWriteJPEG (pmCell *cell, const pmFPAview *view, pmFPAfile *file)
{

    for (int i = 0; i < cell->readouts->n; i++) {

        pmReadout *readout = cell->readouts->data[i];
        pmReadoutWriteJPEG (readout, view, file);
    }
    return true;
}

// read in all readout-level Objects files for this cell
bool pmReadoutWriteJPEG (pmReadout *readout, const pmFPAview *view, pmFPAfile *file)
{
    char *name, *mode, *word, *mapname;
    psArray *range;
    psImageJpegColormap *map;

    switch (file->type) {
    case PM_FPA_FILE_JPEG:

        name = pmFPAfileNameFromRule (file->filerule, file, view);

        mapname = pmFPAfileNameFromRule (file->filextra, file, view);
        map = psImageJpegColormapSet (NULL, mapname);
        if (!map) {
            map = psImageJpegColormapSet (NULL, "-greyscale");
        }

        mode = pmFPAfileNameFromRule (file->extrule, file, view);
        word = pmFPAfileNameFromRule (file->extxtra, file, view);
        range = psStringSplitArray (word, ":");

        // XXX we need to decide where the scale will come from in the long term
        psImageClippedStatsInit (10000);

        psStats *stats = psImageClippedStats (readout->image, NULL, 0, 0.25, 0.75);
        float delta = stats->robustUQ - stats->robustLQ;
        float min = stats->robustMedian - 3*delta;
        float max = stats->robustMedian - 6*delta;
        if (!strcasecmp (mode, "RANGE") && range) {
            float fmin = atof(range->data[0]);
            float fmax = atof(range->data[1]);
            min = stats->robustMedian + fmin*delta;
            max = stats->robustMedian + fmax*delta;
        }
        if (!strcasecmp (mode, "FRACTION")) {
            float fmin = atof(range->data[0]);
            float fmax = atof(range->data[1]);
            min = fmin*stats->robustMedian;
            max = fmax*stats->robustMedian;
        }
        psImageJpeg (map, readout->image, name, min, max);

        psFree (name);
        psFree (mode);
        psFree (word);
        psFree (mapname);
        psFree (map);
        psFree (stats);
        psImageClippedStatsCleanup ();

        return true;

    default:
        fprintf (stderr, "warning: type mismatch\n");
        break;
    }
    return false;
}
