/********************** modified from myfont.c *******************/
/********************* to test the use of XmScrolledList *********/

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#ifdef SYS_DIR
#include <sys_dir.h>
#else
#ifdef NDIR
#include <ndir.h>
#else
#include <dirent.h>
#endif
#endif

#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>

#include <stdlib.h>

#include <X11/Intrinsic.h>
#include <X11/IntrinsicP.h>
#include <X11/CoreP.h>
#include <X11/Shell.h>
#include <Xm/XmAll.h>

void main();
Widget MyCreateMain(Widget );
Widget SelectedFontSample(Widget );
Widget MyHelpDialog(Widget,int );

Widget slist;
Widget command_window;
//Widget swindow;
static int call_back_signal = 0;

void FontSelectedCB(Widget,caddr_t,caddr_t);
void CloseCB(Widget,caddr_t,caddr_t);
void HelpCB(Widget,int,caddr_t);
void QuitCB(Widget,caddr_t,caddr_t);
void ListSelectCB(Widget,caddr_t,XmListCallbackStruct *);
void ListActionCB(Widget,caddr_t,caddr_t);
void CommandWindowInputCB(Widget,caddr_t,caddr_t);
void MenuCommandCB(Widget,caddr_t,caddr_t);
void ActiveCB(Widget,caddr_t,caddr_t);

#define MAX_ARGS 20

#define MENU_DISPLAY_POSITION 201
#define MENU_NEXT_POSITION 202

typedef struct
{
	char *fontpath;
}ApplicationData,*ApplicationDataPtr;

class ManPath;
class SubDir;
class ManItem;

class ManPath
{
public:
	ManPath*	next;
	char *	alias;
	char *	man_path;
	SubDir*	sub_dir[11];
public:
	ManPath(char * path_name);
	~ManPath();
	LoadManPath(char *);
	int GetSize(char c);
	int GetItems(char c, ManItem *buffer[]);
};

class SubDir 
{
public:
	ManPath *man_path;
	int	buffer_length;
	int count;
	ManItem **item_list;
public:
	SubDir(ManPath *);
	~SubDir();
	void AddItem(char* name);
	int GetSize();
	int GetItems(ManItem *buffer[]);
};

class ManItem
{
public:
	SubDir		*sub_dir;
	char		*name;
public:
	ManItem(SubDir *, char* name);
	~ManItem();
};

void InitData();
static void attach (char *dest, const char *dirname, const char *name);
static int subdir_translate_c_to_n(char c);
static int ManItemComp(ManItem ** a,ManItem ** b);
static int ItemMatch(char *);
static void active_man_page(ManItem *);

ManPath * man_paths;
ManItem ** item_list;
int item_list_length;
int item_list_count;

ApplicationData AppData;

#define XtNfontPath "fontPath"
#define XtCFontPath "FontPath"
static XtResource resources[] = 
{
	{
		XtNfontPath,XtCFontPath,XmRString,sizeof(String),
		XtOffset(ApplicationDataPtr,fontpath),
		//XmRString,"/usr/lib/X11/fonts/misc"
		XmRString,"/home/wxk/fonts"
	}
};

static XmStringCharSet charset = (XmStringCharSet)XmSTRING_DEFAULT_CHARSET;

/********************** main **********************/
void main(int argc,char ** argv)
{
	Widget toplevel;
	Widget main_window;
	XtAppContext app_context;

	toplevel = XtVaAppInitialize(&app_context,"XMdemos",NULL,0,
				&argc,argv,NULL,XmNallowShellResize,True,NULL);
	main_window = MyCreateMain(toplevel);
	XtRealizeWidget(toplevel);

	XtAppMainLoop(app_context);
}

