/***********************************************************************
 *
 * TITLE: filemenu.c
 *
 * AUTHOR: Cassie Mulnix
 *
 * DESCRIPTION:	Creates the pulldown menus on the menu bar
 *
 *                              CHANGE HISTORY
 *
 * $Log: filemenu.c,v $
 * Revision 1.64  1994/12/31  05:05:25  kevin
 * updated shell management
 *
 * Revision 1.63  1994/12/31  04:46:08  kevin
 * removed unused definitions
 *
 * Revision 1.62  1994/12/31  01:20:06  kevin
 * removed redundant file loader
 *
 * Revision 1.61  1994/10/12  18:15:22  cassie
 * fixed BEWARE so it is more meaningful
 *
 * Revision 1.60  1994/08/10  22:06:43  cassie
 * replaced pict and windows buttons with single export button]`
 *
 * Revision 1.59  1994/06/07  16:38:58  clm
 * changed parameters to edit_plot
 *
 * Revision 1.58  1994/06/02  22:25:57  clm
 * added MAC Pict and Windows META files options
 *
 * Revision 1.57  1994/05/20  23:31:43  clm
 * updated with HP, SGI changes
 *
 * Revision 1.56  1994/05/04  23:34:36  clm
 * ported to ANSI C
 *
 * Revision 1.55  1993/10/19  14:40:50  clm
 * updated all oellib stuff
 *
 * Revision 1.54  1993/05/18  20:58:30  clm
 * added new message.c function
 *
 * Revision 1.53  1993/02/20  00:06:31  clm
 * added file title to chart
 *
 * Revision 1.52  1992/12/15  16:12:23  clm
 * used xmTemp for XmStringCreate so string free can be used
 *
 * Revision 1.51  1992/12/09  15:57:57  clm
 * revised for saving file filter as changed during each session
 *
 * Revision 1.50  1992/12/04  17:57:39  clm
 * changed MAX_PLN to npln
 *
 * Revision 1.49  1992/11/24  22:38:56  clm
 * made changes to open_file if load is not successful
 *
 * Revision 1.48  1992/11/24  21:14:21  clm
 * added loc_pline to open_button
 *
 * Revision 1.47  1992/11/09  16:29:12  clm
 * added precedence lines
 *
 * Revision 1.46  1992/10/14  14:34:45  clm
 * added modified = FALSE in new_buttoin
 *
 * Revision 1.45  1992/10/12  20:30:36  clm
 * added id_disp toggle button to option pulldown
 *
 * Revision 1.44  1992/10/06  17:06:33  clm
 * made filename global the same name is used when entering the
 * data file on the command line
 *
 * Revision 1.43  1992/10/05  20:36:50  clm
 * renumber lines after loading file if auto_renum is ON
 *
 * Revision 1.42  1992/10/02  20:16:06  clm
 * housekeeping
 *
 * Revision 1.41  1992/09/24  15:44:03  clm
 * added save of auto_renum toggle
 *
 * Revision 1.40  1992/09/22  22:35:51  clm
 * added utc_bar toggle to internals.c
 *
 * Revision 1.39  1992/09/10  20:03:22  clm
 * fixed load_dsp_size
 *
 * Revision 1.38  1992/09/10  18:01:42  clm
 * added line_init call to new button
 *
 * Revision 1.37  1992/09/10  17:12:13  clm
 * added fileFilter resource
 * removed xopps_init
 *
 * Revision 1.36  1992/09/02  15:33:23  clm
 * added ren_hline call in prev_button and next_button
 *
 * Revision 1.35  1992/08/27  20:13:24  clm
 * locate all objects after load since pg_lines might change
 *
 * Revision 1.34  1992/08/27  17:43:03  clm
 * housekeeping
 *
 * Revision 1.33  1992/08/26  16:40:43  clm
 * added load_dsp_size function to change page_end and page_begin
 * with respect to loaded pg_lines values
 *
 * Revision 1.32  1992/08/26  15:04:39  clm
 * added snap_evt and snap_txt toggle values to internals.c
 * added set toggle functions to set the value in the pulldown
 *
 * Revision 1.31  1992/08/25  20:06:58  clm
 * added beware messages and modified boolean value
 *
 * Revision 1.30  1992/08/25  15:36:30  clm
 * added xlnary and ylnary to new_button and open_button functions.
 *
 * Revision 1.29  1992/08/20  18:06:08  clm
 * added print popup
 *
 * Revision 1.28  1992/08/13  18:06:44  clm
 * fixed renum_tog
 *
 * Revision 1.27  1992/08/10  17:40:56  clm
 * added objary loop to next and prev_buttons
 *
 * Revision 1.26  1992/08/04  16:31:37  clm
 * added previous and next page buttons
 *
 * Revision 1.25  1992/08/03  21:32:58  clm
 * added toggle button for displaying utc bar
 *
 * Revision 1.24  1992/07/13  20:50:21  clm
 * got new_button functioning
 *
 * Revision 1.23  1992/07/10  16:03:41  clm
 * added snap event and snap text toggles
 *
 * Revision 1.22  1992/07/06  17:47:43  clm
 * all horizontal line calls functioning properly
 *
 * Revision 1.21  1992/06/24  17:12:14  clm
 * added renumber toggle and callback
 *
 * Revision 1.20  1992/06/10  15:02:02  clm
 * incorporated chartmenu.c
 *
 * Revision 1.15  1992/05/20  19:50:57  clm
 * cleaned up file and help format
 *
 * Revision 1.14  1992/05/11  22:38:35  kevin
 * renamed project include file to xopps.h
 *
 * Revision 1.1  90/11/13  10:08:56  ana
 * Initial revision
 *
 ***********************************************************************
 *
 * WARNINGS:
 *
 * EXTERNAL CALLABLE COMPONENTS (PUBLIC):
 *
 * GLOBALS:
 *
 * WAIVERS:
 *
 * NOTES:
 *
 * MANPAGE:
 *
 ***********************************************************************/

