/*
 *  XLeScrabble - X version of the popular board game, in french and
 *  for 1 to 4 players.
 *
 * This software comes with NO warranty whatsoever. I therefore take no
 * responsibility for any damages, losses or problems caused through use
 * or misuse of this program.
 *
 * I hereby grant permission for this program to be freely copied and
 * distributed by any means, provided no charge is made for it.
 *
 * Matthew Chapman, csuoq@csv.warwick.ac.uk
 *    Oct 1994.
 */

/* setup.c - gets setup details from user */

#include "scrab.h"
#include "globals.h"

#include "slate_green.xpm"

#define TIME_INTS 6
#define HILIGHT "white"
#define NORMAL "beige"

void Start();
void Quit();
void Tog_vis();
void Cycle();

XtAppContext app_context;
Widget name[MAXPLAYERS],setup,start,quit,sload,tog[MAXPLAYERS];
Widget disp[MAXPLAYERS],topLevel,nametitle,disptitle,typetitle,num_ply;
Widget wtype[MAXPLAYERS],title,timetitle,timet[TIME_INTS];
Widget curr_entry;
Pixmap bgxpm;
XtTranslations storedt;

char cycle_text[NUM_TYPES][14] = { "Human","Good (1)","Better (2)",
"Great (3)","Smashing (4)","Super (5)","Excellent (6)","Ace (7)", };

static String curr_trans = "#override\n\
	<Key>Tab: Move(t)\n\
	<Key>Return: Move(r)\n\
	Ctrl<Key>R: no-op()\n\
	Ctrl<Key>S:	no-op()\n\
	Meta<Key>I:	no-op()";
static String other_trans = "#override\n\
		<Key>: KeyRedirect()";

void Quit()
{
    XtDestroyApplicationContext(app_context);
    exit(0);
}

/* application data structure */
struct sAppData {
        int version;
} sapp_data;

/* option types and default values */
static XtResource resources[] =
{
	{"version","Version",XtRInt,sizeof(int),XtOffsetOf(struct sAppData,version),
		XtRImmediate,(XtPointer) 0},
};

int Tog2Int()
{
	/* get selected toggle, and convert to int */
	char sw[5];

	strcpy(sw,XawToggleGetCurrent(tog[0]));
	return (sw[3] - '0'+1);
}

void MakeNotCurrent()
{
	XtVaSetValues(curr_entry,XtNtranslations,
		XtParseTranslationTable(other_trans),SETBG(NORMAL),NULL);
	XawTextDisplayCaret(curr_entry,False);
}

void MakeCurrent()
{
	XtVaSetValues(curr_entry,XtNtranslations,storedt,SETBG(HILIGHT),NULL);
	XawTextDisplayCaret(curr_entry,True);
}

void KeyRedirect(Widget w, XEvent *event,String *params,Cardinal num_params)
{
 	if (w!=curr_entry)
 	{
	    event->xany.window = XtWindow(curr_entry);
	    XtDispatchEvent(event);
	}
}

void Move(Widget w, XEvent *event,String *params,Cardinal num_params)
{
	int wnum=0,i,isname=True;
	Boolean istab = (params[0][0] == 't');	

	for (i=0; i<MAXPLAYERS; i++)
		if (w==name[i])
			wnum=i;
	for (i=0; i<MAXPLAYERS; i++)
		if (w==disp[i])
		{
			wnum=i;
			isname=False;
		}
	MakeNotCurrent();
	if (istab)
		if (isname)
			curr_entry = disp[wnum];
		else
			curr_entry = name[(wnum+1) % Tog2Int()];
	else
		if (isname)
			if ((wnum+1)==Tog2Int())
				curr_entry = disp[0];
			else
				curr_entry = name[wnum+1];
		else
			if ((wnum+1)==Tog2Int())
				curr_entry = name[0];
			else
				curr_entry = disp[wnum+1];		
	MakeCurrent();
}

void HandleMouse(Widget w,XtPointer unused,register XEvent *event,Boolean *cont)
{
	if (w!=curr_entry)
	{
		MakeNotCurrent();
		curr_entry=w;
		MakeCurrent();
	}
}