/********************* MyCreateMain *************************/
Widget MyCreateMain(Widget parent)
{
	Widget main_window;
	Widget menu_bar;
	Widget menu_pane;
	Widget cascade;
	Widget frame;
	Widget form;
	Widget button;
	Widget hsb,vsb;

	Arg args[MAX_ARGS];
	register int n;
	DIR *dirp;
	#if defined(SYS_DIR)||defined(NDIR)
		struct direct *item;
	#else
		struct dirent *item;
	#endif

	char filename[80];
	int len;
	int i,j,k;
	XmString label_string;
	XmString stringx[2];

	/***************** Init Data *************/
	InitData();

	printf("piont3.0\n");
	/***************** Create MainWindow *************/
	n = 0;
	main_window = XmCreateMainWindow(parent,"main1",args,n);
	XtManageChild(main_window);

	/***************** Create MenuBar  ***************/
	n = 0;
	menu_bar = XmCreateMenuBar(main_window,"menu_bar",args,n);
	XtManageChild(menu_bar);
	XmAddTabGroup(menu_bar);

	/***************** Create "exit" menu ************/
	n = 0;
	menu_pane = XmCreatePulldownMenu(menu_bar,"menu_pane",args,n);

	n = 0;
	button = XmCreatePushButton(menu_pane,"Quit",args,n);
	XtManageChild(button);
	XtAddCallback(button,XmNactivateCallback,(void (*)(Widget,void *, void *))QuitCB,(XtPointer)NULL);

	n = 0;
	button = XmCreatePushButton(menu_pane,"Display",args,n);
	XtManageChild(button);
	XtAddCallback(button,XmNactivateCallback,(void (*)(Widget,void *, void *))MenuCommandCB,(XtPointer)MENU_DISPLAY_POSITION);

	n = 0;
	button = XmCreatePushButton(menu_pane,"Next",args,n);
	XtManageChild(button);
	XtAddCallback(button,XmNactivateCallback,(void (*)(Widget,void *, void *))MenuCommandCB,(XtPointer)MENU_NEXT_POSITION);

	printf("piont3.2\n");
	n = 0;
	XtSetArg(args[n],XmNsubMenuId,menu_pane);n++;
	cascade = XmCreateCascadeButton(menu_bar,"Exit",args,n);
	XtManageChild(cascade);

	/***************** Create "help" menu ************/
	n = 0;
	//cascade = XmCreateCascadeButton(menu_bar,"help",args,n);
	cascade = XmCreateCascadeButtonGadget(menu_bar,"help",args,n);
	XtManageChild(cascade);
	XtAddCallback(cascade,XmNactivateCallback,(void (*)(Widget,void *, void *))HelpCB,(XtPointer)1);

	n = 0;
	XtSetArg(args[n],XmNmenuHelpWidget,cascade);n++;
	XtSetValues(menu_bar,args,n);

	/***************** Create Frame window ********/
	n = 0;
	XtSetArg(args[n],XmNmarginWidth,2);n++;
	XtSetArg(args[n],XmNmarginHeight,2);n++;
	XtSetArg(args[n],XmNshadowThickness,1);n++;
	XtSetArg(args[n],XmNshadowType,XmSHADOW_OUT);n++;
	frame = XmCreateFrame(main_window,"frame",args,n);
	XtManageChild(frame);

	/***************** Create command window ********/
	n = 0;
	form = XmCreateForm(frame,"form",args,n);
	XtManageChild(form);
	n = 0;
	XtSetArg(args[n],XmNtopAttachment,XmATTACH_FORM);n++;
	XtSetArg(args[n],XmNleftAttachment,XmATTACH_FORM);n++;
	XtSetArg(args[n],XmNrightAttachment,XmATTACH_FORM);n++;
	command_window = XmCreateTextField(form,"textfield",args,n);
	XtManageChild(command_window);

	/***************** Create Scrolled list ***************/
	n = 0;
	XtSetArg(args[n],XmNtopAttachment,XmATTACH_WIDGET);n++;
	XtSetArg(args[n],XmNtopWidget,command_window);n++;
	XtSetArg(args[n],XmNleftAttachment,XmATTACH_FORM);n++;
	XtSetArg(args[n],XmNrightAttachment,XmATTACH_FORM);n++;
	XtSetArg(args[n],XmNbottomAttachment,XmATTACH_FORM);n++;
	XtSetArg(args[n],XmNscrollBarDisplayPolicy,XmAS_NEEDED);n++;
	XtSetArg(args[n],XmNscrollingPolicy,XmAUTOMATIC);n++;
	XtSetArg(args[n],XmNvisibleItemCount,30);n++;
	XtSetArg(args[n],XmNlistMarginWidth,5);n++;
	XtSetArg(args[n],XmNwidth,400);n++;
	XtSetArg(args[n],XmNlistSizePolicy,XmCONSTANT);n++;
	slist = XmCreateScrolledList(form,"slist",args,n);
	XtManageChild(slist);

	/**************** Set MainWindow areas and add tab groups *******
	XmMainWindowSetAreas(main_window,menu_bar,NULL,NULL,NULL,frame);
	n = 0;
	XtSetArg(args[n],XmNhorizontalScrollBar,&hsb);n++;
	XtSetArg(args[n],XmNverticalScrollBar,&vsb);n++;
	XtGetValues(swindow,args,n);
	XmAddTabGroup(slist);
	printf("hsb = %x, vsb = %x",hsb,vsb);
	if(hsb) XmAddTabGroup(hsb);
	if(vsb) XmAddTabGroup(vsb);
	*/
	XmAddTabGroup(slist);
	XmAddTabGroup(command_window);

	//system("ls /home/wxk/x ");
	/**************** Create items in the slist **********/
	for (i=0;i<item_list_count;i++)
	{
		label_string = XmStringCreateLtoR(item_list[i]->name,charset);
		XmListAddItem(slist,label_string,0);
		//if (!strcmp(filename,"core")) stringx[0] = label_string;
		XmStringFree(label_string);
	}
	n = 0;
	//XtSetArg(args[n],XmNselectedItemCount,1);n++;
	//XtSetArg(args[n],XmNselectedItems,stringx);n++;
	//XtSetArg(args[n],XmNtopItemPosition,14);n++;
	XtSetValues(slist,args,n);
	XtAddCallback(slist,XmNbrowseSelectionCallback,(void (*)(Widget,void *, void *))ListSelectCB,(XtPointer)NULL);
	XtAddCallback(slist,XmNdefaultActionCallback,(void (*)(Widget,void *, void *))ActiveCB,(XtPointer)NULL);
	XtAddCallback(command_window,XmNvalueChangedCallback,(void (*)(Widget,void *, void *))CommandWindowInputCB,(XtPointer)NULL);
	XtAddCallback(command_window,XmNactivateCallback,(void (*)(Widget,void *, void *))ActiveCB,(XtPointer)NULL);
	printf("piont3.10\n");
	return(main_window);
}