#ifndef lint
static char rcsid[] =
    "$Id: filemenu.c,v 1.64 1994/12/31 05:05:25 kevin OEL $";
#endif

#include "xopps.h"

#include <unistd.h>
#include <limits.h>
#include <Xm/RowColumn.h>
#include <Xm/CascadeB.h>
#include <Xm/PushBG.h>
#include <Xm/ToggleBG.h>
#include <Xm/MessageB.h>
#define N_BUTTONS 10 

static void new_button(Widget, XtPointer, XmAnyCallbackStruct *);
static void open_button(Widget, XtPointer, XmAnyCallbackStruct *);
static void save_button(Widget, XtPointer, XmAnyCallbackStruct *);
static void save_as_button(Widget, XtPointer, XmAnyCallbackStruct *);
static void print_button(Widget, XtPointer, XmAnyCallbackStruct *);
static void set_dates_button(Widget, XtPointer, XmAnyCallbackStruct *);
static void renum_tog(Widget, XtPointer, XmToggleButtonCallbackStruct *);
static void plot_button(Widget, XtPointer, XmAnyCallbackStruct *);
static void snap_evt_button(Widget, XtPointer, XmToggleButtonCallbackStruct *);
static void snap_txt_button(Widget, XtPointer, XmToggleButtonCallbackStruct *);
static void id_button(Widget, XtPointer, XmToggleButtonCallbackStruct *);
static void utc_bar_button(Widget, XtPointer, XmToggleButtonCallbackStruct *);
static void prev_button(Widget, XtPointer, XmAnyCallbackStruct *);
static void next_button(Widget, XtPointer, XmAnyCallbackStruct *);
static void load_dsp_size(void);

#define BEWARE "The current display has been modified. \nPress OK to ignore\
 all of the changes?"

static char filter[256];
static char default_filter[256];

Widget snapevt;
Widget snaptxt;
Widget utcbar;
Widget renumtog;
void set_evt_tog(void);
void set_txt_tog(void);
void set_utc_tog(void);
void set_renum_tog(void);
static int oldval;				/* previous # of lines */
/***********************************************************************
 *
 * FUNCTION:
 *	init_file_menu()
 *
 * INPUTS:
 *	menu_bar	(Widget)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *	sets up the widgets for the file menu
 */

void 
init_file_menu(Widget menu_bar, char *resource_filter)
{
    Widget file_pulldown, file_cascade;		/* pulldown menus */
    Widget fbuttons[N_BUTTONS];			/* array of widgets */
    Arg args[20];				/* widget given values */
    Cardinal n, nchild;				/* indices of widgets */
    XmString xmTemp;				/* temp buffer for string */

    /* Create file menu */

    strcpy(default_filter, resource_filter);

    n = 0;
    file_pulldown = XmCreatePulldownMenu(menu_bar, "filepulldown", args, n);

    n = 0;
    xmTemp = XmStringCreateSimple("File");
    XtSetArg(args[n], XmNsubMenuId, file_pulldown); n++;
    XtSetArg(args[n], XmNlabelString, xmTemp); n++;
    XtSetArg(args[n], XmNmnemonic, 'F'); n++;
    file_cascade = XmCreateCascadeButton(menu_bar, "filecascade", args, n);
    XtManageChild(file_cascade);
    XmStringFree(xmTemp);

    nchild = 0;

    n = 0;
    xmTemp = XmStringCreateSimple("New");
    XtSetArg(args[n], XmNlabelString,  xmTemp); n++;
    XtSetArg(args[n], XmNmnemonic, 'N'); n++;
    fbuttons[nchild] = XmCreatePushButtonGadget(file_pulldown, "newbutton",
	args, n);
    XtAddCallback(fbuttons[nchild], XmNactivateCallback, 
	(XtCallbackProc)new_button, NULL);
    XmStringFree(xmTemp);

    n = 0;
    xmTemp = XmStringCreateSimple("Open...");
    XtSetArg(args[n], XmNlabelString, xmTemp); n++;
    XtSetArg(args[n], XmNmnemonic, 'O'); n++;
    fbuttons[++nchild] = XmCreatePushButtonGadget(file_pulldown, "openbutton",
	args, n);
    XtAddCallback(fbuttons[nchild], XmNactivateCallback, 
	(XtCallbackProc)open_button, NULL);
    XmStringFree(xmTemp);

    n = 0;
    xmTemp = XmStringCreateSimple("Save");
    XtSetArg(args[n], XmNlabelString, xmTemp); n++;
    XtSetArg(args[n], XmNmnemonic, 'S'); n++;
    fbuttons[++nchild] = XmCreatePushButtonGadget(file_pulldown, "savebutton",
	args, n);
    XtAddCallback(fbuttons[nchild], XmNactivateCallback, 
	(XtCallbackProc)save_button, NULL);
    XmStringFree(xmTemp);

    n = 0;
    xmTemp = XmStringCreateSimple("Save As...");
    XtSetArg(args[n], XmNlabelString, xmTemp); n++;
    XtSetArg(args[n], XmNmnemonic, 'A'); n++;
    fbuttons[++nchild] = XmCreatePushButtonGadget(file_pulldown, "saveasbutton",
	args, n);
    XtAddCallback(fbuttons[nchild], XmNactivateCallback, 
	(XtCallbackProc)save_as_button, NULL);
    XmStringFree(xmTemp);

    n = 0;
    xmTemp =  XmStringCreateSimple("Print...");
    XtSetArg(args[n], XmNlabelString, xmTemp); n++;
    XtSetArg(args[n], XmNmnemonic, 'P'); n++;
    fbuttons[++nchild] = XmCreatePushButtonGadget(file_pulldown, "printbutton",
	args, n);
    XtAddCallback(fbuttons[nchild], XmNactivateCallback, 
	(XtCallbackProc)print_button, NULL);
    XmStringFree(xmTemp);

    n = 0;
    xmTemp = XmStringCreateSimple("Export Graphics...");
    XtSetArg(args[n], XmNlabelString, xmTemp); n++;
    XtSetArg(args[n], XmNmnemonic, 'G'); n++;
    fbuttons[++nchild] = XmCreatePushButtonGadget(file_pulldown, "exportbutton",
        args, n);
    XtAddCallback(fbuttons[nchild], XmNactivateCallback,
        (XtCallbackProc)Export, NULL);
    XmStringFree(xmTemp);

    n = 0;
    xmTemp = XmStringCreateSimple("Exit");
    XtSetArg(args[n], XmNlabelString, xmTemp); n++;
    XtSetArg(args[n], XmNmnemonic, 'E'); n++;
    fbuttons[++nchild] = XmCreatePushButtonGadget(file_pulldown, "exitbutton",
	args, n);
    XtAddCallback(fbuttons[nchild], XmNactivateCallback, 
	(XtCallbackProc)exit_button, NULL);
    XmStringFree(xmTemp);

    if (++nchild > N_BUTTONS) {
        XtWarning("Too many buttons in filemenu.c");
        exit(1);
    }
    XtManageChildren(fbuttons, nchild);
}

