/*
 *   XPP - The X Printing Panel
 *   --------------------------
 *
 *   Definition of the "printFiles" class which is the central class of
 *   XPP for handling the printers, their options and the files to print
 *
 *   Copyright 2000 by Till Kamppeter
 *
 *   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-1307  USA
 *
 */

/*
 * Include necessary headers...
 */

#ifndef xpp_h
#define xpp_h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <cups/cups.h>
#include <cups/ipp.h>
#include <cups/language.h>
#include <cups/ppd.h>
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Pack.H>
#include <FL/Fl_Scroll.H>
#include <FL/Fl_Valuator.H>
#include <FL/Fl_Round_Button.H>
#include <FL/Fl_Tabs.H>
#include <FL/Fl_Choice.H>
#include <FL/Fl_Menu_Button.H>
#include <FL/Fl_Secret_Input.H>
#include <FL/Fl_Multi_Browser.H>
#include <FL/Fl_Menu_Item.H>
#include <FL/Fl_Value_Slider.H>
#include <FL/fl_message.H>
#include <FL/fl_ask.H>
#include "inputslider.h"
#include "cupshelper.h"

// data structure for numerical/string/password options of Foomatic
typedef struct {
  char keyword[41], // option keyword
       text[81];    // human-readable description for GUIs
  int type;         // 0: integer, 1: float, 2: string, 3: password
  double min,       // minumum value
         max,       // maximum value
         defvalue;  // numerical default value
  char defstr[1024];// string/password default value
  int havedefault;  // 0: No default value found, 1: Default value found
} special_opt_t; 

class printFiles {

public:

  static const int     BLOCK_SIZE = 1024; /* Block size for dynamically resized
                                             string 'filelist' */
  static const int     MENU_WIDTH  = 450; /* Width of the printers menu */
  static const int     MENU_HEIGHT = 140; /* Height of the printers menu */
  static const int     ITEM_HEIGHT =  20; /* Height of one menu item */
  static const int     INFO_HEIGHT =  16; /* Height of the info line */

  const char    *STDIN_STR;     /* Key word representing standard
                                   input in 'filelist' */
  int		job_id;		/* Job ID */
  const char	*dest;		/* Destination printer */
  const char	*instance;	/* instance of destination printer */
  const char    *default_pr;    /* Default printer defined under CUPS */
  int           dest_pos;       /* Position of destination entry in list */
  const char	*title;		/* Job title */
  const char    *extra_options; /* Extra options */
  int           priority;       /* Job priority (1-100) */
  int		num_copies;	/* Number of copies per file */
  int		file_printed;	/* Was there a file to print? */
  int		deletefile;	/* Delete file after print? */
  char		buffer[8192];	/* Copy buffer */
  char          *filelist;      /* list of files to print */
  FILE		*temp;		/* Temporary file pointer */
  int           num_dests;      /* Number of accessible printers */
  cups_dest_t   *dests;         /* List of all accessible printers */
  ppd_file_t    **ppds;         /* The PPDs for all printers */
  special_opt_t **special_opts; /* Foomatic numerical/string options */
  int           *num_special_opts; /* number of num options */
  char          **menu_strs;    /* The menu entries for all printers */
  Fl_Pack       *printerPack;   /* Container for the printer menu items */
  Fl_Round_Button **menu_buttons; /* The menu buttons for all printers */
  Fl_Box        **info_lines;       /* info lines below the menu entries */
  int           dest_set_ext;   /* Already set a valid destination because
                                   of a command line option? */
  int           num_changed_options; /* Number of options changed in the
                                        option dialog */
  cups_option_t *changed_options; /* options changed in the option dialog */
  int           conflicting;      /* Are there conflicting options */
  Fl_Tabs       *tabgroup;        /* tabs field of the option dialog */
  Fl_Choice     *papersourcewidget, /* Printer-dependent options in the */
                *papersizewidget,   /* "Basic"-options tab. These pointers */
                *papertypewidget,
                *duplexwidget;      /* allow changing the possible choices */
                                    /* to the ones given by the PPD file */
  Input_Slider    *topmargin,       /* These pointers allow adapting the */
                  *bottommargin,    /* sliders for the text file margins */
                  *leftmargin,      /* to the paper size */
                  *rightmargin;
  Fl_Group	  *papercustomsizewidget;
  int		  custom_width_pspt;
  int		  custom_height_pspt;
  int		  custom_set;
  int             inited;
  
  /*
   *  Parse command line options and set up printer menu
   */

  printFiles(int  argc,		/* I - Number of command-line arguments */
             char *argv[],	/* I - Command-line arguments */
             int &exitstat);    /* O - != 0 if an error occurred */

  /*
   *  Update variables dest and destpos to the destination chosen in the menu
   */

