/*
 * help.c : The Help browser
 *
 * George Ferguson, ferguson@cs.rochester.edu, 23 Apr 1993.
 * 13 May 1993: Change the way the version number is printed.
 */

#include <stdio.h>
#include <X11/Intrinsic.h>
#include <X11/Shell.h>
#include <X11/StringDefs.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/Viewport.h>
#include <X11/Xaw/List.h>
#include <X11/Xaw/AsciiText.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Cardinals.h>
#include "xarchie.h"
#include "xutil.h"
#include "patchlevel.h"

/*
 * Functions defined here
 */
void initHelpActions(),initHelpPanel();
void setHelpShellState();

static void popupHelpPanel();
static void initHelpWidgets();
static void helpCallback();
static void helpDoneAction(),helpPrevAction(),helpNextAction();
static void helpDownAction(),helpUpAction();

/*
 * Data defined here
 */
static Widget helpShell;
static Widget helpLabel,helpViewport,helpList,helpText;
static Widget helpScrollbar;
static Widget helpPrevButton,helpNextButton;

static Boolean isPoppedUp;
static int numHelpTopics;

static XtActionsRec actionTable[] = {
    { "help",		popupHelpPanel },
    { "help-done",	helpDoneAction },
    { "help-prev",	helpPrevAction },
    { "help-next",	helpNextAction },
    { "help-down",	helpDownAction },
    { "help-up",	helpUpAction },
};

static char *helpStrings[] = {
#include "help-text1.h"
    NULL
};

static struct {
    int lineno;
    char *string;
} helpTopicInfo[] = {
#include "help-text2.h"
};

static char **helpTopics;

/*	-	-	-	-	-	-	-	-	*/

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

void
initHelpPanel()
{
    int i;

    /* Last entry in help-text2.h is bogus */
    numHelpTopics = XtNumber(helpTopicInfo)-1;
    /* Make an array with just the strings for the List widget */
    helpTopics = (char **)XtCalloc(numHelpTopics,sizeof(char*));
    for (i=0; i < numHelpTopics; i++)
	*(helpTopics+i) = helpTopicInfo[i].string;
}

static void
popupHelpPanel()
{
    if (isPoppedUp) {
	XRaiseWindow(display,XtWindow(helpShell));
	return;
    }
    if (helpShell == NULL) {
	initHelpWidgets();
    }
    isPoppedUp = True;
    XtPopup(helpShell,XtGrabNone);
}

static void
initHelpWidgets()
{
    Widget form;
    char buf[64];

    helpShell = XtCreatePopupShell("helpShell",topLevelShellWidgetClass,
				   toplevel,NULL,0);
    form = XtCreateManagedWidget("helpForm",formWidgetClass,
				 helpShell,NULL,0);
    helpLabel = XtCreateManagedWidget("helpLabel",labelWidgetClass,
				      form,NULL,0);
#ifdef BETA
    sprintf(buf,"This is help for Xarchie %.1fb%d",VERSION,PATCHLEVEL);
#else
    sprintf(buf,"This is help for Xarchie %.1f.%d",VERSION,PATCHLEVEL);
#endif
    setWidgetLabel(helpLabel,buf);
    helpViewport = XtCreateManagedWidget("helpViewport",viewportWidgetClass,
					 form,NULL,0);
    helpList = XtCreateManagedWidget("helpList",listWidgetClass,
				     helpViewport,NULL,0);
    XawListChange(helpList,helpTopics,numHelpTopics,0,True);
    XtAddCallback(helpList,XtNcallback,helpCallback,NULL);
    helpText = XtCreateManagedWidget("helpText",asciiTextWidgetClass,
				     form,NULL,0);
    (void)XtCreateManagedWidget("helpDoneButton",commandWidgetClass,
				form,NULL,0);
    helpPrevButton = XtCreateManagedWidget("helpPrevButton",commandWidgetClass,
					   form,NULL,0);
    XtSetSensitive(helpPrevButton,False);
    helpNextButton = XtCreateManagedWidget("helpNextButton",commandWidgetClass,
					   form,NULL,0);
    XtSetSensitive(helpNextButton,False);
    (void)XtCreateManagedWidget("helpDownButton",commandWidgetClass,
				form,NULL,0);
    (void)XtCreateManagedWidget("helpUpButton",commandWidgetClass,
				form,NULL,0);
    XtRealizeWidget(helpShell);
    (void)XSetWMProtocols(XtDisplay(helpShell),XtWindow(helpShell),
			  &WM_DELETE_WINDOW,1);
    helpScrollbar = XtNameToWidget(helpViewport,"vertical");
}

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

