/** (C) 1999 World Xiangqi League, Confidential, All Rights Reserved */

import java.awt.*;
import java.util.*;

/** Provide various types of Dialogs. */
class Stickup extends Dialog {
  private Club club;		// parent frame
  private String title;		// command description / title
  private String defval;	// default value / server command / no button
  private String actionLabel;	// Profile, Mute, Strike, OK

  private TextArea textArea;	// put body here
  private TextField input;	// input-field
  private String value;		// input-field's current value
  private boolean completed;	// puke
  private Component[] tabOrder;  

  /** Info window. E.g., Help->About. */
  public static void info(Club club, String title, String body) {
    Stickup stickup = new Stickup(club,title,
				  false, // not modal
				  "OK",	// action label
				  body,
				  0, null); // input field length & defval
  }
  
  /** Member command window. E.g., Member->Profile, Mute, Strike */
  public static String member(Club club, String command, String defval) {
    if (club.browserMSIE3()) {		// puke modal dialog lockup bug
      if (defval==null)
	Stickup.info(club,"Microsoft Java Modal Dialog Bug",
		     "Due to a bug in Microsoft Java Modal Dialogs, the\n"+
		     command+" command can not prompt you for input.\n\n"+
		     "To use this command, you must first double-click\n"+
		     "select the desired member name from within the\n"+
		     "ChatOutputPanel, and then run this command again.");
      return defval;
    }
    String title = command+" Member";
    Stickup stickup = new Stickup(club,title,true,command,
				  "Member", 10, (defval==null) ? "" :
				  defval);
    //Club.debug("Stickup.member calling value()...");
    String member = stickup.value();
    //Club.debug("Stickup.member got "+member);
    if (member!=null && member.equals(""))
      member = null;
    return member;
  }

  /** Modal choice window. */
  public static boolean yesno(Club club, String title, String body,
			      String yes, String no) {
    if (club.browserMSIE3()) {		// puke modal dialog lockup bug
      System.out.println("Due to a Microsoft Java Modal Dialog bug, the\n"+
			 title+
			 " confirmation dialog immediately returned true.");
      return true;
    }
    Stickup stickup = new Stickup(club,title,/*modal=*/true,
				  yes,body,0,no);
    String result = stickup.value();
    return (result==null);
  }

  // -----------------------------------------------------------------

  /** Constructor does the actual stickup windows.
   * Other classes use above wrapper methods vs. this directly.
   */
  Stickup(Club club,
	  String title,
	  boolean modal,
	  String actionLabel,	// Profile, Mute, Strike, OK
          String body,		// Input field label else info body
	  int len,		// Input fieldlen, else 0(info) or -1(list)
	  String defval) {	// Default value for input field
    super((Frame)club,title,modal);
    this.club = club;
    this.title = title;
    this.defval = defval;
    this.actionLabel = actionLabel;

    this.input = null;
    this.value = null;
    this.completed = false;	// puke

    Panel top = new Panel();
    top.setLayout(new FlowLayout());
    Panel bottom = new Panel();
    bottom.setLayout(new FlowLayout());
    Button actionButton = new Button(actionLabel);
    bottom.add(actionButton);

    if (len<0) {		// special server list command
      bottom.add(new Button("Update"));
    }

    if (len<=0) {		// About Dialog
      // Java 1.0 no scrollbars in constructor:
      textArea=new TextArea(body,12,40);//,TextArea.SCROLLBARS_NONE);
      textArea.setBackground(Color.white);
      textArea.setEditable(false);
      textArea.setFont(new Font("Helvetica",Font.PLAIN,16));
      top.add(textArea);
      tabOrder = null;
      if (len==0 && defval!=null) // yesno dialog
	bottom.add(new Button(defval));
    } else {			// Member Dialog, needs input
      input = new TextField(defval,len);
      if (defval.equals("")==false)
	input.selectAll();
      top.add(new Label(body));
      top.add(input);
      Button cancelButton = new Button("Cancel");
      bottom.add(cancelButton);
      tabOrder = new Component[3];
      tabOrder[0] = input;
      tabOrder[1] = actionButton;
      tabOrder[2] = cancelButton;
    }
    
    add("North",top);
    add("South",bottom);
    open();
    if (input!=null)
      input.requestFocus();
    else
      actionButton.requestFocus();
  }

  public void open() {		// Cf ./Tables.java
    pack();
    Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    move( (d.width-size().width)/2, (d.height-size().height)/2 );

    Window w = this;		// show() not implemented for N3 Dialog
    w.pack();			// hack attempt fix for 640x480? layout bug
    w.show();			// thus use Window show method
				// else create dummy Frame to be Dialog parent
    repaint();
  }

  // Use action() instead to save time
  public boolean handleEvent(Event event) {
    //Club.debugEvent("Stickup",event);
    if (event.id==Event.WINDOW_DESTROY || event.arg=="Cancel") {
      complete(null);
      return true;
    }
    if (event.id==Event.KEY_PRESS) {
      //Club.debugEvent("Stickup",event);
      if (event.key==9 && tabOrder!=null) {
	tabProcess(event);
	return true;
      } else if (event.key==10) { // return key
	//Club.debug("Stickup got "+input.getText());
	complete((input!=null) ? input.getText().trim() : null);
	return true;
      } else if (event.key==27) { // escape key
	complete(null);
	return true;
      }
    }
    if (event.id!=Event.ACTION_EVENT)
      return super.handleEvent(event);
    if (event.arg==actionLabel) {
      complete((input!=null) ? input.getText().trim() : null);
      return true;
    }
    if (event.arg=="Update") {
      textArea.setText("Requesting "+title+"...");
      //StringTokenizer reply = club.list(defval);
      //textArea.setText(reply.nextToken("\0"));
    }
    if (event.arg==defval) {	// "no" button
      complete(defval);
      return true;
    }
    return super.handleEvent(event);
  }

  private void tabProcess(Event event) {
    int index = 0;
    while (index<tabOrder.length && tabOrder[index]!=event.target)
      index++;
    index += (((event.modifiers&Event.SHIFT_MASK)==0) ? 1 : -1);
    if (index<0) index=tabOrder.length-1;
    if (index>=tabOrder.length) index=0;
    tabOrder[index].requestFocus();
  }
  
  private void complete(String value) {
    this.value = value;
    //Club.debug("Stickup.complete "+value);
    hide();			// close the window
    dispose();			// destroy its resources
    completed = true;		// puke
  }

  private String value() {
    // IE3 Dialog.show() returns immediately, even for modal dialogs.
    // We could do a wait/notify pair, but AWT thread can't notify
    // stuff in our thread group. UGGH.
    while (completed==false) {
      Club.debug("Waiting for value...");
      Club.sleep(2000);
    }
    return value;
  }
}
