/* index.c
   processing for full index search support */

     /*---------------------------------------------------------------*/
     /* Xgopher        version 1.3     08 April 1993                  */
     /*                version 1.2     20 November 1992               */
     /*                version 1.1     20 April 1992                  */
     /*                version 1.0     04 March 1992                  */
     /* X window system client for the University of Minnesota        */
     /*                                Internet Gopher System.        */
     /* Allan Tuchman, University of Illinois at Urbana-Champaign     */
     /*                Computing and Communications Services Office   */
     /* Copyright 1992, 1993 by                                       */
     /*           the Board of Trustees of the University of Illinois */
     /* Permission is granted to freely copy and redistribute this    */
     /* software with the copyright notice intact.                    */
     /*---------------------------------------------------------------*/


#include <stdio.h>

#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>

#include <X11/Shell.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/AsciiText.h>

#include "osdep.h"
#include "compatR4.h"
#include "index.h"
#include "gui.h"
#include "appres.h"
#include "xglobals.h"

#define INDEX_SHELL_TITLE	"Index Search"


static	Widget		topLevel;
static	Widget		indexShell,
			queryText, doIndexButton,
			indexLabel;
static	Boolean		indexPanelCreated = False;
static	XtPointer	savedItem;

#define THIS_POPUP_NAME		"indexPopup"

				/* default values */
static popupPosResources	placement = {

	/* position at the top of the main panel, centered across */
	from_main, 50, 0, justify_center, justify_top_left, True, True
	};



/* helpProc
   provide help for a index search session */

static void
helpProc(w, clientData, callData)
Widget		w;
XtPointer	clientData, callData;
{
	showHelp("index help");
}


/* doIndexProc
   submit a query to an index search */

static void
doIndexProc(w, clientData, callData)
Widget		w;
XtPointer	clientData, callData;
{
	Cardinal	n;
	Arg		args[5];
	char		*string, *s;
	int		length;
	Boolean		inPlace;


	n=0;
	XtSetArg(args[n], XtNstring, &s);  n++;
	XtGetValues(queryText, args, n);
	length = strlen(s);

	string = XtMalloc(length + 1);
	strncpy (string, s, length);
	string[length] = '\0';

	if (strlen(string) == 0) {
		showError("Enter a query string.");
	} else {

		XtRemoveAllCallbacks(doIndexButton, XtNcallback);
		/* do Index */
		XtPopdown(indexShell);

		processIndexSelection(clientData, string);
	}

}


/* cancelProc
   cancel a index search session */

static void
cancelProc(w, clientData, callData)
Widget		w;
XtPointer	clientData, callData;
{
	Cardinal	n;
	Arg		args[5];

	XtRemoveAllCallbacks(doIndexButton, XtNcallback);
	XtPopdown(indexShell);
}


/* removeIndexPanel
   remove the index panel (Pop down).  Similar to cancel button,
   but a public interface with no parameters. */

void
removeIndexPanel()
{
	cancelProc(NULL, NULL, NULL);
}


/* IndexOk
   accept the "do Index" action from a keyboard <cr> instead of the
   "do Index" button.  The <cr> translation is defined elsewhere.
   Capitalized name is for X action proc convention. */

static void
IndexOk(w, event, parms, nparms)
Widget          w;
XEvent          *event;
String          *parms;
Cardinal        *nparms;
{
	XtCallActionProc(doIndexButton, "set", NULL, NULL, 0);
        doIndexProc(w, savedItem, NULL);
	XtCallActionProc(doIndexButton, "unset", NULL, NULL, 0);
        return;
}


/* IndexCancel
   accept the "do Index" action by a translation.
   Capitalized name is for X action proc convention. */

static void
IndexCancel(w, event, parms, nparms)
Widget          w;
XEvent          *event;
String          *parms;
Cardinal        *nparms;
{
        cancelProc(w, NULL, NULL);
        return;
}


/* displayIndexPanel
   display the panel for index search queries */

void
displayIndexPanel(clientData, title)
XtPointer	clientData;
char		*title;
{
	Arg		args[10];
	Cardinal	n;
	char		titleString[128];


	sprintf (titleString, "Search of:  %.60s\n", title);
	n=0;
	XtSetArg(args[n], XtNlabel, titleString);  n++;
	XtSetValues(indexLabel, args, n);

	XtAddCallback(doIndexButton, XtNcallback, doIndexProc, clientData);
	savedItem = clientData;

	positionAPopup(indexShell, topLevel, &placement);

	XtPopup (indexShell, XtGrabNone);

	if (appResources->warpCursor) {
		XWarpPointer(XtDisplay(indexShell), None,
				XtWindow(queryText),
				0, 0, 0, 0,
				10, 5);

	}


	return;
}


/* makeIndexPanel
   create the X panel for Index Search queries */

