/*  diawin.c

    Copyright (C) 1994	Lambert Klasen & Detlef Steuer
			klasen@asterix.uni-muenster.de
			steuer@amadeus.statistik.uni-dortmund.de

    This file is free source code; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
    COPYING for more details.


    The idea of this textwidget and the functions CreateDialogWindow(),  
    AppendDialogText() and TextGetLastPos() are lifted from xxgdb and
    adopted for xgammon.

 *  xdbx - X Window System interface to the dbx debugger
 *
 *  Copyright 1989 The University of Texas at Austin
 *  Copyright 1990 Microelectronics and Computer Technology Corporation
 *  Copyright 1990 Thomson Consumer Electronics, Inc.

 */




#include <stdio.h>
#include <X11/Xos.h>
#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include <X11/Xaw/Cardinals.h>
#include <X11/Shell.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/AsciiText.h>
#include <X11/Xaw/TextP.h>
#include <X11/Xaw/TextSrc.h>

#include "xgammon.h"
#include "gammon.h"

extern Widget form;
extern FILE*  protokol_file;

void  CreateDialogWindow ();
void  CreateRolloutText  ();
void  AppendDialogText   ();
void  Dispatch           ();
static XawTextPosition  TextGetLastPos ();
static XawTextPosition  InputPos, lt;   /* starting position of input text */

void  print_dialog_text  ();


#define LINESIZ         512             /* input line length */
#define DIALOGSIZE      30000           /* max size of dialogue window buffer */

char add_text[LINESIZ];			/* global text buffer for strings from somewhere to add */
char DialogText[DIALOGSIZE];	        /* text buffer for widget */
char TournamentText[DIALOGSIZE];        /* text buffer for widget */

Widget text_display, tournament_display;



void CreateDialogWindow (X11SET *X11Set)
{
	Arg 	args[7];
	Cardinal 	n;

	n = 0;
	XtSetArg (args[n], XtNuseStringInPlace,    True);		n++;
	XtSetArg (args[n], XtNstring,   (XtArgVal) DialogText);		n++;
	XtSetArg (args[n], XtNlength,   (XtArgVal) DIALOGSIZE);		n++;
	XtSetArg (args[n], XtNeditType, (XtArgVal) XawtextAppend);	n++;
	XtSetArg (args[n], XtNwrap,                XawtextWrapWord);	n++;
	XtSetArg (args[n], XtNfromVert,            X11Set->tournament_display);	n++;
	X11Set->text_display = XtCreateManagedWidget ("text_display", asciiTextWidgetClass, X11Set->form, args, n);
}

void CreateTournamentWindow (X11SET *X11Set)
{
	Arg 	 args[6];
	Cardinal n;

	static XtActionsRec dialog_actions[] = {
		{ "Dispatch",   (XtActionProc) Dispatch},
		{ NULL, 	NULL}
	};

	static String translations = "#override\n\
		<Key>Return:    newline() Dispatch()\n\
	";

	n = 0;
	XtSetArg (args[n], XtNuseStringInPlace,    True);		n++;
	XtSetArg (args[n], XtNstring,   (XtArgVal) TournamentText);	n++;
	XtSetArg (args[n], XtNlength,   (XtArgVal) DIALOGSIZE);		n++;
	XtSetArg (args[n], XtNeditType, (XtArgVal) XawtextAppend);	n++;
	XtSetArg (args[n], XtNwrap,		   XawtextWrapWord);	n++;
	XtSetArg (args[n], XtNfromVert,            X11Set->quit);	n++;
	X11Set->tournament_display = XtCreateManagedWidget ("tournament_display", asciiTextWidgetClass, X11Set->form, args, n );
	XtOverrideTranslations (X11Set->tournament_display, XtParseTranslationTable (translations));
	XtAppAddActions (app_con, dialog_actions, XtNumber(dialog_actions));
}

void CreateRolloutText (Widget parent)
{
	Arg 	args[6];
	Cardinal 	n;

	n = 0;
	XtSetArg (args[n], XtNuseStringInPlace,    True);		n++;
	XtSetArg (args[n], XtNstring,   (XtArgVal) DialogText);		n++;
	XtSetArg (args[n], XtNlength,   (XtArgVal) DIALOGSIZE);		n++;
	XtSetArg (args[n], XtNeditType, (XtArgVal) XawtextAppend);	n++;
	XtSetArg (args[n], XtNwrap,                XawtextWrapWord);	n++;

	Player[0].X11Set.text_display = XtCreateManagedWidget ("text_display", asciiTextWidgetClass, parent, args, n);
}

