#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Xaw/List.h>
#include <X11/Xaw/Box.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/MenuButton.h>
#include <X11/Xaw/SimpleMenu.h>
#include <X11/Xaw/SmeBSB.h>
#include <X11/Xaw/Label.h>
#include "LinkView.h"
#include "LinkText.h"
#include "PcBar.h"

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include "moviedb.h"
#include "dbutils.h"
#include "xregal.h"
#include "popup.h"
#include "tree.h"
#include "genre.h"
#include "printmovies.h"
#include "lookuptitle.h"

/* Function prototypes */
static void searchFromGenreList(Widget, XEvent*, String*, Cardinal*);

Boolean gs_popped_up=False;
int genre_stage=0;
char genre_searchtext[ MXLINELEN ] ;

static Widget genre_list=NULL, genre_shell=NULL;
static Widget genre_form, genre_search, genre_cancel, genre_view;

static Tree genres;
static char **genre_array;

static String myDouble = "<Btn1Up>(2):   searchFromGenreList()\n";
static XtTranslations doubleTransl=NULL;

static XtActionsRec actionTable[] = {
	{"searchFromGenreList",searchFromGenreList}
	};

typedef struct {
	char *text;
	int value;
	} GenreItem;

Boolean doGenreSearch(XtPointer client_data) {
	static FILE  *dbFp = NULL;
	static FILE  *titleKeyFp = NULL;
	static FILE  *titleIndexFp = NULL;
	TitleID titleKey ;
	int len ;
	char line [MXLINELEN];
	AttributeID attrKey;
	static TitleRec *head;
	static TitleRec *tail;
	static int count;
	static long upper;
	static int lastpcdone=0;
	int final_message;
	int pcdone;
	char buf[MAXPATHLEN];

	if (genre_stage==0) {
		count=0;
		dbFp = openFile (GENREDB);
		titleKeyFp = openFile(TITLEKEY);
		titleIndexFp = openFile(TITLEIDX);
		fseek(dbFp, 0, SEEK_END);
		upper=ftell(dbFp);
		rewind(dbFp);
		genre_stage++;
		return False;
		}

	if (genre_stage == 1) {
		while (!feof(dbFp)) { 

			/* update display */
			pcdone=ftell(dbFp)*100/upper;
			if (pcdone != lastpcdone) {
				lastpcdone=pcdone;
				if (app_data.showprogress) {
					PcBarSetPercentage(pcbar, pcdone);
					sprintf(buf, "Matches on '%s': %d", genre_searchtext, count);
					SetTitle(buf);
					}
				return False;
				}

		    titleKey = getTitle ( dbFp ) ;
	    	len = getByte ( dbFp ) ;
	    	fread(line, 1, len, dbFp ) ;
			line [len] = '\0' ;
    		attrKey = getAttr ( dbFp ) ;
			if (strcmp(line, genre_searchtext)==0) {
				if (count == 0) {
					head = newTitleRec();
					head->title = mapTitleKeyToText(titleKey, titleKeyFp, titleIndexFp);
					head->titleKey = titleKey;
					tail=head;
					}
				else {
					tail->next = newTitleRec();
					tail = tail->next;
					tail->title = mapTitleKeyToText(titleKey, titleKeyFp, titleIndexFp);
					tail->titleKey = titleKey;
					}	
				count++;	
				}
			} 

		fclose(dbFp);
		fclose(titleKeyFp);
		fclose(titleIndexFp);
		genre_stage++;
		if (app_data.showprogress) return False;
		}

	PcBarSetPercentage(pcbar, 0);
	final_message=SEARCH_OK;

	sprintf(line, "Genre: %s", genre_searchtext);
	if (count<200)
		addAka(head);
	displayListOfMovies(head, line, final_message);
	freeTitles(head);
	SetBusy(viewer, False);
	genre_stage=0;
	search_in_progress=False;
	return True;
	}



static void Search(Widget w, XtPointer client_data, XtPointer call_data) {
	int index;
	char *cp;

	index=XawListShowCurrent(genre_list)->list_index;
	if (index ==  XAW_LIST_NONE)
		return;

	XtPopdown(genre_shell);
	gs_popped_up=False;	
	enableSearch();
	SetBusy(viewer, True);
	XFlush(XtDisplay(topLevel));

	strcpy(genre_searchtext, genre_array[index]);
	cp=strchr(genre_searchtext, ' ');
	if (cp!=NULL)
		*cp='\0';

	search_in_progress=True;
	XtAppAddWorkProc(app_context, doGenreSearch, NULL);
	}