/***********************************************************************
 *
 * FUNCTION:
 *	option_menu()
 *
 * INPUTS:
 *	menu_bar	(Widget)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *	creates the option menu
 */

void 
init_option_menu(Widget menu_bar)
{
    Widget option_pulldown, option_cascade, obuttons[N_BUTTONS];
	/* widgets for the option pulldown menu buttons */
    Arg args[20];				/* widget given values */
    Cardinal n, nchild;				/* indices for widgets */
    XmString xmTemp;				/* temp string buffer */

    auto_renum = TOG_ON;

    n = 0;
    option_pulldown = XmCreatePulldownMenu(menu_bar, "optionpulldown", args, n);

    n = 0;
    xmTemp = XmStringCreateSimple("Options");
    XtSetArg(args[n], XmNsubMenuId, option_pulldown); n++;
    XtSetArg(args[n], XmNlabelString, xmTemp); n++;
    XtSetArg(args[n], XmNmnemonic, 'O'); n++;
    option_cascade = XmCreateCascadeButton(menu_bar, "optioncascade", args, n);
    XtManageChild(option_cascade);
    XmStringFree(xmTemp);

    nchild = 0;
 
    n = 0;
    xmTemp = XmStringCreateSimple("Set Dates");
    XtSetArg(args[n], XmNlabelString, xmTemp); n++;
    XtSetArg(args[n], XmNmnemonic, 'D'); n++;
    obuttons[nchild] = XmCreatePushButtonGadget(option_pulldown,
	 "setdatesbutton", args, n);
    XtAddCallback(obuttons[nchild], XmNactivateCallback, 
	(XtCallbackProc)set_dates_button, NULL);
    XtAddCallback(obuttons[nchild], XmNhelpCallback, (XtCallbackProc)ShowHelp, 
	"date");
    XmStringFree(xmTemp);

    n = 0;
    xmTemp = XmStringCreateSimple("Renumber");
    XtSetArg(args[n], XmNlabelString, xmTemp); n++;
    XtSetArg(args[n], XmNmnemonic, 'R'); n++;
    XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); n++;
    XtSetArg(args[n], XmNset, (int)auto_renum); n++;
    renumtog = obuttons[++nchild] = XmCreateToggleButtonGadget(option_pulldown, 
	"renumbutton", args, n);
    XtAddCallback(obuttons[nchild], XmNvalueChangedCallback, 
	(XtCallbackProc)renum_tog, NULL);
    XtAddCallback(obuttons[nchild], XmNhelpCallback, 
	(XtCallbackProc)ShowHelp, "renum");
    XmStringFree(xmTemp);

    n = 0;
    xmTemp = XmStringCreateSimple("Plot Setup");
    XtSetArg(args[n], XmNlabelString, xmTemp); n++;
    XtSetArg(args[n], XmNmnemonic, 'P'); n++;
    obuttons[++nchild] = XmCreatePushButtonGadget(option_pulldown,"setupbutton",
	args, n);
    XtAddCallback(obuttons[nchild], XmNactivateCallback, 
	(XtCallbackProc)plot_button, NULL);
    XtAddCallback(obuttons[nchild], XmNhelpCallback, 
	(XtCallbackProc)ShowHelp, "plot");
    XmStringFree(xmTemp);

    n = 0;
    xmTemp = XmStringCreateSimple("Snap Events");
    XtSetArg(args[n], XmNlabelString, xmTemp); n++;
    XtSetArg(args[n], XmNmnemonic, 'S'); n++;
    XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); n++;
    XtSetArg(args[n], XmNset, (int)snap_evt); n++;
    snapevt = obuttons[++nchild] = XmCreateToggleButtonGadget(option_pulldown, 
	"snapevents", args, n);
    XtAddCallback(obuttons[nchild], XmNvalueChangedCallback, 
	(XtCallbackProc)snap_evt_button, NULL);
    XtAddCallback(obuttons[nchild], XmNhelpCallback, 
	(XtCallbackProc)ShowHelp, "snapevt");
    XmStringFree(xmTemp);

    n = 0;
    xmTemp = XmStringCreateSimple("Snap Text");
    XtSetArg(args[n], XmNlabelString, xmTemp); n++;
    XtSetArg(args[n], XmNmnemonic, 'T'); n++;
    XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); n++;
    XtSetArg(args[n], XmNset, (int)snap_txt); n++;
    snaptxt = obuttons[++nchild] = XmCreateToggleButtonGadget(option_pulldown,
        "snaptext", args, n);
    XtAddCallback(obuttons[nchild], XmNvalueChangedCallback, 
	(XtCallbackProc)snap_txt_button, NULL);
    XtAddCallback(obuttons[nchild], XmNhelpCallback, 
	(XtCallbackProc)ShowHelp, "snaptxt");
    XmStringFree(xmTemp);

    n = 0;
    xmTemp = XmStringCreateSimple("Display DOY");
    XtSetArg(args[n], XmNlabelString, xmTemp); n++;
    XtSetArg(args[n], XmNmnemonic, 'U'); n++;
    XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); n++;
    XtSetArg(args[n], XmNset, (int)utc_bar); n++;
    utcbar = obuttons[++nchild] = XmCreateToggleButtonGadget(option_pulldown,
	"utc_bar", args, n);
    XtAddCallback(obuttons[nchild], XmNvalueChangedCallback, 
	(XtCallbackProc)utc_bar_button, NULL);
    XtAddCallback(obuttons[nchild], XmNhelpCallback, 
	(XtCallbackProc)ShowHelp, "utcbar");
    XmStringFree(xmTemp);

    n = 0;
    xmTemp = XmStringCreateSimple("Display Id");
    XtSetArg(args[n], XmNlabelString, xmTemp); n++;
    XtSetArg(args[n], XmNmnemonic, 'I'); n++;
    XtSetArg(args[n], XmNindicatorType, XmN_OF_MANY); n++;
    XtSetArg(args[n], XmNset, (int)all_id_disp); n++;
    obuttons[++nchild] = XmCreateToggleButtonGadget(option_pulldown,
	"id_tog", args, n);
    XtAddCallback(obuttons[nchild], XmNvalueChangedCallback, 
	(XtCallbackProc)id_button, NULL);
    XtAddCallback(obuttons[nchild], XmNhelpCallback, 
	(XtCallbackProc)ShowHelp, "id_tog");
    XmStringFree(xmTemp);

    n = 0;
    xmTemp = XmStringCreateSimple("Page Forward");
    XtSetArg(args[n],XmNlabelString, xmTemp); n++;
    XtSetArg(args[n], XmNmnemonic, 'B'); n++;
    obuttons[++nchild] = XmCreatePushButtonGadget(option_pulldown,
	"pageforward", args, n);
    XtAddCallback(obuttons[nchild], XmNactivateCallback, 
	(XtCallbackProc)next_button, NULL);
    XtAddCallback(obuttons[nchild], XmNhelpCallback, 
	(XtCallbackProc)ShowHelp, "next_button");
    XmStringFree(xmTemp);

    n = 0;
    xmTemp = XmStringCreateSimple("Page Backward");
    XtSetArg(args[n],XmNlabelString, xmTemp); n++;
    XtSetArg(args[n], XmNmnemonic, 'F'); n++;
    obuttons[++nchild] = XmCreatePushButtonGadget(option_pulldown,
	"pageback", args, n);
    XtAddCallback(obuttons[nchild], XmNactivateCallback, 
	(XtCallbackProc)prev_button, NULL);
    XtAddCallback(obuttons[nchild], XmNhelpCallback, 
	(XtCallbackProc)ShowHelp, "prev_button");
    XmStringFree(xmTemp);

    if (++nchild > N_BUTTONS) {
	XtWarning("Too many buttons in filemenu.c");
 	exit(1);
    }
    XtManageChildren(obuttons, nchild);
}