/********************* SelectFontCB ***********************/
Widget SelectedFontSample(Widget widget)
{
	Widget message_box;
	Widget button;
	Arg args[MAX_ARGS];
	register int n;
	int i;
	XtPointer * buffer;
	char *name = NULL;
	XFontStruct * font = NULL;
	XmFontList fontlist = NULL;
	static char message[BUFSIZ];
	XmString name_string = NULL;
	XmString message_string = NULL;
	XmString button_string = NULL;

	/******************* get font name *********************/
	printf("piont SelectedFontSample\n");
	XtVaGetValues(widget,XmNlabelString,&name_string,NULL);
	XmStringGetLtoR(name_string,charset,&name);
/*
	for(i=0;i<10;i++)
	{
	if(name) font = XLoadQueryFont(XtDisplay(XtParent(widget)),name);
		if(font == NULL) sprintf(message,"Unable to load font:%s.",name);
	else
	{
		fontlist = XmFontListCreate(font,charset);
		sprintf(message,"\n This is font %s.\n The quick brown fox jumps over the lazy dog.",name);
	}
	printf("font=%x, fontlist=%x\n",font,fontlist);
	XmFontListFree(fontlist);
	if(font) XFreeFont(XtDisplay(XtParent(widget)),font);
	}
*/
	if(name) font = XLoadQueryFont(XtDisplay(XtParent(widget)),name);
		if(font == NULL) sprintf(message,"Unable to load font:%s.",name);
	else
	{
		fontlist = XmFontListCreate(font,charset);
		sprintf(message,"\n This is font %s.\n The quick brown fox jumps over the lazy dog.",name);
	}
	printf("font=%x, fontlist=%x\n",font,fontlist);
	buffer = (XtPointer*)XtMalloc(sizeof(XtPointer)*2);
	printf("buffer=%x, size=%d\n",buffer,sizeof(XtPointer)*2);
	buffer[0] = (XtPointer)fontlist;
	buffer[1] = (XtPointer)font;

	printf("piont SelectedFontSample, name=%x, name_string=%x, font=%x\n",name,name_string,font);
	message_string = XmStringCreateLtoR(message,charset);
	for(i=0;i<0;i++)
	{
	button_string = XmStringCreateLtoR("Close",charset);
	printf("button_string=%x\n",button_string);
	XmStringFree(button_string);
	}
	button_string = XmStringCreateLtoR("Close",charset);

	n = 0;
	if (fontlist)
	{
		XtSetArg(args[n],XmNlabelFontList,fontlist);n++;
	}
	XtSetArg(args[n],XmNdialogTitle,name_string);n++;
	XtSetArg(args[n],XmNokLabelString,button_string);n++;
	XtSetArg(args[n],XmNmessageString,message_string);n++;
	for(i=0;i<0;i++)
	{
	message_box = XmCreateMessageDialog(XtParent(XtParent(widget)),"fontbox",args,n);
	XtDestroyWidget(message_box);
	}
	message_box = XmCreateMessageDialog(XtParent(XtParent(widget)),"fontbox",args,n);
	XtAddCallback(message_box,XmNokCallback,(void (*)(Widget,void *, void *))CloseCB,(XtPointer)buffer);
	XtAddCallback(message_box,XmNhelpCallback,(void (*)(Widget,void *, void *))HelpCB,(XtPointer)2);

	button = XmMessageBoxGetChild(message_box,XmDIALOG_CANCEL_BUTTON);
	//if(name_string) XmStringFree(name_string);
	//XtVaGetValues(button,XmNlabelString,&name_string,NULL);
	//if(name_string) XmStringFree(name_string);
	XtUnmanageChild(button);
	//XtDestroyWidget(button);
	
	//if(fontlist) XmFontListFree(fontlist);
	if(name) XtFree((char*)name);
	//if(name_string) XtFree((char*)name_string);
	//if(message_string) XtFree((char*)message_string);
	//if(button_string) XtFree((char*)button_string);
	if(button_string) XmStringFree(button_string);
	if(message_string) XmStringFree(message_string);
	printf("button_string=%x,  message_string=%x, name_string=%x\n",button_string,message_string,name_string);
	return (message_box);
}

