/*
 * $Id: imview.hxx,v 4.3 2004/06/23 08:22:48 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.
 * */

/*------------------------------------------------------------------------
 *
 * Main include file for imview, an application for displaying image
 * under X11 and the Windows (tm) GDI.
 *
 * Hugues Talbot	26 Oct 1997
 *
 * Usage is free of charge for anyone under no guarantee whatsoever,
 * expressed or implied.
 *
 *-----------------------------------------------------------------------*/

#ifndef IMVIEW_H
#define IMVIEW_H

#include <imcfg.h> // defines all sorts of things...

#include <string>

#include <FL/Fl.H>
#include <FL/Fl_Menu.H>
#include <FL/Fl_Menu_Bar.H>

#ifndef WIN32
//#include <vector> // OK, a header that defines  needs to be included 
//using namespace std;
#endif

using std::string;

// Constants
#define SHEIGHT 400
#define SWIDTH  600
#define MINHEIGHT  100
#define MINWIDTH   280
#define MAXWIDTH   1024
#define MAXHEIGHT  768
#define MENUHEIGHT 30
#define TBOXWIDTH 460
#define TBOXHEIGHT 100

#define DFLTSTRLEN     1024
#define SMALSTRLEN     128

#define MAX_FL_COLOURS 292 // a weird number, but heh.

// Installation path
#if !defined(PrefPath)
#define PrefPath  "/usr/local/share/Imview"
#endif


#ifdef WIN32
// win32 doesn't have basename(), so we do the bit by hand
#  define IMVIEW        "imview"
#  define PATHSEP       ','   // Windows/DOS path use :, as in D:\mydir
#  define SLASH         '\\'
#else
#  define PATHSEP       ':'   // traditionally, Unix path use : as separators
#  define SLASH         '/'   // POSIX directory slash
#endif

// prefix to debug messages
#define DEBUGPROMPT  "Imview> "
#define SRVDBGPRMPT  "Server Imview> "
#define SRVIDBGPRMPT "Server Internal> "
#define ERRORPROMPT  "**error** Imview> "

// default point file name
#define DEFAULTPF   "pointfile"
#define ANNOTEHDR   "# annotation: "

// overlay image marker
#define OVERLAY_MARKER "<overlay>"

// default port file name
#define DEFAULT_PORT_FILE "portfile"
#define PF_MAX_LEN        1023  // max length of port file name

#define CLUT_SUFFIX ".lut"

// trivial macros
#ifndef trivmin
#define trivmin(x,y) ((x) > (y)) ? (y):(x)
#endif

#ifndef trivmax
#define trivmax(x,y) ((x) < (y)) ? (y):(x)
#endif

// page sizes 
// needed by both io/cpostscript.cxx and io/readps.cxx
typedef enum {
    PAGESIZE_AUTO = 0,
    PAGESIZE_A5,
    PAGESIZE_B5,
    PAGESIZE_A4,
    PAGESIZE_LETTER,
    PAGESIZE_LEGAL,
    PAGESIZE_A3,
    PAGESIZE_NB /* size of array needed */
} page_size;

// image types and pixel types

typedef enum {
    IM_INVALID = 0,
    IM_BINARY=10,
    IM_CHAR=31,    IM_INT1 = 31, IM_UINT1 = 30,
    IM_SHORT = 35, IM_INT2 = 35, IM_UINT2 = 37,
    IM_INT = 40,   IM_INT4 = 40, IM_UINT4 = 42,
    IM_INT8 = 43,  IM_UINT8 = 44, 
    IM_FLOAT=45,   IM_DOUBLE=50
} pixtype;

/*-- Multi-component image types --*/
typedef enum { IM_ERROR=0, IM_UNSPEC, IM_SINGLE, IM_SPECTRUM, IM_RGB, IM_HLS } imgtype;

/* the colour used in the bivariate histogram */
typedef enum {BHPBlack = FL_BLACK,
	      BHPRed=FL_RED,
	      BHPGreen=FL_GREEN,
	      BHPYellow=FL_YELLOW,
	      BHPBlue=FL_BLUE,
	      BHPMagenta=FL_MAGENTA,
	      BHPCyan=FL_CYAN
	     } BHPColour;

// the valid image  formats

typedef enum {
    TIFF_FMT = 0,
    ZIMAGE_FMT = 1,
    EURO_FMT = 2,
    PNG_FMT = 3,
    JPG_FMT = 4,
    LAST_FMT = 5
} imgfmt;

// panel IDS
typedef enum{SPECTRAPANEL=0, PROFILEPANEL} paneltype;

// orientations
typedef enum {
    STR_NE=0,
    STR_SE,
    STR_SW,
    STR_NW,
    STR_QUAD_MAX
} str_quadrant;

// filemap

class image_psfile {
public:
    image_psfile(void) {}
    image_psfile(const image_psfile &i) {filename_ = i.getfilename(); hash_ = i.gethash();}
    image_psfile(const string &fn, const string &hh) {filename_ = fn; hash_ = hh;}
    image_psfile& operator=(image_psfile &i) {
        if (this == &i)
            return *this; // nothing more
        filename_ = i.getfilename();
        hash_ = i.gethash();
    }
    const string getfilename(void) const {return filename_;}
    void setfilename(const string &s) {filename_ = s;}
    const string gethash() const {return hash_;}
    void sethash(const string &s) {hash_ = s;}
private:
    string filename_;
    string hash_;
};