/***********************************************************************
 *
 * FUNCTION:
 *	new_button()
 *
 * INPUTS:
 *	w	(Widget)
 *	client_data	(XtPointer)
 *	call_data	(XmAnyCallbackStruct *)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *	sets up the screen for a new file
 */

static void 
new_button(Widget w, XtPointer client_data, XmAnyCallbackStruct *call_data)
{
    XRectangle r;			/* rectangle */
    int i;				/* temp index */

    Message("New button was selected");
    if ((!modified) || Beware(BEWARE)) {
    	Message("Set up new screen with zero objects");
   	gr_clear();
    	clear_all_obj();
    	for (i = 0; i < Hnobj; i++) {
	    delete_hline(i);
    	}
    	Hnobj = 0;
    	gr_screen_on(&dw);
    	filename[0] = '\0';
	set_title_to_filename();
	line_init();
    	hline_init();
    	init_chart();
	init_pline();
	npln = 0;
	/* make sure toggles get set to cleared values */
	set_txt_tog();
	set_evt_tog();
	set_utc_tog();
	set_renum_tog();
	modified = FALSE;
     	/*
       	 * Run the locate function on the initial objects
         */
    	for (i = 0; i < Hnobj; i++) {
            (*(Hobjary[i].opsptr->loc))(i, OBJECT);
    	}
    	for (i = 0; i < nobj; i++) {
            (*(objary[i].opsptr->loc))(i, OBJECT);
   	}

    	for (i = 0; i < nxln; i++) {
	    (*(xlnary[i].opsptr->loc))(i, LINE_X);
    	}

    	for (i = 0; i < nyln; i++) {
	    (*(ylnary[i].opsptr->loc))(i, LINE_Y);
    	}

    	dsp_chart(0);
    	gr_screen_off();
    	r.x = 0;
    	r.y = 0;
    	r.width = page_width;
    	r.height = page_height;
    	AddExposeEvent(0, &r);
    }
}