Widget MyHelpDialog(Widget parent,int flag)
{
	static int first_time = 1;
	static Widget message_box;
	Arg args[MAX_ARGS];
	register int n;

	static char message[BUFSIZ];
	XmString title_string = NULL;
	static XmString message_string1 = NULL;
	static XmString message_string2 = NULL;
	XmString button_string = NULL;

	if (first_time)
	{
		Widget wtmp;
		n = 0;
		message_box = XmCreateMessageDialog(XtParent(XtParent(parent)),"helpbox",args,n);
		button_string = XmStringCreateLtoR("Close",charset);
		title_string = XmStringCreateLtoR("myfonts help",charset);
		message_string1 = XmStringCreateLtoR("\nPush one button to get the sample "
						"\ntext display in the font.\n(Some font may not be opened.)",charset);
		message_string2 = XmStringCreateLtoR("\n The help text for this specific font.\n",charset);

		XtVaSetValues(message_box,XmNdialogTitle,title_string,XmNokLabelString,button_string,NULL);
		wtmp = XmMessageBoxGetChild(message_box,XmDIALOG_CANCEL_BUTTON);
		XtUnmanageChild(wtmp);
		wtmp = XmMessageBoxGetChild(message_box,XmDIALOG_HELP_BUTTON);
		XtUnmanageChild(wtmp);
		first_time = 0;
	}

	if (flag == 1)
		XtVaSetValues(message_box,XmNmessageString,message_string1,NULL);
	else
		XtVaSetValues(message_box,XmNmessageString,message_string2,NULL);

	return (message_box);
}

