/*
 * $Id: printSpect.cxx,v 4.0 2003/04/28 14:39:56 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 print preference panel using fluid.
 *
 * Hugues Talbot	21 Apr 1998
 *      
 *-----------------------------------------------------------------------*/

#include <stdio.h>
#include <stdlib.h>
#include "imunistd.h"
#include <string.h>
#include <errno.h>
#include <setjmp.h>
#include <signal.h>
#include <FL/Fl_File_Chooser.H>
#include <FL/fl_ask.H>
#include "imview.hxx"
#include "io/imSystem.hxx"
#include "imageIO.hxx"
#include "imageViewer.hxx"
#include "spectraBox.hxx"
#include "profileBox.hxx"
#include "io/gplot2.hxx"
#include "printSpect.hxx"

extern char appName[];
extern imageIO *IOBlackBox;
extern profile     *profilePanel;
extern spectra     *spectraPanel; 

// print panel methods

printspect::printspect()
{
    dbgprintf("Print panel constructed\n");
    prefWindow = 0; // fluid depend on that...
    return;
}

void printspect::setDefaults()
{
    static char buff[100];
    char *myenv;

    // we print to a real printer by default
    printerCheck->set();

    // default printing output
    if ((myenv = getenv("PRINTER")) != 0)
	sprintf(buff, "lpr -P%s", myenv);
    else
	strcpy(buff, "lpr");
    commandInput->value((const char *)buff);

    // default value for file
    sprintf(buff, "%s.ps", appName);
    filenameInput->value(buff);

    // empty title is fine...

    // orientation should be landscape
    landscapeCheck->set();

    // Paper size should be A4
    A4Check->set();
    
    // no smoothing by default
    linesCheck->set();

    // number of copies should be just one
    nbcopiesInput->value("1");

    // Panel is SPECTRA by default.
    whichPanel = SPECTRAPANEL;
    // that's it
    
    return;
}

// this method switches between the `File' and the `Printer' defaults
void printspect::toggleToFile()
{
    // disable the Print command
    commandInput->deactivate();
    commandInput->color(47); // got that from fluid...
    commandInput->textcolor(31);
    commandInput->labelcolor(31);
    // enable the "file" command
    filenameInput->activate();
    filenameInput->color(43);
    filenameInput->textcolor(FL_BLACK);
    filenameInput->labelcolor(FL_BLACK);
    // enable the browse button
    browseButton->activate();
    browseButton->labelcolor(FL_BLACK);

    prefWindow->redraw();
    
    return;
}

void printspect::toggleToPrinter()
{
    // disable the Print command
    filenameInput->deactivate();
    filenameInput->color(47); // got that from fluid...
    filenameInput->textcolor(31);
    filenameInput->labelcolor(31);
    // enable the "file" command
    commandInput->activate();
    commandInput->color(43);
    commandInput->textcolor(FL_BLACK);
    commandInput->labelcolor(FL_BLACK);
    // disable the browse button
    browseButton->deactivate();
    browseButton->labelcolor(31);

    prefWindow->redraw();

    return;
}

void printspect::allowTitle(bool b)
{
    if (b) {
	// setting the title is allowed
	titleInput->activate();
	titleInput->color(43); // fluid...
	titleInput->textcolor(FL_BLACK);
	titleInput->labelcolor(FL_BLACK);
    } else {
	titleInput->deactivate();
	titleInput->color(47);
	titleInput->textcolor(31);
	titleInput->textcolor(31);
    }
    
    prefWindow->redraw();
    
    return;
}

void printspect::printFileName(const char *fn)
{
    // this copies it to something more permanent.
    filenameInput->value(fn);
    return;
}