/***********************************************************************
 *
 * FUNCTION:
 *	open_button()
 *
 * INPUTS:
 *	w	(Widget)
 *	client_data	(XtPointer)
 *	call_data	(XmAnyCallbackStruct *)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *	opens a file from the file selection box
 */

static void 
open_button(Widget w, XtPointer client_data, XmAnyCallbackStruct *call_data)
{
    load_the_file(NULL);
}

/***********************************************************************
 *
 * FUNCTION:
 *	load_the_file
 *
 * INPUTS:
 *	file		- (char *) name of file from command line
 *
 * OUTPUTS:
 *	none
 *
 * RETURNS:
 *	none
 *
 * EXTERNALLY READ:
 *	none
 *
 * EXTERNALLY MODIFIED:
 *	none
 *
 * DESCRIPTION:
 *	Opens a file from the file selection box or command line.
 */

void 
load_the_file(char *file)
{
    XRectangle r;	/* rectangle */
    int i;

    if (file == NULL) {
	oldval = pg_lines;
	Message("Open button was selected");
	if ((!modified) || Beware(BEWARE)) {
	    if (modified == TRUE) {
		Message("All changes have been deleted.");
	    }
	    r.x = 0;
	    r.y = 0;
	    r.width = page_width;
	    r.height = page_height;
	    if (filter[0] == '\0') {
		strcpy(filter, default_filter);
	    }
	    if (!FileSelect(filename, filter, FALSE, "open_file")) {
		return;
	    }
	}
    } else {
	oldval = pg_lines;
	r.x = 0;
	r.y = 0;
	r.width = page_width;
	r.height = page_height;
	strcpy(filename, file);
    }

    if (load_file(filename) == -1) {
	Message("Bad Data File: %s", filename);
	/* bad data file was entered, so load new file */
	clear_all_obj();
	for (i = 0; i < Hnobj; i++) {
	    delete_hline(i);
	}
	Hnobj = 0;
	filename[0] = '\0';
	line_init();
	hline_init();
	init_chart();
	init_pline();
	npln = 0;
	/* make sure toggles get set to cleared values */
	set_txt_tog();
	set_evt_tog();
	set_utc_tog();
	set_renum_tog();
	modified = FALSE;
	/*
	* Run the locate function on the initial objects
	*/
	for (i = 0; i < Hnobj; i++) {
	    (*(Hobjary[i].opsptr->loc))(i, OBJECT);
	 }
	for (i = 0; i < nobj; i++) {
	    (*(objary[i].opsptr->loc))(i, OBJECT);
	}
	for (i = 0; i < nxln; i++) {
	    (*(xlnary[i].opsptr->loc))(i, LINE_X);
	}
	for (i = 0; i < nyln; i++) {
	    (*(ylnary[i].opsptr->loc))(i, LINE_Y);
	}
    } else {
	set_title_to_filename();
	for (i = 0; i < nxln; i++) {
	    (*(xlnary[i].opsptr->loc))(i, LINE_X);
	}

	for (i = 0; i < nyln; i++) {
	    (*(ylnary[i].opsptr->loc))(i, LINE_Y);
	}
	oldval = pg_lines;
	load_dsp_size();
	for (i = 0; i < nobj; i++) {
	    (*(objary[i].opsptr->loc))(i, OBJECT);
	}
	for (i = 0; i < npln; i++) {
	    loc_pline(i, OBJECT);
	}
	modified = FALSE;
    }
    AddExposeEvent(0, &r);
}

/***********************************************************************
 *
 * FUNCTION:
 *	save_button()
 *
 * INPUTS:
 *	w	(widget)
 *	client_data	(XtPointer)
 *	call_data	(XmAnyCallbackStruct *)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *	
 * DESCRIPTION:
 *	saves the file
 */