void FontSelectedCB(Widget w,caddr_t client_data,caddr_t call_data)
{
	Widget message_box;
	//putchar(007);fflush(stdout);
	message_box = SelectedFontSample(w);
	XtManageChild(message_box);
}

void CloseCB(Widget w,caddr_t client_data,caddr_t call_data)
{
    XmString message_string = NULL;
    XmString button_string = NULL;
    XmString name_string = NULL;
	Widget button;
	XtPointer * buffer;
		
	Widget message_box = XtParent(w);
	buffer = (XtPointer*)client_data;
	printf("buffer=%x, call_data=%x\n",buffer,call_data);
	//putchar(007);fflush(stdout);
    //XtVaGetValues(w,XmNokLabelString,&button_string,XmNmessageString,&message_string,XmNdialogTitle,&name_string,NULL);
	//printf("freeing button_string=%x,  message_string=%x\n",button_string,message_string);
	XtUnmanageChild(message_box);
	XtDestroyWidget(message_box);

	if(buffer[0]) XmFontListFree((XmFontList)buffer[0]);
	//printf("font=%x, fontlist=%x\n",buffer[1],buffer[0]);
	if(buffer[1]) XFreeFont(XtDisplay(XtParent(w)),(XFontStruct *)buffer[1]);
	XtFree((char*)buffer);
/*
	if(button_string) XmStringFree(button_string);
	if(button_string) XmStringFree(button_string);
	if(message_string) XmStringFree(message_string);
	if(message_string) XmStringFree(message_string);
*/
}

void HelpCB(Widget w,int tag,caddr_t call_data)
{
	Widget message_box;
	int i = tag;
	printf("tag=%d\n",tag);
	//putchar(007);fflush(stdout);
	message_box = MyHelpDialog(w,i);
	XtManageChild(message_box);
}

void QuitCB(Widget w,caddr_t client_data,caddr_t call_data)
{
	//putchar(007);fflush(stdout);
	exit(0);
}

void MenuCommandCB(Widget w,caddr_t client_data,caddr_t call_data)
{
	Arg args[MAX_ARGS];
	int command;
	int n;
	int *position;
	int buffer[4];

	command = (int)client_data;
	switch(command)
	{
		case MENU_DISPLAY_POSITION:
			n = 0;
			XtSetArg(args[n],XmNselectedPositions,&position);n++;
			XtGetValues(slist,args,n);
			if(position) printf("MenuCommandCB: position[0] = %d\n",*position);
			else printf("MenuCommandCB: position = NULL\n");
			break;
		case MENU_NEXT_POSITION:
			n = 0;
			XtSetArg(args[n],XmNselectedPositions,&position);n++;
			XtGetValues(slist,args,n);
			if(position)
			{
				buffer[0] = *position + 1;
				XmListDeselectAllItems(slist);
				n = 0;
				XtSetArg(args[n],XmNselectedPositions,buffer);n++;
				XtSetArg(args[n],XmNselectedPositionCount,1);n++;
				XtSetValues(slist,args,n);
			}
			else
			{
				buffer[0] = 10;
				n = 0;
				XtSetArg(args[n],XmNselectedPositions,buffer);n++;
				XtSetArg(args[n],XmNselectedPositionCount,1);n++;
				XtSetValues(slist,args,n);
			}
			break;
		default:
			printf("undefined command\n");
	}
}

void ListSelectCB(Widget w,caddr_t client_data,XmListCallbackStruct * callback_data)
{
	Arg args[MAX_ARGS];
	int n;
	int *position;

	n = 0;
	XtSetArg(args[n],XmNselectedPositions,&position);n++;
	XtGetValues(slist,args,n);
	//printf("ListSelectCB: position = %d\n",*position);
	//n = 0;
	//XtSetArg(args[n],XmNtopItemPosition,(*position-1)?(*position-1):1);n++;
	//XtSetValues(slist,args,n);
	call_back_signal = 1;
	XmTextSetString(command_window,item_list[*position-1]->name);
}