void main(int argc,char **argv)
{
	int ply,tn; 
	char wname[12];
	static XtActionsRec actions[] = {
		{"KeyRedirect", KeyRedirect},
		{"Move", Move},
	};
	/* to set radio toggles to "exactly one of many" mode */
	static String togtrans = "#override\n\
		<EnterWindow>:	highlight(Always)\n\
		<LeaveWindow>:	unhighlight()\n\
		<Btn1Down>,<Btn1Up>:	set() notify()";

	topLevel = XtVaAppInitialize(&app_context,"XLeScrabble",NULL,0,
		&argc,argv,NULL,NULL);

	XtVaGetApplicationResources(topLevel,&sapp_data,resources,
		XtNumber(resources),NULL);

	if (sapp_data.version != VERSION)
	{
		fprintf(stderr,"Couldn't find resource file XLeScrabble.\n");
		exit(1);
	}

	setup = XtVaCreateManagedWidget("setup", formWidgetClass,topLevel, 
			XtNtranslations,XtParseTranslationTable(other_trans),
			NULL);

	title = XtVaCreateManagedWidget("title", labelWidgetClass, setup,
			NULL);
	num_ply = XtVaCreateManagedWidget("num_ply", labelWidgetClass, setup,
			NULL);

	for (tn=0; tn<MAXPLAYERS; tn++)
	{
		sprintf(wname,"tog%d",tn);
		tog[tn]= XtVaCreateManagedWidget(wname, toggleWidgetClass, setup,
			XtNtranslations,XtParseTranslationTable(togtrans),NULL);
	}

	timetitle = XtVaCreateManagedWidget("timetitle", labelWidgetClass, setup,
			NULL);

	for (tn=0; tn<TIME_INTS; tn++)
	{
		sprintf(wname,"timet%d",tn);
		timet[tn]= XtVaCreateManagedWidget(wname, toggleWidgetClass, setup,
			XtNtranslations,XtParseTranslationTable(togtrans),NULL);
	}

	nametitle = XtVaCreateManagedWidget("nametitle", labelWidgetClass, setup,
			NULL);
	disptitle = XtVaCreateManagedWidget("disptitle", labelWidgetClass, setup,
			NULL);
	typetitle = XtVaCreateManagedWidget("typetitle", labelWidgetClass, setup,
			NULL);

	for (ply=0; ply<MAXPLAYERS; ply++)
	{
		sprintf(wname,"name%d",ply);
		name[ply] = XtVaCreateManagedWidget(wname, asciiTextWidgetClass, setup,
			XtNwidth,100,XtNtranslations,
			XtParseTranslationTable((ply==0) ? curr_trans : other_trans),NULL);
		if (ply==0)
			XtVaSetValues(name[ply],SETBG(HILIGHT),NULL);
		else
			XawTextDisplayCaret(name[ply],False);
		sprintf(wname,"disp%d",ply);
		disp[ply] = XtVaCreateManagedWidget(wname, asciiTextWidgetClass, setup,
			XtNtranslations,XtParseTranslationTable(other_trans),
			XtNwidth,100,XtNfromHoriz,name[ply],XtNstring,":0.0",NULL);
		XawTextDisplayCaret(disp[ply],False);
		sprintf(wname,"type%d",ply);
		wtype[ply] = XtVaCreateManagedWidget(wname, commandWidgetClass, setup,
			XtNfromHoriz,disp[ply],XtNwidth,100,XtNlabel,"Human",NULL);
		XtAddEventHandler(name[ply],ButtonPressMask,False,HandleMouse,NULL);
		XtAddEventHandler(disp[ply],ButtonPressMask,False,HandleMouse,NULL);
	}
	curr_entry=name[0];

	start = XtVaCreateManagedWidget("start", commandWidgetClass, setup, NULL);
	sload = XtVaCreateManagedWidget("load", commandWidgetClass, setup, NULL);
	quit = XtVaCreateManagedWidget("quit", commandWidgetClass, setup, NULL);
	XtAddCallback(start,XtNcallback,Start,topLevel);
	XtAddCallback(sload,XtNcallback,Start,topLevel);
	XtAddCallback(quit,XtNcallback,Quit,topLevel);
	for (ply=0; ply<MAXPLAYERS; ply++)
	{
		XtAddCallback(tog[ply],XtNcallback,Tog_vis,setup);
		XtAddCallback(wtype[ply],XtNcallback,Cycle,setup);
	}

	load_data_pixmap(slate_green_xpm,&bgxpm,topLevel);
	bg_pixmap(setup);
	bg_pixmap(title);
	bg_pixmap(nametitle);
	bg_pixmap(disptitle);
	bg_pixmap(typetitle);
	bg_pixmap(num_ply);
	bg_pixmap(timetitle);

	XtAppAddActions(app_context,actions,XtNumber(actions));
	XtRealizeWidget(topLevel);

	XtVaGetValues(name[0],XtNtranslations,&storedt,NULL);

	XtAppMainLoop(app_context);
}

