/*  popup.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.
 */




#include <stdio.h>

#include <X11/Intrinsic.h>
#include <X11/Composite.h>
#include <X11/Shell.h>
#include <X11/StringDefs.h>

#include <X11/Xaw/Form.h>
#include <X11/Xaw/Command.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/SimpleMenu.h>
#include <X11/Xaw/SmeBSB.h>
#include <X11/Xaw/SmeLine.h>
#include <X11/Xaw/MenuButton.h>

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

extern int turn, end_of_game;
extern Widget toplevel;
extern XtAppContext app_con;

char *menu1_names[] = {
	"save position <s>",
	"load position <l>", 
	"save game     <S>", 
	"load game     <L>",
	"save as ..", 
	"load ..",
	NULL,
};

char *menu2_names[] = {
	"restart     <r>",
	"undo move   <u>", 
	"human vs. compi", 
	"compi vs. compi", 
	"human vs. human",
	"computer finish",
	"rollout",
	"edit position",
	"mail dump",
	NULL,
};

Widget button_shell, form;              /* popup shell with the buttons ... */
Widget t_label, p_label;                /* game and tournment labels */
Widget pop_down, quit;               /* command buttons */
Widget menu, file_button, setgame, entry;       /* the menus! */

Widget popup_shell;

/* diawin.c */
extern void CreateDialogWindow();
extern void CreateTournamentWindow();

/* drawing.c */
extern void draw_doubler();

/* misc.c */
extern void AddResult();

/* xgammon.c */
extern void Quit();
extern void MenuSelect();
extern void restart();

void CreateXGammonPopup();
void PopupInfoShell();
void PopdownInfoShell();
void ShowComputerAnswerToDoubling();
void AcceptResignPopup();

void CreateXGammonPopup(void)
{
	int i;

	button_shell = XtCreatePopupShell("XGammon-Buttons", topLevelShellWidgetClass, toplevel, NULL, 0);
	form = XtCreateManagedWidget("form", formWidgetClass, button_shell, NULL, 0);

	/* some buttons to push */

	quit = XtCreateManagedWidget("quit", commandWidgetClass, form, NULL, 0);
	XtAddCallback(quit, XtNcallback, Quit, NULL);

	/* the file menu */

	file_button = XtCreateManagedWidget("file", menuButtonWidgetClass, form, NULL, 0);

	menu   = XtCreatePopupShell("menu", simpleMenuWidgetClass, file_button, NULL, 0);

	i = 0;
	while (menu1_names[i]) {
		entry  = XtCreateManagedWidget(menu1_names[i], smeBSBObjectClass, menu, NULL, 0);
		XtAddCallback(entry, XtNcallback, MenuSelect, NULL);
		i++;
	}

	/* the game menu */

	setgame = XtCreateManagedWidget("game", menuButtonWidgetClass, form, NULL, 0);

	menu   = XtCreatePopupShell("menu", simpleMenuWidgetClass, setgame, NULL, 0);

	i = 0;
	while (menu2_names[i]) {
		entry  = XtCreateManagedWidget(menu2_names[i], smeBSBObjectClass, menu, NULL, 0);
		XtAddCallback(entry, XtNcallback, MenuSelect, NULL);
		i++;
	}

	/* no more menus and buttons to pussh */

	/* finally the textwidgets to display some */

	CreateTournamentWindow(form);
	CreateDialogWindow(form);
}

void ShowComputerAnswerToDoubling(int accept)
{
	char *label_string;
	Arg arg[5];
	Position x, y;
	Widget form, label, ok;

	XtSetArg(arg[0], XtNx, &x);
	XtSetArg(arg[1], XtNy, &y);
	XtGetValues(toplevel, arg, 2);
	x += width/2;                   /* in the middle of the board */
	y += height/2;

	XtSetArg(arg[0], XtNx, x);
	XtSetArg(arg[1], XtNy, y);
	popup_shell = XtCreatePopupShell("doubling", transientShellWidgetClass, toplevel, arg, 2);

	form = XtCreateManagedWidget("form", formWidgetClass, popup_shell, NULL, 0);

	if (accept) label_string = " I accept doubling ";
	else label_string = " I resign ";
	XtSetArg(arg[0], XtNlabel, label_string);
	label = XtCreateManagedWidget("label", labelWidgetClass, form, arg, 1);

	XtSetArg(arg[0], XtNfromVert, label);
	/* since the decision is already fallen, this command button is dummmy,
	   it could also be a label, but it highlights, the events are
	   managed in the calling function
	 */
	ok = XtCreateManagedWidget("ok", commandWidgetClass, form, arg, 1);

	XtPopup(popup_shell, XtGrabExclusive);
}