static void 
save_button(Widget w, XtPointer client_data, XmAnyCallbackStruct *call_data)
{
    if (filter[0] == '\0') {
	strcpy(filter, default_filter);
    }
    if (filename[0] =='\0') {
        if (FileSelect(filename, filter, FALSE, "save_file")) {
	    save_file(filename);
	}
	set_title_to_filename();
	modified = FALSE;
    } else {
        save_file(filename);
	set_title_to_filename();
	modified = FALSE;
    }
}

/***********************************************************************
 *
 * FUNCTION:
 *	save_as_button()
 *
 * INPUTS:
 *	w	(widget)
 *	client_data	(XtPointer)
 *	call_data	(XmAnyCallbackStruct *)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *	saves the file as the input name
 */

static void 
save_as_button(Widget w, XtPointer client_data, XmAnyCallbackStruct *call_data)
{
    if (filter[0] == '\0') {
	strcpy(filter, default_filter);
    }
    if (FileSelect(filename, filter, FALSE, "save_as")) {
	save_file(filename);
	set_title_to_filename();
	modified = FALSE;
    } else {
	Message("No file saved");
    }
}

/***********************************************************************
 *
 * FUNCTION:
 *	print_button()
 *
 * INPUTS:
 *	w	(Widget)
 *	client_data	(XtPointer)
 *	call_data	(XmAnyCallbackStruct *)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *	prints the file
 */

static void 
print_button(Widget w, XtPointer client_data, XmAnyCallbackStruct *call_data)
{
    Message("Print button was selected for page %d", current_page);
    popup_print_options();
}

/***********************************************************************
 *
 * FUNCTION:
 *	exit_button()
 *
 * INPUTS:
 *	w	(Widget)
 *	client_data	(XtPointer)
 *	call_data	(XmAnyCallbackStruct *)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *	exits from the opps editor
 */

void 
exit_button(Widget w, XtPointer client_data, XmAnyCallbackStruct *call_data)
{
    if (ShellValidateClose(w)) {
	if ((!modified) || Beware(BEWARE)) {
            gr_free_fonts();
            exit(0);
	}
    } else {
	Warning("Unable to close application at this time.");
    }
}

/***********************************************************************
 *
 * FUNCTION:
 *	set_dates_button()
 *
 * INPUTS:
 *	w       (Widget)
 *      client_data     (XtPointer)
 *      call_data       (XmAnyCallbackStruct *)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *	gets the dates entered by the user
 */

static void 
set_dates_button(Widget w, XtPointer client_data, XmAnyCallbackStruct *call_data)
{
    int co;			/* current object */

    if ((co = find_object_type(OBJ_CHT)) == -1) {
     /* error only one chart (timeline area) object allowed */
        Warning("Error on edit of timeline");
    } else {
        Message("Edit TimeLine");
        (*(objary[co].opsptr->edt))(co, FALSE);
    }
}

/***********************************************************************
 *
 * FUNCTION:
 *	renum_tog()
 *
 * INPUTS:
 *	w       (Widget)
 *      client_data     (XtPointer)
 *      call_data       (XmAnyCallbackStruct *)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *	toggles the auto_renumber value between on or off
 */

static void 
renum_tog(Widget w, XtPointer client_data, XmToggleButtonCallbackStruct 
    *call_data)
{
    int i, tempco; 			/* temp index */

    auto_renum = (enum tog) call_data->set;
    if (auto_renum == TOG_ON) {
	for (i = 0; i < Hnobj; i++) {
	    if (Hobjary[i].z.hlnptr->our_num == 1) {
	 	tempco = i;
	    }
    	}
        ren_hline();
        /*
         * find tempco as first line on page so the page gets reexposed
         */
        exposeRectList(0, Hobjary[tempco].rlist);
    }
    modified = TRUE;
}

/***********************************************************************
 *
 * FUNCTION:
 *	plot_button()
 *
 * INPUTS:
 *	w       (Widget)
 *      client_data     (XtPointer)
 *      call_data       (XmAnyCallbackStruct *)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *	sets the various options for the plot
 */

static void 
plot_button(Widget w, XtPointer client_data, XmAnyCallbackStruct *call_data)
{
    Message("Set plot options ");
    edit_plot();
}

/***********************************************************************
 *
 * FUNCTION:
 *     snap_evt_button() 
 *
 * INPUTS:
 *      w       (Widget)
 *      client_data     (XtPointer)
 *      call_data       (XmToggleButtonCallbackStruct *)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *     sets the snap events toggle - restricting horizontal motion of events 
 */

static void 
snap_evt_button(Widget w, XtPointer client_data, XmToggleButtonCallbackStruct 
    *call_data)
{
    snap_evt = (enum tog)call_data->set;
    modified = TRUE;
}

/***********************************************************************
 *
 * FUNCTION:
 *     snap_txt_button()
 *
 * INPUTS:
 *      w       (Widget)
 *      client_data     (XtPointer)
 *      call_data       (XmToggleButtonCallbackStruct *)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *     sets the snap text toggle - restricting horizontal motion of text 
 */

static void 
snap_txt_button(Widget w, XtPointer client_data, XmToggleButtonCallbackStruct
     *call_data)
{
    snap_txt = (enum tog)call_data->set;
    modified = TRUE;
}

/***********************************************************************
 *
 * FUNCTION:
 *     utc_bar_button()
 *
 * INPUTS:
 *      w       (Widget)
 *      client_data     (XtPointer)
 *      call_data       (XmToggleButtonCallbackStruct *)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *    displays the utc dates along the bottom of the chart 
 */