void searchFromGenreList(Widget w, XEvent *ev, String *x, Cardinal *y) {
	Search(w, NULL, NULL);
	}

static void Cancel(Widget w, XtPointer client_data, XtPointer call_data) {
	XtPopdown(genre_shell);
	gs_popped_up=False;
	enableSearch();
	}


void CreateGenreDialog(Widget parent) {
	static String myreturn = "#override <Key>Return:   set() notify() unset()\n";
	static String myescape = "#override <Key>Escape:   set() notify() unset()\n";
	XtAccelerators escaccel;
	XtAccelerators accel;
	Dimension spacing;
	XFontStruct *font;

	accel = XtParseAcceleratorTable(myreturn);
	escaccel = XtParseAcceleratorTable(myescape);

	genre_shell=XtVaCreatePopupShell("genre_shell",
                transientShellWidgetClass,  parent,
                XtNallowShellResize, True, NULL);

	genre_form=XtVaCreateManagedWidget("genre_form",formWidgetClass,
				genre_shell, NULL);
	genre_view=XtVaCreateManagedWidget("genre_view",linkViewWidgetClass,
				genre_form,
		        XtNborderWidth, 2,
		        XtNallowVert, True,
	        	XtNallowHoriz, True,
				XtNbottom, XtChainBottom,
		        NULL);


  genre_list=XtVaCreateManagedWidget("genre_list",listWidgetClass,genre_view,
        XtNlist, NULL,
        NULL);

  XtVaGetValues(genre_list, XtNrowSpacing, &spacing, XtNfont, &font, NULL);
  spacing +=  font->max_bounds.ascent + font->max_bounds.descent;
  XtVaSetValues(genre_view, XtNbaselineskip, spacing, NULL);

  genre_search=XtVaCreateManagedWidget("genre_search",commandWidgetClass, genre_form,
        XtNfromVert, genre_view,
		XtNlabel, "Search",
        XtNaccelerators, accel,
		XtNleft, XtChainLeft,
		XtNright, XtChainLeft,
		XtNtop, XtChainBottom,
		XtNbottom, XtChainBottom,
		NULL);
  genre_cancel=XtVaCreateManagedWidget("genre_cancel",commandWidgetClass,genre_form,
        XtNfromVert, genre_view,
		XtNfromHoriz, genre_search,
		XtNlabel, "Cancel",
        XtNaccelerators, escaccel,
		XtNleft, XtChainLeft,
		XtNright, XtChainLeft,
		XtNtop, XtChainBottom,
		XtNbottom, XtChainBottom,
		NULL);

  XtAddCallback(genre_cancel, XtNcallback, Cancel, 0);
  XtAddCallback(genre_search, XtNcallback, Search, 0);
  XtSetKeyboardFocus(genre_form, genre_view);
  XtInstallAccelerators(genre_view, genre_cancel);
  XtInstallAccelerators(genre_view, genre_search);

	if (!doubleTransl) {
		XtAppAddActions(app_context, actionTable, 1);
		doubleTransl = XtParseTranslationTable(myDouble);
		}
	XtOverrideTranslations(genre_list, doubleTransl);
	}


	


void read_genres(void) {
	FILE  *dbFp = NULL;
	TitleID titleKey ;
	int len ;
	char line [ MXLINELEN ] ;
	AttributeID attrKey;

	dbFp = openFile (GENREDB);
	TreeInitialize(&genres);
	while (!feof(dbFp)) { 
	    titleKey = getTitle ( dbFp ) ;
	    len = getByte ( dbFp ) ;
    	fread(line, 1, len, dbFp ) ;
		line [len] = '\0' ;
    	attrKey = getAttr ( dbFp ) ;
		TreeInsert(&genres, line);
		} 
	genre_array=TreeToArray(&genres, 1);
	fclose(dbFp);
	}



void PopupGenre(void) {
	if (genre_shell==NULL) {
		SetBusy(viewer, True);
		XFlush(XtDisplay(topLevel));
		CreateGenreDialog(topLevel);
		read_genres();
		XawListChange(genre_list, genre_array, 0, 0,True);
		SetBusy(viewer, False);
		}

	disableSearch();
	SetPopupPosition(genre_shell, topLevel);
	XtPopup(genre_shell, XtGrabExclusive);
	XDefineCursor(XtDisplay(topLevel), XtWindow(genre_form), unBusyCursor);
	gs_popped_up=True;
	XawListChange(genre_list, genre_array, 0, 0,True);
	}
