/*
 * file-panel.c : The save-load-write panel
 *
 * George Ferguson, ferguson@cs.rochester.edu, 23 Apr 1993.
 * 14 May 1993: Fixed #endif followed by non-comment.
 */

#include <stdio.h>
#include <X11/Intrinsic.h>
#include <X11/Shell.h>
#include <X11/StringDefs.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/MenuButton.h>
#include <X11/Xaw/Label.h>
#ifdef FILECHOOSER
# include <FChooser.h>
#endif
#include "config.h"
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#include "xarchie.h"
#include "db.h"
#include "browser.h"
#include "appres.h"
#include "saveload.h"
#include "file-panel.h"
#include "fchooser.h"
#include "status.h"
#include "xutil.h"
extern DbEntry *db;

/*
 * Functions defined here
 */
void initFilePanelActions();
void updateFileWriteMode();
void setFileShellState();

static void fileSaveAction(),fileLoadAction(),fileWriteAction();
static void popupFilePanel(),initFileWidgets();
static void filePanelOk(),filePanelCancel();
/*
static FileChooserOkProc filePanelOk;
static FileChooserCancelProc filePanelCancel;
*/
static void writeModeWidgetsShown();

/*
 * Data defined here
 */
static FileChooserInfo *fcinfo;
static Widget fileShell,filePanelLabel;
static Widget filePanelWriteModeButton,filePanelWriteModeLabel;
static Boolean fileGoing,isPoppedUp;
static int fileOp;

static XtActionsRec actionTable[] = {
    { "file-save",		fileSaveAction },
    { "file-load",		fileLoadAction },
    { "file-write",		fileWriteAction },
};

void
initFilePanelActions()
{
    XtAppAddActions(appContext,actionTable,XtNumber(actionTable));
}

/*	-	-	-	-	-	-	-	-	*/
/* Action Procedures */

#define ACTION_PROC(NAME)	void NAME(w,event,params,num_params) \
					Widget w; \
					XEvent *event; \
					String *params; \
					Cardinal *num_params;

/*ARGSUSED*/
static
ACTION_PROC(fileSaveAction)
{
    popupFilePanel(FILE_SAVE);
}

/*ARGSUSED*/
static
ACTION_PROC(fileLoadAction)
{
    popupFilePanel(FILE_LOAD);
}

/*ARGSUSED*/
static
ACTION_PROC(fileWriteAction)
{
    popupFilePanel(FILE_WRITE);
}

static void
popupFilePanel(op)
int op;
{
    /* Ignore if the browser is being changed */
    if (getBrowserState() != BROWSER_READY) {
	XBell(display,0);
	return;
    }
    /* Create if this is the first time */
    if (fileShell == NULL) {
	setBusyStatus(True);
	initFileWidgets();
	setBusyStatus(False);
    }
#ifdef FILECHOOSER
      else {
	  status0("Re-initializing File Selector...");
	  XfwfFileChooserRefresh((XfwfFileChooserWidget)(fcinfo->fcw));
    }
#endif
    switch (op) {
	case FILE_SAVE:
	    setWidgetLabel(filePanelLabel,"Save to file:");
	    writeModeWidgetsShown(False);
	    break;
	case FILE_LOAD:
	    setWidgetLabel(filePanelLabel,"Load from file:");
	    writeModeWidgetsShown(False);
	    break;
	case FILE_WRITE:
	    setWidgetLabel(filePanelLabel,"Write to file:");
	    writeModeWidgetsShown(True);
	    break;
    }
    fileOp = op;
    if (isPoppedUp) {
	XRaiseWindow(display,XtWindow(fileShell));
    } else {
	isPoppedUp = True;
	XtPopup(fileShell,XtGrabNone);
    }
}

static void
initFileWidgets()
{
    Widget form;
    Arg args[1];

    fileShell = XtCreatePopupShell("filePanelShell",topLevelShellWidgetClass,
				   toplevel,NULL,0);
    form = XtCreateManagedWidget("filePanelForm",formWidgetClass,
				 fileShell,NULL,0);
    filePanelLabel = XtCreateManagedWidget("filePanelLabel",labelWidgetClass,
					   form,NULL,0);
    filePanelWriteModeButton =
	XtCreateManagedWidget("filePanelWriteModeButton",menuButtonWidgetClass,
			      form,NULL,0);
    filePanelWriteModeLabel =
	XtCreateManagedWidget("filePanelWriteModeLabel",labelWidgetClass,
			      form,NULL,0);
    fcinfo = createFileChooser(fileShell,form,"filePanel",filePanelOk,
			       filePanelCancel,(XtPointer)fileShell);
    /* Adjust vertical layout */
    XtSetArg(args[0],XtNfromVert,filePanelWriteModeButton);
#ifdef FILECHOOSER
    XtSetValues(fcinfo->fcw,args,1);
#else
    XtSetValues(fcinfo->text,args,1);
#endif
    /* Realize them all */
    XtRealizeWidget(fileShell);
    /* Register window for WM */
    (void)XSetWMProtocols(XtDisplay(fileShell),XtWindow(fileShell),
			  &WM_DELETE_WINDOW,1);
    updateFileWriteMode(appResources.fileWriteOnePerLine);
}

static void
writeModeWidgetsShown(state)
Boolean state;
{
    if (state) {
	XtMapWidget(filePanelWriteModeButton);
	XtMapWidget(filePanelWriteModeLabel);
    } else {
	XtUnmapWidget(filePanelWriteModeButton);
	XtUnmapWidget(filePanelWriteModeLabel);
    }
}

void
setFileShellState(state)
int state;
{
    if (!isPoppedUp)
	return;
    switch (state) {
	case NormalState:
	    XtMapWidget(fileShell);
	    break;
	case IconicState:
	    XtUnmapWidget(fileShell);
	    break;
    }
}

/*	-	-	-	-	-	-	-	-	*/
/* Callbacks from the FileChooser */

/*ARGSUSED*/
static void
filePanelOk(fcinfo,filename,client_data)
FileChooserInfo *fcinfo;
char *filename;
XtPointer client_data;		/* shell Widget */
{
    Widget shell = (Widget)client_data;
    int status;

    if (fileGoing) {
	XBell(display,0);
	return;
    }
    fileGoing = True;
    switch (fileOp) {
	case FILE_SAVE:
	    status = save(db,filename);
	    break;
	case FILE_LOAD:
	    status = load(db,filename);
	    break;
	case FILE_WRITE:
	    status = writeToFile(db,filename,appResources.fileWriteOnePerLine);
	    break;
    }
    fileGoing = False;
    if (status) {
	XtPopdown(shell);
	isPoppedUp = False;
    }
}

/*ARGSUSED*/
static void
filePanelCancel(fcinfo,client_data)
FileChooserInfo *fcinfo;
XtPointer client_data;		/* shell Widget */
{
    Widget shell = (Widget)client_data;

    if (fileGoing) {
	XBell(display,0);
	return;
    }
    XtPopdown(shell);
    isPoppedUp = False;
}

/*	-	-	-	-	-	-	-	-	*/
/* Used by the menus */

void
updateFileWriteMode(flag)
Boolean flag;
{
    if (flag)
	setWidgetLabel(filePanelWriteModeLabel,"One entry per line");
    else
	setWidgetLabel(filePanelWriteModeLabel,"Pretty-printed");
}