void Cycle(Widget w, XtPointer client_data, XtPointer csetup_data)
{
	String ctext;
	int i,curr=0;
	
	XtVaGetValues(w,XtNlabel,&ctext,NULL);
	for (i=0; i<NUM_TYPES; i++)
	    if (!strcmp(cycle_text[i],ctext))
		curr=i+1;

	XtVaSetValues(w,XtNlabel,cycle_text[(curr<NUM_TYPES) ? curr : 0],NULL);
}

void Tog_vis(Widget w, XtPointer client_data, XtPointer csetup_data)
{
	int i,num;
	Boolean st;

	/* if toggle is now selected */
	XtVaGetValues(w,XtNstate,&st,NULL);
	if (st==True)
	{
		num = Tog2Int();
		for (i=0; i<num; i++)
		{
			XtVaSetValues(name[i],XtNmappedWhenManaged,True,NULL);
			XtVaSetValues(disp[i],XtNmappedWhenManaged,True,NULL);
			XtVaSetValues(wtype[i],XtNmappedWhenManaged,True,NULL);
		}
		for (i=num; i<MAXPLAYERS; i++)
		{
			XtVaSetValues(name[i],XtNmappedWhenManaged,False,NULL);
			XtVaSetValues(disp[i],XtNmappedWhenManaged,False,NULL);
			XtVaSetValues(wtype[i],XtNmappedWhenManaged,False,NULL);

			/* check if selected entry box has been unmanaged */
			if ((name[i]==curr_entry) || (disp[i]==curr_entry))
			{
				/* make first entry the current one */
		MakeNotCurrent();
				curr_entry = name[0];
				MakeCurrent();
			}
		}
	}
}

void Start(Widget w, XtPointer client_data, XtPointer csetup_data)
{
	char sw[12],com[512];
	String ply_name,disp_name,type_name;
	int i,j,num_players,time_val,time_lim,curr=0;

	strcpy(com,"xlescrab");
	num_players=Tog2Int();
	sprintf(&com[strlen(com)]," -players %d",num_players);

	strcpy(sw,XawToggleGetCurrent(timet[0]));
	time_val=sw[5] - '0';
	switch (time_val)
	{
		case 1: case 2: case 3: time_lim=time_val; break;
		case 4: time_lim=5; break;
		case 5: time_lim=10; break;
		default: time_lim=0; break;
	}
	sprintf(&com[strlen(com)]," -time %d",time_lim);

	/* get names and displays */
	for (i=0; i<num_players; i++)
	{
		XtVaGetValues(name[i],XtNstring,&ply_name,NULL);		
		XtVaGetValues(disp[i],XtNstring,&disp_name,NULL);		
		XtVaGetValues(wtype[i],XtNlabel,&type_name,NULL);		
		if (strlen(ply_name)>0)
			sprintf(&com[strlen(com)]," -n%d \"%.13s\"",i+1,ply_name);
		if (strlen(disp_name)>0)
			sprintf(&com[strlen(com)]," -d%d %s",i+1,disp_name);
		for (j=0; j<NUM_TYPES; j++)
			if (!strcmp(cycle_text[j],type_name))
				curr=j;
		sprintf(&com[strlen(com)]," -t%d %d",i+1,curr);		
	}
	if (w==sload)
		strcat(com," -load");
	strcat(com," &");
	printf("%s\n",com);
	system(com);
	XtDestroyWidget(topLevel);
	exit(0);
}

void load_pixmap(char *fname, Pixmap *xpm,Widget top)
{
	int status;
	XpmAttributes attr;
	Pixmap mask;

	attr.valuemask = XpmReturnPixels | XpmCloseness;
	status = XpmReadFileToPixmap(XtDisplay(top),
             DefaultRootWindow(XtDisplay(top)),fname,xpm,&mask,&attr);
	if (status != XpmSuccess)
	{
			fprintf(stderr,"Pixmap error: %s\n",XpmGetErrorString(status));
			exit(0);
 	}
}

void bg_pixmap(Widget w)
{
	XtVaSetValues(w,XtNbackgroundPixmap, (XtArgVal)bgxpm, NULL);
}
