/***************************************************************************/
/***************************************************************************/
/*                                                                         */
/*   (c) 1995-1999.  The Regents of the University of California.  All     */
/*   rights reserved.                                                      */
/*                                                                         */
/*   This work was produced at the University of California, Lawrence      */
/*   Livermore National Laboratory (UC LLNL) under contract no.            */
/*   W-7405-ENG-48 (Contract 48) between the U.S. Department of Energy     */
/*   (DOE) and The Regents of the University of California (University)    */
/*   for the operation of UC LLNL.  Copyright is reserved to the           */
/*   University for purposes of controlled dissemination,                  */
/*   commercialization through formal licensing, or other disposition      */
/*   under terms of Contract 48; DOE policies, regulations and orders;     */
/*   and U.S. statutes.  The rights of the Federal Government are          */
/*   reserved under Contract 48 subject to the restrictions agreed upon    */
/*   by the DOE and University.                                            */
/*                                                                         */
/*                                                                         */
/*                              DISCLAIMER                                 */
/*                                                                         */
/*   This software was prepared as an account of work sponsored by an      */
/*   agency of the United States Government.  Neither the United States    */
/*   Government nor the University of California nor any of their          */
/*   employees, makes any warranty, express or implied, or assumes any     */
/*   liability or responsibility for the accuracy, completeness, or        */
/*   usefulness of any information, apparatus, product, or process         */
/*   disclosed, or represents that its specific commercial products,       */
/*   process, or service by trade name, trademark, manufacturer, or        */
/*   otherwise, does not necessarily constitute or imply its               */
/*   endorsement, recommendation, or favoring by the United States         */
/*   Government or the University of California. The views and opinions    */
/*   of the authors expressed herein do not necessarily state or reflect   */
/*   those of the United States Government or the University of            */
/*   California, and shall not be used for advertising or product          */
/*   endorsement purposes.                                                 */
/*                                                                         */
/*   Permission to use, copy, modify and distribute this software and its  */
/*   documentation for any non-commercial purpose, without fee, is         */
/*   hereby granted, provided that the above copyright notice and this     */
/*   permission notice appear in all copies of the software and            */
/*   supporting documentation, and that all UC LLNL identification in      */
/*   the user interface remain unchanged.  The title to copyright LLNL     */
/*   XDIR shall at all times remain with The Regents of the University     */
/*   of California and users agree to preserve same. Users seeking the     */
/*   right to make derivative works with LLNL XDIR for commercial          */
/*   purposes may obtain a license from the Lawrence Livermore National    */
/*   Laboratory's Technology Transfer Office, P.O. Box 808, L-795,         */
/*   Livermore, CA 94550.                                                  */
/*                                                                         */
/***************************************************************************/
/***************************************************************************/

#include <stdlib.h>
#include <Xm/Form.h>
#include <Xm/Label.h>
#include <Xm/MessageB.h>
#include <Xm/FileSB.h>
#include "xdir.h"

#define NONE    0
#define YES     1
#define NO      2

#define OK      1
#define CANCEL  2

#define CLOSE        1
#define DIAGNOSTICS  2

static int message_response;
static int question_response;
static int filename_response;
static int alert_response;
static Widget w_question;
static Widget w_message;
static Widget w_alert;
static Widget w_getFilename;

extern XtAppContext app;

void cb_question_yes();
void cb_question_no();
void cb_message_ok();
void cb_map_dialog();
void cb_get_filename_cancel();
void cb_get_filename_ok();
void cb_alert_close();
void cb_alert_diagnostics();
void create_alert_dialog();
void create_get_filename_dialog();
void create_message_dialog();
void create_question_dialog();
char *cstring_to_text();
XmString text_to_cstring();


/*
 * question_dialog - Pops up dialog to ask user question.  Returns True
 *                   or False, depending on user's reponse.  The question
 *                   dialog is centered over "w_parent".
 */
question_dialog(question, w_parent)
char *question;
Widget w_parent;
{
	XmString string;

    /* Build dialog */
    create_question_dialog(w_parent);

	/* Enter question */
	string = text_to_cstring(question);
	XtVaSetValues(w_question, XmNmessageString, string, NULL);
	XmStringFree(string);

    /* Pop up dialog and wait for user response */
    question_response = NONE;
    XtManageChild(w_question);
    while (question_response == NONE)
        XtAppProcessEvent(app, (XtInputMask)XtIMAll);
	XtDestroyWidget(XtParent(w_question));

	if (question_response == YES)
		return True;
	else
		return False;
}


