/*
 * $Id: rawImage.cxx,v 4.1 2003/05/13 14:55:26 hut66au Exp $
 *
 * Imview, the portable image analysis application
 * http://www.cmis.csiro.au/Hugues.Talbot/imview
 * ----------------------------------------------------------
 *
 *  Imview is an attempt to provide an image display application
 *  suitable for professional image analysis. It was started in
 *  1997 and is mostly the result of the efforts of Hugues Talbot,
 *  Image Analysis Project, CSIRO Mathematical and Information
 *  Sciences, with help from others (see the CREDITS files for
 *  more information)
 *
 *  Imview is Copyrighted (C) 1997-2001 by Hugues Talbot and was
 *  supported in parts by the Australian Commonwealth Science and 
 *  Industry Research Organisation. Please see the COPYRIGHT file 
 *  for full details. Imview also includes the contributions of 
 *  many others. Please see the CREDITS file for full details.
 *
 *  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, USA.
 * */

/*------------------------------------------------------------------------
 *
 * A panel for reading arbitrary uncompressed images.
 *
 * Hugues Talbot	 8 Apr 2000
 *
 * A wish from the Perth group.
 *      
 *-----------------------------------------------------------------------*/

#include "imnmspc.hxx"

#include <stdio.h>
#include <assert.h>
#include <time.h>
#include <sys/stat.h>
#include <map> // STL
#include "imunistd.h"
#include "imview.hxx"
#include "imageIO.hxx"
#include "rawImage.hxx"
#include "menubar.hxx" // for openimage
#include "machine.hxx"

extern imageIO *IOBlackBox;

extern std::map <string, RAWFILE_HEADER> rawfilemap;

// we use a global static array so that the
// callbacks can see it.
static pixtype pixtype_match[NBTYPES] = {
    IM_UINT1, IM_INT2, IM_UINT2,
    IM_INT4, IM_UINT4, IM_INT8,
    IM_UINT8, IM_FLOAT, IM_DOUBLE
};

rawimage::rawimage()
{
    dbgprintf("Raw image panel constructed\n");
    rawimageWindow = 0; // fluid depends on this
    return;
}

void rawimage::setDefaults(void)
{
    // explanatory text
    bannerOutput->value("If you know the image data is uncompressed and you know the image\n"
			"dimensions, you can enter them below; otherwise press Cancel.");
    
    xInput->value("1");
    yInput->value("1");
    zInput->value("1");

    nbBandsInput->value("1");
    bandTypeChoice->deactivate(); // no need if there is only one band
    assignButton->deactivate(); // same

    headerSizeInput->value("0");
    filesizeOutput->value("0");

    // consistent corresponding values
    nx = ny = nz = 1;
    spp = 1;
    interleave = 0; // default from fluid
    byteOrder = 0; // sameg
    ptype = IM_UINT1; // same
    dataSize = headerSize = 0;
    
    dataSize = 0;
    filename = 0; 
}

void rawimage::show()
{
    rebuildBoxTitle();
    rawimageWindow->show();
    return;
}

void rawimage::hide()
{
    rawimageWindow->hide();
    return;
}

void rawimage::recomputeHeader(void)
{
    int header;

    header = computeSkip();

    if (header < 0) {
	headerSizeInput->textcolor(FL_RED);
	OKButton->deactivate();
    } else {
	headerSizeInput->textcolor(FL_BLACK);
	OKButton->activate();
    }

    if (spp > 1) {
	bandTypeChoice->activate();
	assignButton->activate();
    } else {
	bandTypeChoice->deactivate();
	assignButton->deactivate();
    }
    
}

int rawimage::computeSkip(void)
{
    int totaldata;
    
    totaldata = nx*ny*nz*spp * IOBlackBox->typeSize(ptype);
    headerSize = dataSize - totaldata;


    return headerSize;
}

void rawimage::setHeaderInput(void)
{
    char buf[100];
    int v = computeSkip();

    snprintf(buf, 100, "%d", v);
    headerSizeInput->value(buf);
}

void rawimage::saveHeader(void)
{
    RAWFILE_HEADER rfh;

    rfh.nx = nx;
    rfh.ny = ny;
    rfh.nz = nz;
    rfh.spp = spp;
    rfh.byo = byteOrder;
    rfh.itl = interleave;
    rfh.pixt = ptype;
    rfh.filesize = dataSize;
    rfh.skip = headerSize;

    rawfilemap[filename] = rfh; 
}

void rawimage::tryReading(void)
{
    // try reading the file again...
    openimage(filename);
}

// work out the file size as well...
void rawimage::rebuildBoxTitle(void)
{
    static char newTitle[100], fst[20];
    struct stat  statbuf;
    
    assert(filename != 0);
    snprintf(newTitle, 100, "%s: format not recognized", myBaseName(filename));
    titleBox->label(newTitle);

    
    if (stat(filename, &statbuf) == 0)
	dataSize =  statbuf.st_size;
    else
	dataSize = 0;
    
    snprintf(fst, 20, "%d", dataSize);

    filesizeOutput->value(fst);
    
}
//------- callbacks --------
void xinput_cb(Fl_Int_Input *i, rawimage *panel)
{
    int nx;

    nx = atoi(i->value());
    panel->setnx(nx);
}

void yinput_cb(Fl_Int_Input *i, rawimage *panel)
{
    int ny;

    ny = atoi(i->value());
    panel->setny(ny);
}

void zinput_cb(Fl_Int_Input *i, rawimage *panel)
{
    int nz;

    nz = atoi(i->value());
    panel->setnz(nz);
}

void nbband_cb(Fl_Int_Input *i, rawimage *panel)
{
    int spp;

    spp = atoi(i->value());
    panel->setspp(spp);
}

void pixeltype_cb(Fl_Choice *c, rawimage *panel)
{
    int rp = c->value();

    dbgprintf("pixel type callback: chosen %d\n", rp);
    assert((rp >= 0) && (rp < NBTYPES));
    panel->setPixType(pixtype_match[rp]);
}

void interleave_cb(Fl_Choice *c, rawimage *panel)
{
    int leav = c->value();

    dbgprintf("Interleave callback: %d\n", leav);
    assert((leav >= 0) && (leav < NBINTER));
    panel->setInterleave(leav);
	   
}

void byteorder_cb(Fl_Choice *c, rawimage *panel)
{
    int bo = c->value();

    dbgprintf("Byte order callback: %d\n", bo);
    assert((bo >= 0) && (bo < NBBYORD));
    panel->setByteOrder(bo);
    
}

void computeskip_cb(Fl_Button *, rawimage *panel)
{
    panel->setHeaderInput();
}

void headersize_cb(Fl_Int_Input *i, rawimage *panel)
{
    int hs = atoi(i->value());
    dbgprintf("Header size changed to %d\n", hs);
    panel->setHeaderSize(hs);
}

void helpbutton_cb(Fl_Button *, rawimage *panel)
{
    dbgprintf("Help on rawimage called\n");
    return;
}

void cancelbutton_cb(Fl_Button *, rawimage *panel)
{
    panel->hide();
}

void okbutton_cb(Fl_Button *, rawimage *panel)
{
    dbgprintf("OK Button pressed, saving the structure... \n");
    panel->saveHeader();
    panel->tryReading();
    //panel->hide();
}