/*	-	-	-	-	-	-	-	-	*/
/* Callback procedure */

/*ARGSUSED*/
static void
helpCallback(w,client_data,call_data)
Widget w;
XtPointer client_data;  /* not used */
XtPointer call_data;    /* returnStruct */
{
    int topic = ((XawListReturnStruct*)call_data)->list_index;
    XawTextPosition pos;
    XawTextBlock block;
    Arg args[2];
    int i;

    block.firstPos = 0;
    block.format = FMT8BIT;
    /* Reset helpText */
    XtSetArg(args[0],XtNstring,"");
    XtSetArg(args[1],XtNeditType,XawtextEdit);
    XtSetValues(helpText,args,2);
    pos = (XawTextPosition)0;
    XawTextDisableRedisplay(helpText);
    for (i=helpTopicInfo[topic].lineno; helpStrings[i] != NULL; i++) {
	/* Add helpStrings[i] to helpText */
	block.ptr = helpStrings[i];
	block.length = strlen(helpStrings[i]);
	XawTextReplace(helpText,pos,pos,&block);
	pos += block.length;
    }
    XawTextEnableRedisplay(helpText);
    XtSetArg(args[0],XtNeditType,XawtextRead);
    XtSetValues(helpText,args,1);
    XtSetSensitive(helpPrevButton,(topic != 0));
    XtSetSensitive(helpNextButton,(topic != numHelpTopics-1));
}


/*	-	-	-	-	-	-	-	-	*/
/* 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(helpDoneAction)
{
    XtPopdown(helpShell);
    isPoppedUp = False;
}

/*ARGSUSED*/
static
ACTION_PROC(helpPrevAction)
{
    XawListReturnStruct *ret = XawListShowCurrent(helpList);
    float percent;

    if (ret->list_index != XAW_LIST_NONE && ret->list_index != 0) {
	ret->list_index -= 1;
	/* Highlight the item */
	XawListHighlight(helpList,ret->list_index);
	/* Get the text displayed */
	helpCallback(helpList,NULL,(XtPointer)ret);
	/* Adjust the scrollbar so it's visible */
	percent = (float)(ret->list_index-1) / (float)numHelpTopics;
	XtCallCallbacks(helpScrollbar,"jumpProc",(XtPointer)&percent);
    }
}

/*ARGSUSED*/
static
ACTION_PROC(helpNextAction)
{
    XawListReturnStruct *ret = XawListShowCurrent(helpList);
    float percent;

    if (ret->list_index != XAW_LIST_NONE &&
	ret->list_index != numHelpTopics-1) {
	ret->list_index += 1;
	XawListHighlight(helpList,ret->list_index);
	helpCallback(helpList,NULL,(XtPointer)ret);
	percent = (float)(ret->list_index-1) / (float)numHelpTopics;
	XtCallCallbacks(helpScrollbar,"jumpProc",(XtPointer)&percent);
    }
}

/*ARGSUSED*/
static
ACTION_PROC(helpDownAction)
{
    XtCallActionProc(helpText,"next-page",event,NULL,0);
}

/*ARGSUSED*/
static
ACTION_PROC(helpUpAction)
{
    XtCallActionProc(helpText,"previous-page",event,NULL,0);
}