/*
 * create_question_dialog - Create dialog window to ask user question.
 *                          "w_parent" will be the dialog's parent.
 */
void
create_question_dialog(w_parent)
Widget w_parent;
{
    Arg args[2];
    int i;

    /* Create question dialog */
    i = 0;
    XtSetArg(args[i], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); i++;
	XtSetArg(args[i], XmNdefaultPosition, False); i++;
    w_question = XmCreateQuestionDialog(w_parent, "question", args, i);
	XtAddCallback(w_question, XmNmapCallback, cb_map_dialog,
		(XtPointer)XtWindow(w_parent));

	/* Add callback for the WM_DELETE_WINDOW protocol */
	add_wm_delete_window_cb(w_question, cb_question_no, NULL, False);

    /* Won't need Help button */
    XtUnmanageChild(XmMessageBoxGetChild(w_question, XmDIALOG_HELP_BUTTON));

    /* Add callbacks */
    XtAddCallback(w_question, XmNokCallback, cb_question_yes, (XtPointer)NULL);
    XtAddCallback(w_question, XmNcancelCallback, cb_question_no,
		(XtPointer)NULL);
}


/*
 * cb_question_yes - Callback to handle "Yes" button in question dialog.
 */
void
cb_question_yes(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
	question_response = YES;
}


/*
 * cb_question_no - Callback to handle "No" button in question dialog.
 */
void
cb_question_no(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
	question_response = NO;
}


/*
 * message_dialog - Pop up a dialog created using "create_fn", one of the
 *                  Motif messagebox-creation convenience functions (e.g.,
 *                  XmCreateErrorDialog) that displays the string
 *                  "information". he info dialog is centered over
 *                  "w_parent".  "title" is put in the dialog's title
 *                  bar.
 */
void
message_dialog(create_fn, title, information, w_parent)
Widget (*create_fn)();
char *title;
char *information;
Widget w_parent;
{
	XmString string;

	/* Build dialog? */
    create_message_dialog(create_fn, title, w_parent);

	/* Enter information */
	string = text_to_cstring(information);
	XtVaSetValues(w_message, XmNmessageString, string, NULL);
	XmStringFree(string);

	/* Pop up dialog */
	message_response = NONE;
	XtManageChild(w_message);
	
	/* Wait until user responds */
    while (message_response == NONE)
        XtAppProcessEvent(app, (XtInputMask)XtIMAll);
	XtDestroyWidget(XtParent(w_message));
}


/*
 * create_message_dialog - Create the message dialog using "create_fn",
 *                         one of the Motif messagebox-creation convenience
 *                         functions (e.g., XmCreateErrorDialog). "w_parent"
 *                         will be the dialog's parent.  "title" is put in
 *                         the dialog's title bar.
 */
void
create_message_dialog(create_fn, title, w_parent)
Widget (*create_fn)();
char *title;
Widget w_parent;
{
	Arg args[2];
    int i;

    /* Create information dialog */
    i = 0;
    XtSetArg(args[i], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); i++;
	XtSetArg(args[i], XmNdefaultPosition, False); i++;
    w_message = create_fn(w_parent, "information", args, i);
	XtAddCallback(w_message, XmNmapCallback, cb_map_dialog,
		(XtPointer)XtWindow(w_parent));

    /* Won't need Help or Cancel buttons */
    XtUnmanageChild(XmMessageBoxGetChild(w_message, XmDIALOG_HELP_BUTTON));
    XtUnmanageChild(XmMessageBoxGetChild(w_message, XmDIALOG_CANCEL_BUTTON));

	/* Add callback */
    XtAddCallback(w_message, XmNokCallback, cb_message_ok, (XtPointer)NULL);

	/* Update title bar */
	XtVaSetValues(XtParent(w_message), XmNtitle, title, NULL);
}


/*
 * cb_message_ok - Callback to handle "Ok" button in info dialog.
 */
void
cb_message_ok(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
	message_response = YES;
}


/*
 * get_filename - Prompts user for the full path of a file name.
 *                "selection_label" is the label for the file name.
 *                "title" is the string to put in the dialog's title bar.
 *                This dialog is centered over "w_parent".   Returns
 *                a string containing the file name.  Use XtFree() to
 *                release returned string.  Returns NULL if the user
 *                presses the "Cancel" button.
 */
