import com.mathwizards.remote.*;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import java.net.*;
import java.rmi.*;
import java.rmi.server.*;

public class SimpleClientApplet extends Applet implements com.mathwizards.remote.Client, ActionListener, KeyListener {

  com.mathwizards.remote.Engine server = null;
  Object eval_done = new Object();

  Button disconnect = new Button("Disconnect" );
  Button eval = new Button("Eval" );

  TextArea  console = new TextArea();
  TextArea  diary   = new TextArea();
  TextField prompt  = new TextField();

  String host;

  GenericRemoteClient generic_remote_client = new GenericRemoteClient( this );

  public void init() {

    setLayout( new GridBagLayout() );
    GridBagConstraints gbc = new GridBagConstraints();
    
    gbc.fill = GridBagConstraints.HORIZONTAL;
    gbc.gridx = 0;
    gbc.gridy = 0;
    add( console , gbc );

    gbc.gridy = 1;
    add( diary , gbc );

    gbc.gridy = 2;
    add( prompt , gbc );

    gbc.gridy = 3;
    add( eval , gbc );

    disconnect.addActionListener( this );
    eval.addActionListener( this );
    prompt.addKeyListener( this );

    prompt.setBackground( Color.yellow );
    console.setBackground( Color.cyan );
    prompt.requestFocus();

    host = getDocumentBase().getHost();

  }

  public void keyReleased( KeyEvent e ) {
    if ( e.getKeyCode() == KeyEvent.VK_ENTER )
      Eval();
  }

  public void Eval() {

    try {

      if ( !isConnected() )
	server = connect( getDocumentBase() );

      if ( !isConnected() )
	return;

      server.eval( generic_remote_client , prompt.getText() );

      synchronized( eval_done ) {
	try {
	  eval_done.wait(60000L); // wait for a minute
	}
	catch ( Exception e ) {
	  console.append( e.getMessage() + "\n" );
	}
      }
      
    }
    catch ( RemoteException e ) {

      console.append("lost connection to MathXplorer/J server on host " + 
		     host + " ...\n");
      console.append( e.getMessage() +"\n" );
      server = null;
    } 
  }

  public void actionPerformed( ActionEvent e ) {

    Object source = e.getSource();

    if ( source == eval )
      Eval();

    else if ( source == disconnect )
      if ( isConnected() )
	disconnect();

  }

  public void timeout( double minutes ) {
    System.out.println("applet time out by server after " +
		       minutes + " minutes of inactivity");
    server = null;
  }

  public void displayResult( String str ) throws RemoteException {
    console.append( str );
  }

  public com.mathwizards.remote.Engine connect( URL base ) {
    return generic_remote_client.connect( base );
  }

  public void disconnect() {
    generic_remote_client.disconnect();
  }

  public void destroy() {

    if ( isConnected() )
	disconnect();
    
  }

  public void quit() throws RemoteException {
    disconnect();
  }

  boolean isConnected() {
    return generic_remote_client.isConnected();
  }

  public void evalDone( String script , int remainingScripts ) throws RemoteException {
    synchronized (eval_done) {
      eval_done.notify();
    }
    diary.append( script + "\n" );
    prompt.setText("");

  }

  public void ack() {}

  public void printStatusMessage( String str ) {
    console.append( str );
  }
    
  public void keyTyped( KeyEvent e ) {}
  public void keyPressed( KeyEvent e ) {}
  public void parseError( String error ) throws RemoteException {}
  public void varChanged( String var ) throws RemoteException {}
 

}