static void 
utc_bar_button(Widget w, XtPointer client_data, XmToggleButtonCallbackStruct 
    *call_data)
{
    utc_bar = (enum tog)call_data->set;
    (*(objary[0].opsptr->dsp))(0);
    exposeRectList(0, objary[0].rlist);
    modified = TRUE;
}

/***********************************************************************
 *
 * FUNCTION:
 *     id_button()
 *
 * INPUTS:
 *      w       	(Widget)
 *      client_data     (XtPointer)
 *      call_data       (XmToggleButtonCallbackStruct *)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *    displays the entered id text strings for the dated objects
 */

static void 
id_button(Widget w, XtPointer client_data, XmToggleButtonCallbackStruct 
    *call_data)
{
    int i;				/* temp loop index */
    XRectangle r;			/* expose rectangle */

    all_id_disp = (enum tog)call_data->set;
    /* find all id_tog and set them to new value */
    for (i = 0; i < nobj; i++) {
	switch (objary[i].type) {
	case OBJ_ACT:
	    objary[i].z.actptr->idtog = all_id_disp;
	    break;
	case OBJ_EVT:
	    objary[i].z.evtptr->idtog = all_id_disp;
	    break;
	case OBJ_SACT:
	    objary[i].z.sactptr->idtog = all_id_disp;
	    break;
	case OBJ_SEQ:
	    objary[i].z.seqptr->idtog = all_id_disp;
	    break;
	case OBJ_SLP:
	    objary[i].z.slpptr->idtog = all_id_disp;
	    break;
	default:
	    break;
	}
    }
    /* expose screen to show changes */
    r.x = 0;
    r.y = 0;
    r.width = page_width;
    r.height = page_height;
    AddExposeEvent(0, &r); 
    modified = TRUE;
}

/***********************************************************************
 *
 * FUNCTION:
 *      prev_button()
 *
 * INPUTS:
 *      w               - (Widget)
 *      client_data     - (XtPointer)
 *      call_data       - (XmAnyCallbackStruct *)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *
 */

/* ARGSUSED */
static void 
prev_button(Widget w, XtPointer client_data, XmAnyCallbackStruct *call_data)
{
    int i;
    XRectangle r;

    if (current_page == 1) {
	Warning("At the First Page");
    } else {
	current_page = current_page - 1;
    	set_dsp_size();
    	for (i = 0; i < Hnobj; i++) {
	    (*(Hobjary[i].opsptr->loc))(i, OBJECT);
	    (*(Hobjary[i].opsptr->dsp))(i);
     	}
	ren_hline();
     	for (i = 0; i < nobj; i++) {
	    (*(objary[i].opsptr->loc))(i, OBJECT);
	    (*(objary[i].opsptr->dsp))(i);
    	}
	for (i = 0; i < npln; i++) {
	    loc_pline(i, OBJECT);
	}
    	r.x = 0;
     	r.y = 0;
     	r.width = page_width;
     	r.height = page_height;
     	AddExposeEvent(0, &r);
    }
}

/***********************************************************************
 *
 * FUNCTION:
 *      next_button()
 *
 * INPUTS:
 *      w               - (Widget)
 *      client_data     - (XtPointer)
 *      call_data       - (XmAnyCallbackStruct *)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *
 */

/* ARGSUSED */
static void 
next_button(Widget w, XtPointer client_data, XmAnyCallbackStruct *call_data)
{
    int i;
    XRectangle r;

    if (current_page == num_pages) {
	Warning("At Last Page");
    } else {
	current_page = current_page + 1;
    	set_dsp_size();
    	for (i = 0; i < Hnobj; i++) {
	    (*(Hobjary[i].opsptr->loc))(i, OBJECT);
	    (*(Hobjary[i].opsptr->dsp))(i);
     	}
	ren_hline();
    	for (i = 0; i < nobj; i++) {
	    (*(objary[i].opsptr->loc))(i, OBJECT);
	    (*(objary[i].opsptr->dsp))(i);
     	}
	for (i = 0; i < npln; i++) {
	    loc_pline(i, OBJECT);
	}
     	r.x = 0;
     	r.y = 0;
     	r.width = page_width;
     	r.height = page_height;
	AddExposeEvent(0, &r);
    }
}

/***********************************************************************
 *
 * FUNCTION:
 *      getfm_text()
 *
 * INPUTS:
 *      type            - (enum fm_type) request of text to return
 *
 * OUTPUTS:
 *      text            - (char []) array to contain returned text
 *                        If no file is open, the FILE will be "".
 *                        Any empty fields will be set to ""
 *                        Size of array especially for DIR should be
 *                        ~ 256.
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *      filename        - (static char []) name of current open file.
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *      This function parses the the current open filename and returns
 *      pieces of it.
 */