char *
get_filename(title, selection_label, w_parent)
char *title;
char *selection_label;
Widget w_parent;
{
	char *filename;

	/* Build dialog */
	create_get_filename_dialog(title, selection_label, w_parent);

	/* Pop up dialog and wait for user response */
	filename_response = NONE;
	XtManageChild(w_getFilename);
	while (filename_response == NONE)
		XtAppProcessEvent(app, (XtInputMask)XtIMAll);

	/* Return file name */
	if (filename_response == CANCEL)
		filename = NULL;
	else
		XtVaGetValues(w_getFilename, XmNuserData, &filename, NULL);
	XtDestroyWidget(XtParent(w_getFilename));
	return filename;
}


/*
 * create_get_filename_dialog - Create dialog window to ask user to specify
 *                              file name.  "w_parent" will be the dialog's
 *                              parent.
 */
void
create_get_filename_dialog(title, selection_label, w_parent)
char *title;
char *selection_label;
Widget w_parent;
{
	XmString string;
	Arg args[1];
	int i;

	/* Create File Selection dialog */
	i = 0;
	XtSetArg(args[i], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); i++;
	w_getFilename = XmCreateFileSelectionDialog(w_parent, "getFilename",
		args, i);

	/* Update title bar */
	XtVaSetValues(XtParent(w_getFilename), XmNtitle, title, NULL);

	/* Add callback for the WM_DELETE_WINDOW protocol */
	add_wm_delete_window_cb(w_getFilename, cb_get_filename_cancel, NULL, False);

	/* Set selection label */
	string = XmStringCreateSimple(selection_label);
	XtVaSetValues(w_getFilename, XmNselectionLabelString, string, NULL);
	XmStringFree(string);

	/* Initialize directory to home directory */
	string = XmStringCreateSimple(getenv("HOME"));
	XtVaSetValues(w_getFilename, XmNdirectory, string, NULL);
	XmStringFree(string);

	/* Won't need Help button */
	XtUnmanageChild(XmFileSelectionBoxGetChild(w_getFilename,
		XmDIALOG_HELP_BUTTON));

	/* Add callbacks */
	XtAddCallback(w_getFilename, XmNokCallback, cb_get_filename_ok,
		(XtPointer)NULL);
	XtAddCallback(w_getFilename, XmNcancelCallback, cb_get_filename_cancel,
		(XtPointer)NULL);
}


/*
 * cb_get_filename_ok - Callback to handle "OK" button in get file name dialog.
 */
void
cb_get_filename_ok(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
	char *filename;
	XmFileSelectionBoxCallbackStruct *cbs =
		(XmFileSelectionBoxCallbackStruct *)call_data;

	filename = cstring_to_text(cbs->value);
	XtVaSetValues(w_getFilename, XmNuserData, (XtPointer)filename, NULL);

	filename_response = OK;
}


/*
 * cb_get_filename_cancel - Callback to handle "Cancel" button in get file
 *                          name dialog.
 */
void
cb_get_filename_cancel(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
	filename_response = CANCEL;
}


/*
 * show_in_progress_dialog - Pop up a dialog that displays an in-progress
 *                           message ("msg") over directory window "dirwin".
 *                           "title" is the string to put in the dialog's
 *                           title bar.  Returns widget id of the dialog.
 */
Widget
show_in_progress_dialog(dirwin, title, msg)
struct dirwin_st *dirwin;
char *title;
char *msg;
{
	XmString string;
	Widget w_dialog;
	Widget w_message;

	/* Create form dialog */
	w_dialog = XmCreateFormDialog(dirwin->w_shell, "inProgress", NULL, 0);
	XtAddCallback(w_dialog, XmNmapCallback, cb_map_dialog,
		(XtPointer)XtWindow(dirwin->w_shell));

	/* Create message */
	string = text_to_cstring(msg);
	w_message = XtVaCreateManagedWidget(
		"inProgressMessage",
		xmLabelWidgetClass,
		w_dialog,
		XmNlabelString,			string,
		XmNtopAttachment,		XmATTACH_FORM,
		XmNtopOffset,			40,
		XmNbottomAttachment,	XmATTACH_FORM,
		XmNbottomOffset,		40,
		XmNleftAttachment,		XmATTACH_FORM,
		XmNleftOffset,			50,
		XmNrightAttachment,		XmATTACH_FORM,
		XmNrightOffset,			50,
		NULL
	);
	XmStringFree(string);

	/* Update title bar */
	XtVaSetValues(XtParent(w_dialog), XmNtitle, title, NULL);

	/* Pop up dialog */
	XtManageChild(w_dialog);
	add_dialog_to_list(w_dialog);
	force_update(w_dialog);

	return w_dialog;
}