int printspect::doThePrinting()
{
    int     retval = 0; 
    char    papertype; 
    char    jointype; 
    char    orientation;
    int     nbcopies; 
    char   *title, *filename = 0, *pipeCommand = 0; 
    static char tmptitle[1024];
    int     nx = 0;
    double *dbuff = 0, *rbuff = 0, *gbuff = 0, *bbuff = 0;


    if (whichPanel == SPECTRAPANEL) {
	nx = spectraPanel->getNbVal();
	dbuff = spectraPanel->getData();
    } else if (whichPanel == PROFILEPANEL) {
	nx = profilePanel->getNbVal();
	dbuff = rbuff = profilePanel->getDataR();
	gbuff = profilePanel->getDataG();
	bbuff = profilePanel->getDataB();
    }
    
    if (dbuff != 0) {
	// get all the options now
	if (A3Check->value()) papertype = A3_PAGE;
	else if (letterCheck->value()) papertype = LETTER_PAGE;
	else papertype = A4_PAGE;

	if (landscapeCheck->value()) orientation = LANDSCAPE;
	else orientation = PORTRAIT;

	if (linesCheck->value()) jointype = LINES;
	else jointype = SPLINES;
    
	nbcopies = trivmax(atoi(nbcopiesInput->value()), 1);

	title = (char *)(titleInput->value());
	if ((title != 0) && (title[0] == '\0'))
	    title = 0; // empty string
    
	// open the pipe!
	if (printerCheck->value()) {
	    // we pipe to a command, which hopefully will print
	    // (not our problem if it doesn't...

	    // get the pipe command
	    pipeCommand = (char *)commandInput->value();
	    if ((pipeCommand != 0) && (pipeCommand[0] == '\0')
		|| (pipeCommand == 0)) {
		errprintf("Please specify a print command\n");
		retval = 1;
	    } else {
		// prepare a `pipe file name'
		strcpy(tmptitle, "|");
		strcat(tmptitle, pipeCommand);
		filename = tmptitle;
	    }
	
	} else {
	    // we send to a file
	    filename = (char *)filenameInput->value();
	    if ((filename != 0) && (filename[0] == '\0')
		|| (filename == 0)) {
		errprintf("Please specify a file to print to\n");
		retval = 4;
	    } else {
		if (access(filename, W_OK) == 0) {
		    // the file aready exist, do we really want to do this?
		    static char alrtmsg[1024];
		    sprintf(alrtmsg,
			    "File %s already exists\n"
			    "Do you want to overwrite?\n",
			    filename);
		    if (fl_ask(alrtmsg) == 0) {
			retval = 6;
		    } 
		} 
	    }
	}

	if (retval == 0) {
	    // all is fine, we can send the postscript code away.
	    dbgprintf("Composing gnuplot code\n");
	    thePlot = openPlot(title);
	    if (thePlot != 0) {
		send2plot(thePlot, "set terminal postscript %s",
			  (orientation == PORTRAIT)? "eps": "");
		send2plot(thePlot, "set output \"%s\"", filename);
		if (whichPanel == SPECTRAPANEL) {
		    send2plot(thePlot,
			      "set xlabel 'Spectrum of %s at position x=%d, y=%d'",
			      IOBlackBox->getImName(),
			      spectraPanel->getXpos(),
			      spectraPanel->getYpos());
		    plotDoubles(dbuff, nx, thePlot,
				(jointype == SPLINES));
		} else if (whichPanel == PROFILEPANEL) {
		    double *vecs[3];
		    char   *lbl[3];
		    int     len[3];
		    send2plot(thePlot, "set data style lines");
		    send2plot(thePlot,
			      "set xlabel 'Profile of %s from position x=%d, y=%d"
			      " to position x=%d, y=%d'",
			      IOBlackBox->getImName(),
			      profilePanel->getXstart(),
			      profilePanel->getYstart(),
			      profilePanel->getXend(),
			      profilePanel->getYend());
		    vecs[0] = rbuff;
		    vecs[1] = gbuff;
		    vecs[2] = bbuff;
		    lbl[0] = "Red";
		    lbl[1] = "Green";
		    lbl[2] = "Blue";
		    len[0] = len[1] = len[2] = nx;
		    dataMPlot(thePlot,
			      // this is to show that we know what we are talking about...
			      (char * (*) (...))writeDoubleVector, 
			      3,
			      (void**)vecs,
			      lbl,
			      len,
			      0); // no splines			      
		}

		closePlot(thePlot);
	    }
		
	}
    }

    return retval;
}


int printspect::doThePreview()
{
    int     retval = 0;
    char    jointype;
    char   *title;
    int     nx = 0; 
    double *dbuff = 0, *rbuff = 0, *gbuff = 0, *bbuff = 0;

    if (whichPanel == SPECTRAPANEL) {
	nx = spectraPanel->getNbVal();
	dbuff = spectraPanel->getData();
    } else if (whichPanel == PROFILEPANEL) {
	nx = profilePanel->getNbVal();
	dbuff = rbuff = profilePanel->getDataR();
	gbuff = profilePanel->getDataG();
	bbuff = profilePanel->getDataB();
    }
    
    if (dbuff != 0) {
	if (linesCheck->value()) jointype = LINES;
	else jointype = SPLINES;
    
	title = (char *)(titleInput->value());
	if ((title != 0) && (title[0] == '\0'))
	    title = 0; // empty string
    

	// all is fine, we can send the postscript code away.
	dbgprintf("Composing gnuplot code\n");
	thePlot = openPlot(title);
	if (thePlot != 0) {
	    if (whichPanel == SPECTRAPANEL) {
		char    xlabel[1024];
		
		sprintf(xlabel, "spectrum of %s at position x=%d, y=%d",
			IOBlackBox->getImName(),
			spectraPanel->getXpos(),
			spectraPanel->getYpos());
		send2plot(thePlot, "set xlabel '%s'", xlabel);
		plotDoubles(dbuff, nx, thePlot,
			    (jointype == SPLINES));
	    } else if (whichPanel == PROFILEPANEL) {
		double *vecs[3];
		char   *lbl[3];
		int     len[3];
		send2plot(thePlot, "set data style lines");
		send2plot(thePlot,
			  "set xlabel 'Profile of %s from position x=%d, y=%d"
			  " to position x=%d, y=%d'",
			  IOBlackBox->getImName(),
			  profilePanel->getXstart(),
			  profilePanel->getYstart(),
			  profilePanel->getXend(),
			  profilePanel->getYend());
		vecs[0] = rbuff;
		vecs[1] = gbuff;
		vecs[2] = bbuff;
		lbl[0] = "Red";
		lbl[1] = "Green";
		lbl[2] = "Blue";
		len[0] = len[1] = len[2] = nx;
		dataMPlot(thePlot,
			  (char * (*) (...))writeDoubleVector,
			  3,
			  (void **)vecs,
			  lbl,
			  len,
			  0); // no splines	
	    }
	}
    }
    return retval;
}