void 
getfm_text(char *text, enum fm_type type)
{
    char *ptr;
    int root_index;
    int ext_index;

    /*
     * parse the filename
     */
    ptr = filename;

    /*
     * set pointer past all '/'s
     */
    while (strchr(ptr, '/') != NULL) {
        ptr = strchr(ptr, '/') + 1;
    }

    /*
     * root_index is index of root of filename
     */
    root_index = ptr - filename;

    /*
     * set pointer past all '.'s
     */
    if (strchr(ptr, '.') == NULL) {
        /*
         * if none -> move to end of string
         */
        while (*ptr) ++ptr;
    } else {
        while (strchr(ptr, '.') != NULL) {
            ptr = strchr(ptr, '.') + 1;
        }
    }
    /*
     * ext_index is index of extension of filename
     */
    ext_index = ptr - filename;

    switch (type) {
    case FM_FILE:               /* obtain filename without directory */
        strcpy(text, filename + root_index);
        break;
    case FM_DIR:                /* get directory with / on end */
        if (filename[0] == '/') {
            strncpy(text, filename, (unsigned)root_index);
            text[root_index] = '\0';
        } else {
            if (getcwd(text, _POSIX_PATH_MAX) == NULL) {
		Warning("Unable to find directory");
		return;
	    }
            ptr = text + strlen(text);
            *(ptr++) = '/';
            strncpy(ptr, filename, (unsigned)root_index);
            *(ptr + root_index) = '\0';
        }
        break;
    case FM_ROOT:               /* strip .ext from filename */
        strncpy(text, filename + root_index,(unsigned)(ext_index - root_index));
        text[ext_index - root_index] = '\0';
        if (text[0] && text[(ext_index - root_index) - 1] == '.') {
            text[(ext_index - root_index) - 1] = '\0';
        }
        break;
    case FM_EXT:                /* get extension (user.c -> c) */
        strcpy(text, filename + ext_index);
        break;
    }
}

/***********************************************************************
 *
 * FUNCTION:
 *      set_evt_tog()
 *
 * INPUTS:
 *      parent  (Widget)
 *      display (Display *)
 *      app     (XtAppContext)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *      sets the snap events toggle to the value loaded from the file
 */

void 
set_evt_tog(void)
{
    if (XmToggleButtonGadgetGetState(snapevt) != (int)snap_evt) {
	XmToggleButtonGadgetSetState(snapevt, True, True);
    }
}

/***********************************************************************
 *
 * FUNCTION:
 *      set_txt_tog()
 *
 * INPUTS:
 *      parent  (Widget)
 *      display (Display *)
 *      app     (XtAppContext)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *      sets the snap text toggle to the value loaded from the file
 */

void 
set_txt_tog(void)
{
    if (XmToggleButtonGadgetGetState(snaptxt) != (int)snap_txt) {
	XmToggleButtonGadgetSetState(snaptxt, True, True);
    }
}

/***********************************************************************
 *
 * FUNCTION:
 *      set_utc_tog()
 *
 * INPUTS:
 *      parent  (Widget)
 *      display (Display *)
 *      app     (XtAppContext)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *      sets the display doy toggle to the value loaded from the file
 */

void 
set_utc_tog(void)
{
    if (XmToggleButtonGadgetGetState(utcbar) != (int)utc_bar) {
        XmToggleButtonGadgetSetState(utcbar, True, True);
    }
}

/***********************************************************************
 *
 * FUNCTION:
 *      set_renum_tog()
 *
 * INPUTS:
 *      parent  (Widget)
 *      display (Display *)
 *      app     (XtAppContext)
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *      sets the auto renumber toggle to the value loaded from the file
 */

void 
set_renum_tog(void)
{
    if (XmToggleButtonGadgetGetState(renumtog) != (int)auto_renum) {
        XmToggleButtonGadgetSetState(renumtog, True, True);
    }
}

/***********************************************************************
 *
 * FUNCTION:
 *      load_dsp_size()
 *
 * INPUTS:
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *      sets the new number of lines displayed on screen per page
 *	after loading new values from a file
 *
 */

static void 
load_dsp_size(void)
{
    int i;                              /* temp index */
    struct hln *hlnptr;                 /* object pointer */

    page_end = current_page * pg_lines;
    page_begin = page_end - pg_lines + 1;
    y_gap = (int)((y_lines_end - y_act_bottom) / pg_lines);
    y_lines_end = y_gap * pg_lines + y_act_bottom;
    for ( i = oldval; i < pg_lines; i++) {
        hlnptr = Hobjary[i-1].z.hlnptr;
        add_hline(i, i, hlnptr->dsp_lin, hlnptr->dsp_num,
             objary[0].z.chtptr->color, 0, 10, hlnptr->grid, hlnptr->text);
        if (Hobjary[i-1].rlist == NULL) {
            Hobjary[i-1].rlist = newRectList(0);
        }
    }
    for (i = 0; i < Hnobj; i++) {
        (*(Hobjary[i].opsptr->loc))(i, OBJECT);
    }
    if (auto_renum == TOG_ON) {
	ren_hline();
    }
    modified = TRUE;
}

/***********************************************************************
 *
 * FUNCTION:
 *      set_title_to_filename
 *
 * INPUTS:
 *
 * OUTPUTS:
 *
 * RETURNS:
 *
 * EXTERNALLY READ:
 *      filename        (static char *) current filename
 *
 * EXTERNALLY MODIFIED:
 *
 * DESCRIPTION:
 *      Used by open_button, save_button, and save_as_button to change the 
 *	title of the tool.
 */

void 
set_title_to_filename(void)
{
    char name[256], dir[256];

    if (filename[0] == '\0') {
        set_title(NULL, NULL);
    } else {
        getfm_text(name, FM_FILE);
        getfm_text(dir, FM_DIR);
        set_title(name, dir);
    }
}