void ActiveCB(Widget w,caddr_t client_data,caddr_t call_data)
{
	Arg args[MAX_ARGS];
	int n;
	int *position;

	n = 0;
	XtSetArg(args[n],XmNselectedPositions,&position);n++;
	XtGetValues(slist,args,n);
	if(!position) return;
	//printf("active = %d, name = %s\n",position[0]-1,item_list[position[0]-1]->name);
	active_man_page(item_list[position[0]-1]);
}

void CommandWindowInputCB(Widget w,caddr_t client_data,caddr_t call_data)
{
	Arg args[MAX_ARGS];
	int n;
	int count;
	char * name;
	int position;
	int *positions;

	if (call_back_signal) 
	{
		call_back_signal = 0;
		return;
	}

	name = XmTextGetString(command_window);

	position = ItemMatch(name);
	position ++;
	//printf("match position = %d\n",position);
	XtFree(name);

	XmListDeselectAllItems(slist);
	n = 0;
	XtSetArg(args[n],XmNselectedPositionCount,1);n++;
	XtSetArg(args[n],XmNselectedPositions,&position);n++;
	XtSetArg(args[n],XmNtopItemPosition,(position-1)?(position-1):1);n++;
	XtSetValues(slist,args,n);
}

/************************* ManPath ************************/
ManPath::ManPath(char* path_name)
{
	int i;
	int len;
	next = NULL;
	alias = NULL;
	len = strlen(path_name);
	man_path = (char*)malloc(len+1);
	strncpy(man_path,path_name,len);
	man_path[len] = '\0';
	for (i=0;i<11;i++) sub_dir[i] = new SubDir(this);
	LoadManPath(path_name);
}

ManPath::~ManPath()
{
	int i;
	for (i = 0;i<11;i++) delete(sub_dir[i]);
	free(man_path);
}

ManPath::GetSize(char c)
{
	int count;
	int i;
	int type = subdir_translate_c_to_n(c)+1;
	if (type <= 11 && type >= 1) return sub_dir[type-1]->GetSize();
	for (i = count = 0;i<11;i++) count += sub_dir[i]->GetSize();
	return count;
}

ManPath::GetItems(char c, ManItem * buffer[])
{
	int count;
	int i;
	int type = subdir_translate_c_to_n(c)+1;
	if (type <= 11 && type >= 1) return sub_dir[type-1]->GetItems(buffer);
	for (i = count = 0;i<11;i++) count += sub_dir[i]->GetItems(buffer+count);
	return count;
}

struct stat state;

ManPath::LoadManPath(char * path_name)
{
	DIR *dirp;
	#if defined(SYS_DIR)||defined(NDIR)
		struct direct *item;
	#else
		struct dirent *item;
	#endif

	int len;
	int val;
	char name[180];
	
	man_path = (char*)realloc(man_path,strlen(path_name)+1);
	strcpy(man_path,path_name);

	dirp = opendir(path_name);
	if (!dirp)
	{
		fprintf(stderr,"Can not open man path %s\n",path_name);
	}
	for (item = readdir(dirp);item != NULL;item = readdir(dirp))
	{
		if(item->d_name[0] == '.' && (item->d_name[1] == 0 ||(item->d_name[1] == '.'&&item->d_name[2]==0)))
			continue;
		attach(name,path_name,item->d_name);
		val = stat (name, &state);
		if (val < 0) fprintf(stderr,"error number %d, in get state %s",errno,name);
		else if (S_ISDIR(state.st_mode)) LoadManPath(name);
		else
		{
			len = (strlen(item -> d_name));
			if(item -> d_name[len-2] == '.')
			{
				val = subdir_translate_c_to_n(item->d_name[len-1]);
				strncpy(name,item->d_name,len-2);
				name[len-2] = '(';
				name[len-1] = item->d_name[len-1];
				name[len] = ')';
				name[len+1] = '\0';
				sub_dir[val]->AddItem(name);
			}
			else if(item -> d_name[len-3] == '.')
			{
				val = subdir_translate_c_to_n(item->d_name[len-2]);
				strncpy(name,item->d_name,len-3);
				name[len-3] = '(';
				name[len-2] = item->d_name[len-2];
				name[len-1] = item->d_name[len-1];
				name[len] = ')';
				name[len+1] = '\0';
				sub_dir[val]->AddItem(name);
			}
		}
	}
}