int printspect::closePreview()
{
    if (thePlot != 0)
	closePlot(thePlot);

    return 0;
}

void printspect::show()
{
    prefWindow->show();
    return;
}

void printspect::hide()
{
    prefWindow->hide();
    return;
}

    

// print panel associated callbacks

void printercheck_cb(Fl_Check_Button *, printspect *panel)
{
    dbgprintf("Printer check callback\n");
    panel->toggleToPrinter();
    
    return;
}

void filecheck_cb(Fl_Check_Button *, printspect *panel)
{
    dbgprintf("File check callback\n");
    panel->toggleToFile();

    
    return;
}

void commandInput_cb(Fl_Input *, printspect *)
{
    dbgprintf("Command input callback\n");

    return;
}

void filenameInput_cb(Fl_Input *, printspect *)
{
    dbgprintf("filename input callback\n");

    return;
}

void browsebutton_cb(Fl_Button *, printspect *panel)
{
    const char *currentfile;
    static const char *p = 0;

    dbgprintf("Browse Button pressed on print prefs panel\n");

    currentfile = panel->filenameInputValue();
    
    p = fl_file_chooser("Print to file", "*[pP][sS]", currentfile);
			
    if (p) panel->printFileName(p);
    
    return;
}


void titleInput_cb(Fl_Input *, printspect *)
{
    dbgprintf("title input callback\n");

    return;
}

void portraitcheck_cb(Fl_Check_Button *, printspect *)
{
    dbgprintf("Portrait check callback\n");

    return;
}

void landscapecheck_cb(Fl_Check_Button *, printspect *)
{
    dbgprintf("Landscape check callback\n");

    return;
}


void a4check_cb(Fl_Check_Button *, printspect *)
{
    dbgprintf("A4 check callback\n");

    return;
}

void lettercheck_cb(Fl_Check_Button *, printspect *)
{
    dbgprintf("Letter check callback\n");

    return;
}

void a3check_cb(Fl_Check_Button *, printspect *)
{
    dbgprintf("A3 check callback\n");

    return;
}

void pscheck_cb(Fl_Check_Button *, printspect *panel)
{
    dbgprintf("PS check callback\n");
    panel->allowTitle(true);
    
    return;
}

void epscheck_cb(Fl_Check_Button *, printspect *panel)
{
    dbgprintf("EPS check callback\n");
    panel->allowTitle(false);
    
    return;
}

void nbcopies_cb(Fl_Input *, printspect *)
{
    dbgprintf("Nb of copies callback\n");
    return;
}

void linescheck_cb(Fl_Check_Button *, printspect *)
{
    dbgprintf("Lines check callback\n");
    
    return;
}

void splinescheck_cb(Fl_Check_Button *, printspect *)
{
    dbgprintf("Splines check callback\n");
    
    return;
}


void cancelbutton_cb(Fl_Button *, printspect *panel)
{
    dbgprintf("Cancel Button pressed on print prefs panel\n");
    // hide the window
    panel->hide();
    return;
}

void previewbutton_cb(Fl_Button *b, printspect *panel)
{
    dbgprintf("preview Button pressed on print spect panel\n");
    if (b->value()) panel->doThePreview();
    else panel->closePreview();
    return;
}

// This is really the `print' button...
void okbutton_cb(Fl_Return_Button *, printspect *panel)
{
    dbgprintf("Print Button pressed on print prefs panel\n");
    if (panel->doThePrinting() == 0) {
	// hide the window
	panel->hide();
    } // else leave the panel around for the user to correct things
    return;
}