  void setDest();

  /*
   *  Insert the printer list in a scroll box
   */

  void insertPrinterList(Fl_Scroll *o); /* The scroll box where to insert
                                           the list */

  /*
   *  Print the files when 'Print' button is clicked
   */

  void print(int &exitstat);

  /*
   *  Print from Standard Input
   */

  void printStdin(int &exitstat, cups_option_t *options, int num_options);

  /*
   * initialize banner page buttons
   */

  void initBannerMenues(Fl_Choice *before, Fl_Choice *after); 
                                                    /* banner menues */

  /*
   * Enter changes on the banner settings into the attribute list
   */

  void setBannerChanges(Fl_Choice *before, Fl_Choice *after); 
                                                    /* banner menues */

  /*
   * Read Foomatic numerical/string options from the PPD file
   */

  int /* O - index of the record of the given option in the array */
  getSpecialOptionIndex(int *num_special_opts_in_arr,
				      /* number of options in the array */
				      special_opt_t **special_opts_arr,
                                      /* array of numerical/string 
					 options */
				      const char *option);

  int /* O - number of numrical/string options for the current printer */
  getSpecialOptions(special_opt_t **special_opts_arr);
             /* array of numerical/string options */

  /*
   *  Determine the value of an option, taking into account PPD file options,
   *  options from "~/.lpotions", and command line options
   */

  int                                       /* O - menu pos. of item */ 
  getChosenValue(const char *option1,
		 const char *option2,       /* I - options to examine */
                 const Fl_Menu_Item *values); /* I - check value in this 
                                               menu */

  /*
   *  Get value of an option from "~/.lpotions" or command line
   */

  const char *                        /* O - value */
  getOptionValue(const char *option); /* I - option to examine */

  /*
   *  remove an option from an option list
   */

  int                                           /* new # of options */
  removeOptions(const char *option,             /* which option */
                int option_list_length,         /* # opt in list */
                cups_option_t **option_list);   /* from which list */

  /*
   * Get default page size and margins of a printer and read yje margin
   * settings from the user-supplied options
   */

  int                           /* O - user-supplied settings exist? */
  getPageMargins(int &top, int &bottom, int &left, int &right,
                                /* O - obtained values of margins */
                 int &length, int &width, int &orientation);
                                /* O - obtained height and width of the page */
				/* O - orientation */

  int                           /* O - user-supplied settings exist? */
  getPageMargins(int &top, int &bottom, int &left, int &right,
                                /* O - obtained values of margins */
                 int &length, int &width);
                                /* O - obtained height and width of the page */

  /*
   *  Scan PPD file to build the widgets for the printer-specific options
   */

  void buildOptionWidgets();

  /*
   *  Remove all groups of PPD options
   */

  void removeOptionWidgets();

  /*
   *  Refresh all groups of PPD options
   */

  void refreshOptionWidgets();

  /*
   *  Callback function for the option widgets
   */

  inline void cbiPickOneOption(Fl_Widget* o, // From which widget
			                     // we are called
                              void* v);      // option to add

  static void cbPickOneOption(Fl_Widget* o,  // From which widget
			                     // we are called
                              void* v);      // option to add

  inline void cbiPickManyOption(Fl_Widget* o,// From which widget
				             // we are called
                              void* v);      // option to add

  static void cbPickManyOption(Fl_Widget* o, // From which widget 
                                             // we are called
                              void* v);      // option to add

  inline void cbiNumericalOption(Input_Slider* o,
                                             // From which widget 
                                             // we are called
                              void* v);      // option to change

  static void cbNumericalOption(Input_Slider* o,
                                             // From which widget 
				             // we are called
                              void* v);      // option to change

  inline void cbiStringInput(Fl_Widget* o,
					     // From which widget
					     // we are called
			      void* v);      // option to add

  static void cbStringInput(Fl_Widget* o, 
					     // From which widget 
					     // we are called
			      void* v);      // option to add

  inline void cbiStringInputMenu(Fl_Widget* o,
					     // From which widget
					     // we are called
			      void* v);      // option to add

  static void cbStringInputMenu(Fl_Widget* o, 
					     // From which widget 
					     // we are called
			      void* v);      // option to add

  /*
   *  Set up destination list
   */

  void setupDestinationList(Fl_Choice* destChoice); // Widget where to fill
                                                    // in the destination
                                                    // names

  /*
   *  Copy an instance of a destination
   */

  int copyInstance(int dest_index,           // Index of the destination to 
		                             // copy
                    const char *new_name);   // Name of the new instanc

  /*
   *  Delete an instance of a destination
   */

  int deleteInstance(int dest_index);        // Index of the destination to 
		                             // delete

  /*
   *  Free all memory used for dynamical structures
   */

  ~printFiles();

};

#endif