/************************* SubDir ************************/
SubDir::SubDir(ManPath* path)
{
	man_path = path;
	buffer_length = 64;
	count = 0;
	item_list = (ManItem**)malloc(buffer_length*sizeof(ManItem*));
}

SubDir::~SubDir()
{
	int i;
	for (i=0;i<count;i++) delete(item_list[i]);
	free(item_list);
}

void SubDir::AddItem(char * file_name)
{
	if(count >= buffer_length) item_list = (ManItem**)realloc(item_list,(buffer_length*=2)*sizeof(*item_list));
	item_list[count++] = new ManItem(this,file_name);
}

inline SubDir::GetSize()
{
	return count;
}

SubDir::GetItems(ManItem *buffer[])
{
	memcpy(buffer,item_list,count*sizeof(ManItem*));
	return count;
}

/************************* ManItem ************************/
inline ManItem::ManItem(SubDir * sub,char *name)
{
	int len;
	len = strlen(name);
	this->name = (char*)malloc(len+1);
	strncpy(this->name,name,len);
	this->name[len] = '\0';
}

inline ManItem::~ManItem()
{
	free(name);
}
	
/************************* init global data ************************/
void InitData()
{
	int i;
	man_paths = NULL;
	item_list = NULL;
	item_list_length = 0;
	item_list_count = 0;

	man_paths = new ManPath("/usr/X11/man/");
	printf("GetSize = %d\n",man_paths->GetSize('a'));

	item_list_length = item_list_count = man_paths->GetSize('a');
	printf("GetSize = %d\n",item_list_count);
	item_list = (ManItem**)malloc(item_list_count*sizeof(ManItem*));
	man_paths->GetItems('a',item_list);
	qsort(item_list,item_list_count,sizeof(ManItem*),&ManItemComp);
	//for(i=0;i<item_list_count;i++) printf("%s\n",item_list[i]->name);
}

/* Put DIRNAME/NAME into DEST, handling `.' and `/' properly. */

static void attach (char *dest, const char *dirname, const char *name)
{
	const char *dirnamep = dirname;

    /* Copy dirname if it is not ".". */
	if (dirname[0] != '.' || dirname[1] != 0)
	{
		while (*dirnamep) *dest++ = *dirnamep++;
		/* Add '/' if `dirname' doesn't already end with it. */
		if (dirnamep > dirname && dirnamep[-1] != '/') *dest++ = '/';
	}
	while (*name) *dest++ = *name++;
	*dest = 0;
}

int subdir_translate_c_to_n(char c)
{
	if(c<='8' && c>='1') return (c-'1');
	else if(c == 'n') return 8;
	else if(c == 'l') return 9;
	else if(c == 'a') return -1;
	else return 10;
}

int ManItemComp(ManItem ** a,ManItem ** b)
{
	return (strcmp((*a)->name,(*b)->name));
}

int ItemMatch(char * name)
{
	int i;
	for (i=0;i<item_list_count && strcmp(name,item_list[i]->name)>0 ;i++);
	return (i >= item_list_count)? i-1:i;
}

static void active_man_page(ManItem * item)
{
	int i;
	int len,len2;
	char buffer[180];
	len = strlen(item->name);
	if (item->name[len-3] == '(') len -= 3;
	else len -= 4;

	strcpy(buffer,"nxterm -T '");
	strcat(buffer,item->name);
	strcat(buffer,"' -n KMan -e man ");
	len2 = strlen(buffer);
	strncat(buffer,item->name,len); buffer[len+len2] = '\0';
	if(!fork())
	{
		//printf(buffer);
		system(buffer);
		exit(0);
	}
	return;
}
		