void AppendDialogText (int where, char *s)
{
	XawTextPosition i, lastPos;
	XawTextBlock    textblock, nullblock;

	TextWidget ctx;
	Widget w;

	if      (where == UPPER) {
		ctx = (TextWidget) Player[0].X11Set.tournament_display;
		w   =              Player[0].X11Set.tournament_display;
	} else if (where == LOWER) {
		ctx = (TextWidget) Player[0].X11Set.text_display;
		w   =              Player[0].X11Set.text_display;
	} else {
		fprintf (stderr, "unkown widget for AppendDialogText ()\n");
		return;
	}

	if (!s || !strcmp(s, "")) return;

	textblock.firstPos = 0;
	textblock.length   = strlen(s);
	textblock.ptr      = s;

	lastPos = TextGetLastPos (ctx);
	if (textblock.length > DIALOGSIZE) {
		fprintf (stderr, "xgammon error: cannot display string in dialogue window\n\
			string has %d bytes; dialogue window size limit is %d bytes\n",
			textblock.length, DIALOGSIZE);
		return;
	}
	if (lastPos + textblock.length > DIALOGSIZE) {
		nullblock.firstPos = 0;
		nullblock.length   = 0;
		nullblock.ptr      = "";

		i = textblock.length - (DIALOGSIZE - lastPos);
		if (i < 0.9*DIALOGSIZE) i += 0.1*DIALOGSIZE;
		while (DialogText[i] != '\n') i++;
		XawTextReplace (w, 0, i+1, &nullblock);
		lastPos = TextGetLastPos (ctx);
	}
	XawTextReplace (w, lastPos, lastPos, &textblock);
	InputPos = TextGetLastPos (ctx);
	if (where == UPPER) lt = InputPos;
	XawTextSetInsertionPoint (w, InputPos);
	if (gammon_resource.protokol) fprintf(protokol_file, "%s", s);

	if (gammon_resource.other_display) {

	if      (where == UPPER) {
		ctx = (TextWidget) Player[1].X11Set.tournament_display;
		w   =              Player[1].X11Set.tournament_display;
	} else if (where == LOWER) {
		ctx = (TextWidget) Player[1].X11Set.text_display;
		w   =              Player[1].X11Set.text_display;
	} else {
		fprintf (stderr, "unkown widget for AppendDialogText ()\n");
		return;
	}

	if (!s || !strcmp(s, "")) return;

	textblock.firstPos = 0;
	textblock.length   = strlen(s);
	textblock.ptr      = s;

	lastPos = TextGetLastPos (ctx);
	if (textblock.length > DIALOGSIZE) {
		fprintf (stderr, "xgammon error: cannot display string in dialogue window\n\
			string has %d bytes; dialogue window size limit is %d bytes\n",
			textblock.length, DIALOGSIZE);
		return;
	}
	if (lastPos + textblock.length > DIALOGSIZE) {
		nullblock.firstPos = 0;
		nullblock.length   = 0;
		nullblock.ptr      = "";

		i = textblock.length - (DIALOGSIZE - lastPos);
		if (i < 0.9*DIALOGSIZE) i += 0.1*DIALOGSIZE;
		while (DialogText[i] != '\n') i++;
		XawTextReplace (w, 0, i+1, &nullblock);
		lastPos = TextGetLastPos (ctx);
	}
	XawTextReplace (w, lastPos, lastPos, &textblock);
	InputPos = TextGetLastPos (ctx);
	if (where == UPPER) lt = InputPos;
	XawTextSetInsertionPoint (w, InputPos);

	}
}

XawTextPosition TextGetLastPos (Widget w)
{
	TextWidget ctx = (TextWidget) w;
	return (ctx->text.lastPos);
}

void Dispatch (Widget w, XEvent *event, String *params, Cardinal *num_params)
{
	char s[LINESIZ];

	strcpy (s, TournamentText + lt);
	lt       = TextGetLastPos (w);
	InputPos = TextGetLastPos (w);
}

void print_dialog_text (FILE *f)
{
	fprintf (f, "%s\n", DialogText);
}