/*
 * hide_in_progress_dialog - Pop down dialog that displays an in-progress
 *                           message.  "w_dialog" is the widget id of the
 *                           in-progress-dialog to hide.
 */
void
hide_in_progress_dialog(w_dialog)
Widget w_dialog;
{
	/* Remove dialog from cursor linked list */
	remove_dialog_from_list(w_dialog);

	/* Get rid of in-progress dialog */
	XtUnmanageChild(w_dialog);
	XtDestroyWidget(XtParent(w_dialog));
}


/*
 * warn - Pop up an error dialog that displays the string "msg"
 *        and emits a beep.  The error dialog is centered over
 *        "w_parent".
 */
void
warn(information, w_parent)
char *information;
Widget w_parent;
{
	beep();
	message_dialog(XmCreateErrorDialog, "Error", information, w_parent);
}


/*
 * info_dialog - Pop up an information dialog that displays the string
 *               "msg" and emits a beep.  The information dialog is over
 *               "w_parent".
 */
void
info_dialog(information, w_parent)
char *information;
Widget w_parent;
{
	beep();
	message_dialog(XmCreateInformationDialog, "Information", information,
		w_parent);
}


/*
 * record_and_alert - Writes warning error "msg" to diagnostics window and
 *                    pops up dialog to alert user to error condition.
 *                    If user presses "Diagnostics" button then diagnostics
 *                    window is displayed.  The alert dialog is centered
 *                    over "w_parent".
 */
void
record_and_alert(msg, w_parent)
char *msg;
Widget w_parent;
{
	static char *instruction =
		"\n\nPress Diagnostics button to view diagnostics window.";
	XmString string;
	char *full_msg;

	/* Write error message to diagnostics window */
	record_warning(msg);

    /* Build dialog */
    create_alert_dialog(w_parent);

	/* Enter warning message */
	full_msg = XtMalloc(strlen(msg)+strlen(instruction)+1);
	strcpy(full_msg, msg);
	strcat(full_msg, instruction);
	string = text_to_cstring(full_msg);
	XtFree(full_msg);
	XtVaSetValues(w_alert, XmNmessageString, string, NULL);
	XmStringFree(string);

    /* Pop up dialog and wait for user response */
	beep();
    alert_response = NONE;
    XtManageChild(w_alert);
    while (alert_response == NONE)
        XtAppProcessEvent(app, (XtInputMask)XtIMAll);
	XtDestroyWidget(XtParent(w_alert));

	if (alert_response == DIAGNOSTICS)
		cb_popup_diagnostics((Widget)NULL, (XtPointer)NULL, (XtPointer)NULL);
}


/*
 * create_alert_dialog - Create dialog window to alert user to error
 *                       condition.  "w_parent" will be the dialog's
 *                       parent.
 */
void
create_alert_dialog(w_parent)
Widget w_parent;
{
    Arg args[2];
    int i;

    /* Create alert dialog */
    i = 0;
    XtSetArg(args[i], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); i++;
	XtSetArg(args[i], XmNdefaultPosition, False); i++;
    w_alert = XmCreateErrorDialog(w_parent, "alert", args, i);
	XtAddCallback(w_alert, XmNmapCallback, cb_map_dialog,
		(XtPointer)XtWindow(w_parent));

	/* Add callback for the WM_DELETE_WINDOW protocol */
	add_wm_delete_window_cb(w_alert, cb_alert_close, NULL, False);

    /* Won't need Help button */
    XtUnmanageChild(XmMessageBoxGetChild(w_alert, XmDIALOG_HELP_BUTTON));

    /* Add callbacks */
    XtAddCallback(w_alert, XmNokCallback, cb_alert_close, (XtPointer)NULL);
    XtAddCallback(w_alert, XmNcancelCallback, cb_alert_diagnostics,
		(XtPointer)NULL);
}


/*
 * cb_alert_close - Callback to handle "Close" button in alert dialog.
 */
void
cb_alert_close(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
	alert_response = CLOSE;
}


/*
 * cb_alert_diagnostics - Callback to handle "Diagnostics" button in alert
 *                        dialog.
 */
void
cb_alert_diagnostics(widget, client_data, call_data)
Widget widget;
XtPointer client_data;
XtPointer call_data;
{
	alert_response = DIAGNOSTICS;
}



syntax highlighted by Code2HTML, v. 0.9.1