void
makeIndexPanel(top)
Widget	top;
{
	Arg		args[10];
	Cardinal	n;
	Widget		indexForm;
	Widget		cancelButton, helpButton;
	static XtActionsRec     indexActionsTable[] = {
				{ "indexok", (XtActionProc) IndexOk },
				{ "indexCancel", (XtActionProc) IndexCancel }
					};


	if (indexPanelCreated) return;

	topLevel = top;


	/* create Index Search shell */

		n=0;
		XtSetArg(args[n], XtNtitle, INDEX_SHELL_TITLE);  n++;
	indexShell = XtCreatePopupShell("indexShell",
				transientShellWidgetClass,
				topLevel, args, n);


	/* create Index Search main panel form */

		n=0;
	indexForm  = XtCreateManagedWidget("indexForm",
				formWidgetClass,
				indexShell, args, n);


	/* create DO QUERY button */

		n=0;
		XtSetArg(args[n], XtNtop,	XawChainTop);  n++;
		XtSetArg(args[n], XtNbottom,	XawChainTop);  n++;
		XtSetArg(args[n], XtNleft,	XawChainLeft);  n++;
		XtSetArg(args[n], XtNright,	XawChainLeft);  n++;
	doIndexButton = XtCreateManagedWidget("indexDoIndex",
				commandWidgetClass,
				indexForm, args, n);


	/* create CANCEL button */

		n=0;
		XtSetArg(args[n], XtNfromHoriz,	doIndexButton);  n++;
		XtSetArg(args[n], XtNtop,	XawChainTop);  n++;
		XtSetArg(args[n], XtNbottom,	XawChainTop);  n++;
		XtSetArg(args[n], XtNleft,	XawChainLeft);  n++;
		XtSetArg(args[n], XtNright,	XawChainLeft);  n++;
	cancelButton = XtCreateManagedWidget("indexCancel", commandWidgetClass,
				indexForm, args, n);
		XtAddCallback(cancelButton, XtNcallback, cancelProc, NULL);


	/* create HELP button */

		n=0;
		XtSetArg(args[n], XtNfromHoriz,	cancelButton);  n++;
		XtSetArg(args[n], XtNtop,	XawChainTop);  n++;
		XtSetArg(args[n], XtNbottom,	XawChainTop);  n++;
		XtSetArg(args[n], XtNleft,	XawChainLeft);  n++;
		XtSetArg(args[n], XtNright,	XawChainLeft);  n++;
	helpButton = XtCreateManagedWidget("indexHelp", commandWidgetClass,
				indexForm, args, n);
		XtAddCallback(helpButton, XtNcallback, helpProc, NULL);
	

	/* create INDEX label */

		n=0;
		XtSetArg(args[n], XtNfromVert,	doIndexButton);  n++;
		XtSetArg(args[n], XtNtop,	XawChainTop);  n++;
		XtSetArg(args[n], XtNbottom,	XawChainTop);  n++;
		XtSetArg(args[n], XtNleft,	XawChainLeft);  n++;
		XtSetArg(args[n], XtNright,	XawChainLeft);  n++;
	indexLabel = XtCreateManagedWidget("indexLabel",
				labelWidgetClass,
				indexForm, args, n);


	/* create NAME TEXT entry */

		n=0;
		XtSetArg(args[n], XtNeditType, XawtextEdit);  n++;
		XtSetArg(args[n], XtNstring, "");  n++;
		XtSetArg(args[n], XtNfromVert,	indexLabel);  n++;
		XtSetArg(args[n], XtNtop,	XawChainTop);  n++;
		XtSetArg(args[n], XtNbottom,	XawChainBottom);  n++;
		XtSetArg(args[n], XtNleft,	XawChainLeft);  n++;
		XtSetArg(args[n], XtNright,	XawChainRight);  n++;
	queryText = XtCreateManagedWidget("indexQueryText",
				asciiTextWidgetClass,
				indexForm, args, n);
		setTextWidgetSize(queryText, 60, 1);
	XtOverrideTranslations(queryText, oneLineParsed);

	XtAppAddActions(appcon, indexActionsTable,
		 XtNumber(indexActionsTable));

	XtSetKeyboardFocus(indexForm, queryText);

        /* for ICCCM window manager protocol complience */

        XtOverrideTranslations (indexShell,
            XtParseTranslationTable ("<Message>WM_PROTOCOLS: indexCancel()"));
        XtRealizeWidget(indexShell);
        (void) XSetWMProtocols (XtDisplay(indexShell), XtWindow(indexShell),
                                    &wmDeleteAtom, 1);

	/* find the popup placement for this shell */

	{
	popupPosResources *resourcePlacement;

	resourcePlacement = getPopupPosResources(
				THIS_POPUP_NAME, POPUP_POS_CLASS, &placement);
	bcopy( (char *) resourcePlacement, (char *) &placement,
				sizeof(popupPosResources) );
	}


	indexPanelCreated = True;
}