// simple useful typedefs
typedef unsigned char uchar;

// this structure is used to store extra information
// about the images in the image list.
typedef struct image_parm {
    char             *itempath;  // used to index the structure...
    char             *clutpath;  // path to the CLUT used by the image
    char             *ovlpath;   // path to overlay, if any
    char             *pfpath;    // path to pointfile, if any
    int               zslice;    // 3rd dimension slice to display
    int               comp;      // component to show
    int               frame;     // frame to show
    int               nbframes;  // total number of frames in image
    float             gamma;     // gamma factor to be used
    float             contrast;  // contrast to use
    float             brightness; // same for brightness
    double            Rgamma, Rbrightness, Rcontrast; // RGB version 
    double            Ggamma, Gbrightness, Gcontrast; 
    double            Bgamma, Bbrightness, Bcontrast; 
    float             angle;      // Remember the angle
    char              mirror;     // Remember the mirror state (0 or 1)
    struct item_xtra *next;      // next in list
} IMAGEPARM;

// image header, useful when receiving raw binary data
typedef struct imagecomp_header {
    int             nx, ny, nz;              // size
    int             ox, oy, oz;              // offset
    imgtype         imgt;                    // types 
    pixtype         pixt;                    // ....
    int             spp;                     // samples per pixel
    void          **buffp;                   // array of buffers (one per spectrum.)
} IMAGECOMP_HEADER;

typedef struct image_header {
    char                *label;                   // image name or label
    unsigned int         unique_id;               // necessary to find the right buffer, assumed to be 4 bytes
    unsigned int         previous_id;             // ID of previous buffer
    unsigned int         expected_size;
    bool                 needswap;                // if the data comes from a diffent-endian machine
    int                  nbc;                     // nb of components
    void                *rawdata;                 // pointer to raw data, needed when freed.
    IMAGECOMP_HEADER    *comp;                    // array of components
} IMAGE_HEADER;


// this structure is sufficiently different from the `socket' raw data
// that it warrants its own type.
typedef struct rawfile_header {
    int            nx, ny, nz;
    int            spp, byo;  // sample per pixels = nb of bands; byo = byte ordering
    int            itl;       // interleave type
    pixtype        pixt;
    int            filesize;  // if changed!
    int            skip;      // need to remember this too!
} RAWFILE_HEADER;

// the `bivariate histogram point' class. Has to be small
class BHPoint {
public:
    BHPoint(void) { return;}
    BHPoint(BHPColour c, int i, double dx, double dy) {
	colour = c;
	imgOffset = i;
	Xvalue = dx;
	Yvalue = dy;
    }
    BHPColour colour;          // 255 different colours should be enough
    int       imgOffset;       // offset in the original image. Enough for a cube 1600 pixels aside.
    double    Xvalue, Yvalue;  // values of the point in both components.
};

// this predicate class to be used to sort the points
class cmpBHPoints {
public:
    bool operator() (const BHPoint &a, const BHPoint &b) const;
};



// prototypes for C-like functions

void run(void);
Fl_Menu_Bar *makeMenu(void);
// this functions checks the argument and return an image list.
void huntCLUT(const char **clutpathlist);
void checkArgs(int argc, char **argv, char ***imlist, char ***lutlist);
void showSimpleBanner(void);
void removeSimpleBanner(void);
void displayImages(char **imageList, char **lutList);

void filechooser_cb(const char *name);
int arg_cb(int argc, char **argv, int &i);

// server startup function
void start_server(void);
// exit/cleanup function
void imview_exit(int status, bool abort = false);

// debugging function
int dbgprintf(const char *msg, ...);
int stderrprintf(const char *msg, ...);
int srv_dbgprintf(const char *msg, ...);
int srv_internal_dbgprintf(const char *msg, ...);
int srv_printf(const char * msg,...);
// error printing function
int errprintf(const char *msg, ...);
// warning printing function
int warnprintf(const char * msg,...);

// utility colour function
Fl_Color fl_closest_colour(uchar r, uchar g, uchar b);
Fl_Color fl_closest_index(int i);

// from the FL directory
// defines the very important snprintf
#if !HAVE_SNPRINTF
#include <stdio.h>
#include <stdarg.h>
extern "C" {
int snprintf(char* str, size_t size, const char* fmt, ...);
}
#endif /* !HAVE_SNPRINTF */

#if !HAVE_VSNPRINTF
#include <stdio.h>
#include <stdarg.h>
extern "C" {
int vsnprintf(char* str, size_t size, const char* fmt, va_list ap);
}
#endif /* !HAVE_VSNPRINTF */


// puzzling missing prototype
// not missing anymore in RH >= 5.0
// missing againg in 6.1
//#ifdef Linux
//extern "C" {
//    const char *basename(const char *name);
//}
//#endif

#if defined(Solaris) || defined(Linux)
#include <libgen.h> // isn't that totally incredible?
#endif



#endif