/* AcceptResignPopup()
   this popup is alaways called, when the anser of a human player aspected,
   the difference in layout is checked via the Player[].type.
   the function then simply waits for a button event.
 */

void AcceptResignPopup(void)
{
	char *label_string;
	Arg arg[2];
	Position x, y;
	Widget form, label, resign, accept;

	XtSetArg(arg[0], XtNx, &x);
	XtSetArg(arg[1], XtNy, &y);
	XtGetValues(toplevel, arg, 2);
	x += width/2;                   /* in the middle of the board */
	y += height/2;

	XtSetArg(arg[0], XtNx, x);
	XtSetArg(arg[1], XtNy, y);
	popup_shell = XtCreatePopupShell("doubling", transientShellWidgetClass, toplevel, arg, 2);

	form = XtCreateManagedWidget("form", formWidgetClass, popup_shell, NULL, 0);

	if (Player[0].type == HUMAN && Player[1].type == HUMAN) {
		if (turn == BLACK) label_string = "white player:\ndo you accept doubling?";
		else		   label_string = "black player:\ndo you accept doubling?";
	}
	else {
		label_string = "I'd like to double\ndo you accept?";
	}
	XtSetArg(arg[0], XtNlabel, label_string);
	label = XtCreateManagedWidget("label", labelWidgetClass, form, arg, 1);

	XtSetArg(arg[0], XtNfromVert, label);
	resign = XtCreateManagedWidget("resign", commandWidgetClass, form, arg, 1);

	XtSetArg(arg[1], XtNfromHoriz, resign);
	accept = XtCreateManagedWidget("accept", commandWidgetClass, form, arg, 2);

	XtPopup(popup_shell, XtGrabExclusive);

/* once again an event problem, cause of cache and buffering or whatever else,
   the Callback functions are too slow, to get an event and process it,
   before the event loops look for the next one. so, you have to trigger two
   events, to pop the shell down or I try this fuck here. (can't do better, yet)
   any event, than pressing resign button is accept.
 */

	while(1) {
		XEvent event;
	        XtAppNextEvent(app_con, &event);
	        if(event.type == ButtonRelease) {
		   if (event.xbutton.window == XtWindow(resign)) {
			end_of_game = 1;
	        	XtDispatchEvent(&event);
	           	break;
			}
		   else if (event.xbutton.window == XtWindow(accept)) {
	        	XtDispatchEvent(&event);
			break;
		   }
	        }
	        XtDispatchEvent(&event);
	}
	XtPopdown(popup_shell);
}

void PopupInfoShell(char *message)
{
Arg arg[3];
Position x, y;
Widget info_form, info_label, down;
extern XtAppContext app_con;

XtSetArg(arg[0], XtNx, &x);
XtSetArg(arg[1], XtNy, &y);
XtGetValues(toplevel, arg, 2);
x += width/4;                   /* almost above the doubler */
y += height/2;

XtSetArg(arg[0], XtNx, x);
XtSetArg(arg[1], XtNy, y);
popup_shell = XtCreatePopupShell("Info", transientShellWidgetClass, toplevel, arg, 2);

info_form  = XtCreateManagedWidget("info_form", formWidgetClass, popup_shell, NULL, 0);

XtSetArg(arg[0], XtNlabel, message);
info_label = XtCreateManagedWidget("info_label", labelWidgetClass, info_form, arg, 1);

XtSetArg(arg[0], XtNfromVert, info_label);
down = XtCreateManagedWidget("ok", commandWidgetClass, info_form, arg, 1);
XtAddCallback(down, XtNcallback, PopdownInfoShell, (XtPointer) 0);

XtAppAddTimeOut(app_con, 5000, PopdownInfoShell, (XtPointer) 0);

XtPopup(popup_shell, XtGrabExclusive);
}

void PopdownInfoShell(Widget w, XtPointer call_data, XtPointer client_data)
{
	XtPopdown(popup_shell);
}
