/*
 * Copyright 1990 by Baylor College of Medicine ALL RIGHTS RESERVED. 
 *
 * This program is subject to a license agreement between 
 * Baylor College of Medicine and MIT. Any use inconsistent with
 * said license and any use by persons other than the faculty, 
 * students and staff at MIT or any use on a computer not operated 
 * as part of the Athena Computing Environment (ACE) is expressly 
 * prohibited.
 */
/****************************************************************
 * File: search.c
 * Date: 04/26/91
 *
 * Description:
 *   This file contains the search user-interface to the srvlib.
 *
 * Revisions:
 ****************************************************************/
#include <stdio.h>
#include <string.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <Xm/Xm.h>
#include <Xm/PushB.h>
#include <Xm/Label.h>
#include <Xm/Text.h>
#include <Xm/List.h>
#include <VList.h>
#include <srvlib.h>

#include "VtP.h"

static char *defstr = "";
static Boolean created = FALSE;

typedef struct
{
	Widget pop;            /* search popup shell widget */
	Widget oneline;        /* oneline widget where user enters query */
	Widget status;         /* status label widget */
	Widget list;           /* list widget */
	int nid;               /* notebook id */
	long *pages;           /* array of page ids */
	int npages;            /* number of page ids in list */
	SrvContext *srv;       /* server id */
	void (*cb)();          /* callback function to open a page */
	XtPointer data;        /* callback data */
} SearchInfo;

/****************************************************************
 *              Private Functions
 ****************************************************************/

/*ARGSUSED*/
static
void
sel_search(wd,si)
	Widget wd;
	SearchInfo *si;
{
	XmString str;
	char buf[50];
	char *s;

	/* free up pages */
	if (si->npages > 0)
	{
		int i = 0;
		while(si->pages[i])
			XtFree((caddr_t) si->pages[i++]);
		XtFree((caddr_t) si->pages);
	}
	XtVaGetValues(si->oneline,
		XmNvalue,&s,
		NULL);

	XmListDeleteAllItems(si->list);

	if ((s != NULL) && (strlen(s) > 0))
	{
		srv_search_notebook(si->srv,si->nid,1,1,s,&si->pages,&si->npages);
	}
	else
	{
		si->npages = 0;
	}

	sprintf(buf,"Found %d items",si->npages);
	str = XmStringCreateLtoR(buf,XmSTRING_DEFAULT_CHARSET);
	XtVaSetValues(si->status,
		XmNlabelString,str,
		NULL);
	XmStringFree(str);

	if (si->npages > 0)
	{
		int i;

		for (i = 0; i < si->npages; i++)
		{
			Page_Info info;

			srv_inq_page(si->srv,si->nid,si->pages[i],&info);
			str = XmStringCreateLtoR(info.title,XmSTRING_DEFAULT_CHARSET);
			XmListAddItem(si->list,str,i+1);
			XmStringFree(str);
		}
		XmListSelectPos(si->list,1,True);
	}
}

/*ARGSUSED*/
static
void
sel_cancel(w,si)
	Widget w;
	SearchInfo *si;
{
	XtDestroyWidget(si->pop);
}

/*ARGSUSED*/
static
void
sel_list(w, si, list_data)
	Widget w;
	SearchInfo *si;
	XmListCallbackStruct *list_data;
{
	int pid;

	switch(list_data->reason)
	{
		case XmCR_SINGLE_SELECT:
			break;
		case XmCR_DEFAULT_ACTION:
			pid = si->pages[list_data->item_position - 1];
			if (si->cb)
			{
				si->cb(si->nid,pid,si->data);
			}
			XmListDeselectAllItems(si->list);
			break;
		default:
			break;
	}
}

/*ARGSUSED*/
static
void
sel_wild(w,si)
	Widget w;
	SearchInfo *si;
{
	char *txt;
	XtVaGetValues(si->oneline,
		XmNvalue,&txt,
		NULL);

	strcat(txt,"~");

	XtVaSetValues(si->oneline,
		XmNvalue,txt,
		NULL);
}

/*
 * Callback called when popup is destroyed via the window manager
 */
static
void
sel_destroy(w,si)
	Widget w;
	SearchInfo *si;
{
	XtFree((char *)si);
}

/****************************************************************
 *              Public Functions
 ****************************************************************/

/*
 * exported function for activating search popup
 */
PUBLIC
void
VtSearchNotebook(parent,srv,nid,cb,data)
	Widget parent;
	SrvContext *srv;
	int nid;
	void (*cb)();
	XtPointer data;
{
	XmString str;
	Widget form;
	SearchInfo *si = (SearchInfo *)XtMalloc(sizeof(SearchInfo));

	si->srv = srv;
	si->nid = nid;
	si->cb = cb;
	si->data = data;
	si->pages = NULL;
	si->npages = 0;

	si->pop = XtVaCreatePopupShell("SearchPopup",vendorShellWidgetClass,parent,
		XmNwindowGroup,None,
		NULL);
	XtAddCallback(si->pop,XmNdestroyCallback,sel_destroy,(XtPointer)si);

	form = XtVaCreateManagedWidget("form",vListWidgetClass,si->pop,
		XtNvSpacing,2,
		XtNhSpacing,2,
		NULL);
	{
		Widget row = XtVaCreateManagedWidget("Title",vListWidgetClass,form,
			XtNnumRows,1,
			XtNborderWidth,0,
			XtNhSpacing,2,
			XtNvSpacing,2,
			NULL);
		Widget search = XtVaCreateManagedWidget("Search",xmPushButtonWidgetClass,row,
			NULL);
		Widget wild = XtVaCreateManagedWidget("Wildcard",xmPushButtonWidgetClass,row,
			NULL);
		Widget cancel = XtVaCreateManagedWidget("Cancel",xmPushButtonWidgetClass,row,
			NULL);
		XtAddCallback(search,XmNactivateCallback,sel_search,(XtPointer)si);
		XtAddCallback(wild,XmNactivateCallback,sel_wild,(XtPointer)si);
		XtAddCallback(cancel,XmNactivateCallback,sel_cancel,(XtPointer)si);
	}
	{
		Widget row = XtVaCreateManagedWidget("Title",vListWidgetClass,form,
			XtNnumRows,1,
			XtNborderWidth,0,
			XtNhSpacing,2,
			XtNvSpacing,2,
			NULL);
		str = XmStringCreateLtoR("Search For:",XmSTRING_DEFAULT_CHARSET);
		XtVaCreateManagedWidget("SearchLabel",xmLabelWidgetClass,row,
			XmNlabelString,str,
			NULL);
		XmStringFree(str);
		si->oneline = XtVaCreateManagedWidget("editor",xmTextWidgetClass,row,
			XtNstretchHoriz,True,
			NULL);
	}
	{
		si->status = XtVaCreateManagedWidget("StatusLabel",xmLabelWidgetClass,form,
			XtNstretchHoriz,True,
			NULL);
	}
	{
		Arg args[10];
		int n;

		n = 0;
		XtSetArg(args[n],XmNheight,200); n++;
		XtSetArg(args[n],XtNstretchHoriz,True); n++;
		XtSetArg(args[n],XtNstretchVert,True); n++;
		si->list = XmCreateScrolledList(form,"list",args,n);

		XtAddCallback(si->list,XmNsingleSelectionCallback,sel_list,(XtPointer)si);
		XtAddCallback(si->list,XmNdefaultActionCallback,sel_list,(XtPointer)si);

		XtManageChild(si->list);
	}

	XtPopup(si->pop,XtGrabNone);
	XRaiseWindow(XtDisplay(si->pop),XtWindow(si->pop));
}
