/* This code contributed by Paolo Brutti <gi0570@rh0015.roma.tlsoft.it> */

#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include "xregal.h"
#include "searchHistory.h"

typedef struct {
	String *list;
	int iElems;
	int iCurrent;
} History;

static struct _history{
	Widget wdg;
	History *hist;
} *histories=NULL;

/* The number of text widgets with history mechanisms added */
static int numHistories=0;


static String myHist = "<Key>Up: historyUp()\n<Key>Down: historyDown()\n";
static XtTranslations histTransl=NULL;

static void historyUp(Widget wdg,
                     XEvent *event,
                     String *params,
                     Cardinal *num_params);
static void historyDown(Widget wdg,
                     XEvent *event,
                     String *params,
                     Cardinal *num_params);

static XtActionsRec actionTable[] = {{"historyUp",historyUp},
                                     {"historyDown",historyDown}};

static void addToHistory(History *hist, String str) {
	hist->list = (String *)XtRealloc((char *)hist->list,
	                                 (hist->iElems+1)*sizeof(String));
	hist->iCurrent = hist->iElems;
	hist->list[hist->iElems++] = XtNewString(str);
	}



/* Add a history mechanism to the given text widget */

void AddHistoryText(Widget wdg) {
	if (!histTransl) {
	  	XtAppAddActions(app_context, actionTable, XtNumber(actionTable));
  		histTransl = XtParseTranslationTable(myHist);
		}
	XtOverrideTranslations(wdg, histTransl);

	histories = (struct _history *)XtRealloc((char *)histories,
	                                         (numHistories+1)*sizeof(struct _history));
	histories[numHistories].wdg = wdg;
	histories[numHistories++].hist = (History *)XtCalloc(1,sizeof(History));
	}




void AddStringToHistory(Widget wdg, String str) {
	int i;
	
	for (i=0; i<numHistories; i++) {
		if (histories[i].wdg == wdg) {
			addToHistory(histories[i].hist, str);
			return;
			}
		}
	}



/* for the given widget, reset the current pointer to the last text item
   that was entered */

void ResetHistory(Widget wdg) {

	int i;
	
	for (i=0; i<numHistories; i++) {
		if (histories[i].wdg == wdg) {
			histories[i].hist->iCurrent = histories[i].hist->iElems;
			return;
			}
		}
	}


/* Go to the previous history item (if it exists) */

static void historyUp(Widget wdg,
                     XEvent *event,
                     String *params,
                     Cardinal *num_params) {
	int i;
	
	for (i=0; i<numHistories; i++) {
		if (histories[i].wdg == wdg) {
			History *hist=histories[i].hist;
			if(hist->iElems) {
 				if(hist->iCurrent)
					 hist->iCurrent--;
 				XtVaSetValues(wdg, XtNstring, hist->list[hist->iCurrent],NULL);
				}
			return;
			}
		}
	} 	



/* Go to the next history item (if it exists) */

static void historyDown(Widget wdg,
                     XEvent *event,
                     String *params,
                     Cardinal *num_params) {
	int i;
	
	for (i=0; i<numHistories; i++) {
		if (histories[i].wdg == wdg) {
			History *hist=histories[i].hist;
			if(hist->iCurrent<(hist->iElems-1))
				XtVaSetValues(wdg, XtNstring, hist->list[++(hist->iCurrent)],NULL);
			else {
				XtVaSetValues(wdg, XtNstring, NULL, NULL);
				if (hist->iCurrent == (hist->iElems-1))
					hist->iCurrent++;
				}
			return;
			}
		}
	} 	



