
//Title:
//Version:     1.0
//Copyright:   Copyright (c) Waterloo Maple Inc
//Author:      Bill Huiskamp
//Company:     Waterloo Maple Inc
//Description:
package com.maplesoft.maplenet.tutorial;

import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.lang.System;
import java.net.URL;
import com.maplesoft.client.MapleStatement;
import javax.swing.*;

import java.beans.*;

/**
 * Applet to test sending a string containing a Maple command to the MapleNet server
 */
public class MapleCommandApplet extends JApplet {
   boolean isStandalone = false;
   String      sHost;
   int         iPort;
   String      sUser;
   String      sPassword;

   JLabel jLabel1           = new JLabel();
   JTextField jHostname     = new JTextField();
   JLabel jLabel2           = new JLabel();
   JTextField jPortNumber   = new JTextField();
   JLabel jLabel3           = new JLabel();
   JTextField jUserName     = new JTextField();
   JLabel jLabel4           = new JLabel();
   JPasswordField jPassword = new JPasswordField();
   JScrollPane jScrollPane1 = new JScrollPane();
   JTextArea jResultWindow     = new JTextArea();
   JTextField jCommandLine  = new JTextField();
   JButton jClearButton     = new JButton();
   JButton jSendButton      = new JButton();

   //Get a parameter value
   public String getParameter(String key, String def) {
      return isStandalone ? System.getProperty(key, def) :
         (getParameter(key) != null ? getParameter(key) : def);
   }

   //Construct the applet
   public MapleCommandApplet() {
   }

   //Initialize the applet and set default parameters
   public void init() {


      // Set name of machine containing the MapleNet server
      try {
         if( isStandalone ) {
            sHost = this.getParameter("host", "localhost" );
         } else {
            URL url = getDocumentBase();
            String sDocHost = url.getHost();
            sHost = this.getParameter("host", sDocHost );
            System.out.println("DocHost " + sDocHost);
         }
      }
      catch(Exception e) {
         e.printStackTrace();
      }

      // Set the communcication port
      try {
         iPort = Integer.parseInt(this.getParameter("port", "14444"));
      }
      catch(Exception e) {
         e.printStackTrace();
      }

      // Get username
      try {
         sUser = this.getParameter("user", "client");
      }
      catch(Exception e) {
         e.printStackTrace();
      }

      // Set user password
      try {
         sPassword = this.getParameter("password", "demopass");
      }
      catch(Exception e) {
         e.printStackTrace();
      }

      // Create the Visual components on the applet
      try {
         jbInit();
      }
      catch(Exception e) {
         e.printStackTrace();
      }
   }

   //Component initialization
   private void jbInit() throws Exception {


      this.getContentPane().setLayout(null);

      // Set up Entry field for Hostname
      jLabel1.setText("Hostname");
      jLabel1.setBounds(new Rectangle(21, 18, 71, 17));
      jHostname.setNextFocusableComponent(jPortNumber);
      jHostname.setToolTipText("Enter name of the MapleNet Server");
      jHostname.setText( sHost );
      jHostname.setBounds(new Rectangle(115, 18, 447, 19));

      // Set up Entry field for Port Number
      jLabel2.setText("Port");
      jLabel2.setBounds(new Rectangle(21, 44, 71, 17));
      jPortNumber.setNextFocusableComponent(jUserName);
      jPortNumber.setToolTipText("Enter the Port that the Maple Server is listening on");
      jPortNumber.setText( Integer.toString(iPort) );
      jPortNumber.setBounds(new Rectangle(115, 44, 82, 19));

      // Set up Entry field for Username
      jLabel3.setText("Username");
      jLabel3.setBounds(new Rectangle(21, 78, 71, 17));
      jUserName.setNextFocusableComponent(jPassword);
      jUserName.setToolTipText("Enter the MapleNet Username");
      jUserName.setText( sUser );
      jUserName.setBounds(new Rectangle(115, 78, 447, 19));

      // Set up Entry field for password
      jLabel4.setText("Password");
      jLabel4.setBounds(new Rectangle(21, 101, 71, 17));
      jPassword.setToolTipText("Enter the password for the user");
      jPassword.setNextFocusableComponent(jCommandLine);
      jPassword.setBounds(new Rectangle(115, 101, 147, 19));
      jPassword.setText( sPassword );

      // Set up the behaviour of the Command Entry Line
      jCommandLine.setBackground(SystemColor.info);
      jCommandLine.setNextFocusableComponent(jClearButton);
      jCommandLine.setToolTipText("Type in a Maple Command");
      jCommandLine.setText("<Enter command here>");
      jCommandLine.setBounds(new Rectangle(22, 502, 542, 32));
      jCommandLine.addActionListener(new MapleCommandApplet_jCommandLine_actionAdapter(this));

      // Set the Clear Button
      jClearButton.setNextFocusableComponent(jSendButton);
      jClearButton.setToolTipText("Clears the result window");
      jClearButton.setText("Clear");
      jClearButton.setBounds(new Rectangle(153, 550, 108, 30));
      jClearButton.addActionListener(new MapleCommandApplet_jClearButton_actionAdapter(this));

      // Set the Send Button
      jSendButton.setNextFocusableComponent(jHostname);
      jSendButton.setToolTipText("Will send Maple command to the server");
      jSendButton.setText("Send");
      jSendButton.setBounds(new Rectangle(316, 550, 97, 32));
      jSendButton.addActionListener(new MapleCommandApplet_jSendButton_actionAdapter(this));

      // Settings for Scrollable Window - it is a 'text pane' inside of a 'scroll pane'
      jResultWindow.setToolTipText("Result Window showing answer from Maple Server");
      jResultWindow.setEditable(false);
      jScrollPane1.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
      jScrollPane1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
      jScrollPane1.setViewportBorder(BorderFactory.createLoweredBevelBorder());
      jScrollPane1.setAutoscrolls(true);
      jScrollPane1.setBounds(new Rectangle(22, 134, 542, 367));

      // Add the components to the ContentPane of the Applet
      this.getContentPane().add(jLabel1, null);
      this.getContentPane().add(jHostname, null);
      this.getContentPane().add(jLabel2, null);
      this.getContentPane().add(jPortNumber, null);
      this.getContentPane().add(jLabel3, null);
      this.getContentPane().add(jUserName, null);
      this.getContentPane().add(jLabel4, null);
      this.getContentPane().add(jPassword, null);

      jScrollPane1.getViewport().add(jResultWindow, null);
      this.getContentPane().add(jScrollPane1, null);

      this.getContentPane().add(jCommandLine, null);
      this.getContentPane().add(jSendButton, null);
      this.getContentPane().add(jClearButton, null);
   }

   //Start the applet
   public void start() {
   }

   //Stop the applet
   public void stop() {
   }

   //Destroy the applet
   public void destroy() {
   }


   //Get Applet information
   public String getAppletInfo() {
      return "Applet Information";
   }

   //Get parameter info
   public String[][] getParameterInfo() {
      String[][] pinfo =
         {
         {"host",     "String",   "Name of Host machine"},
         {"port",     "int",      "Connection Port"},
         {"user",     "String",   "User name"},
         {"password", "String",   "users password"},
         };
      return pinfo;
   }

   //Main method - this is used when running standalone
   public static void main(String[] args) {

      // Create the basic applet
      MapleCommandApplet applet = new MapleCommandApplet();
      applet.isStandalone = true;

      // Create the frame that Applet will appear in
      JFrame frame = new JFrame();

      frame.setDefaultCloseOperation(3); //EXIT_ON_CLOSE == 3
      frame.setTitle("Maple Command Applet");
      frame.getContentPane().add(applet, BorderLayout.CENTER);
      frame.setSize(600,620);

      applet.init();
      applet.start();

      Dimension d = Toolkit.getDefaultToolkit().getScreenSize();

      // Center applet on screen
      frame.setLocation((d.width - frame.getSize().width) / 2, (d.height - frame.getSize().height) / 2);
      frame.setVisible(true);

      applet.setFocusToCommandLine();
   }

   //static initializer for setting look & feel
   static {
      try {
         //UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
         //UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
      }
      catch(Exception e) {
      }
   }

   public void setFocusToCommandLine() {
      jCommandLine.selectAll();
      jCommandLine.requestFocus();
   }

   // Command to enable the buttons
   private void enable_cmds() {
      jSendButton.setEnabled( true );
   }

   // Command to disable the buttons - disable when sending to server
   private void disable_cmds() {
      jSendButton.setEnabled( false );
   }

   // Make sure that variable are in sync with Entry fields
   private void update_user_and_host() {
      sHost = jHostname.getText();
      iPort = Integer.parseInt( jPortNumber.getText());
      sUser = jUserName.getText();
      sPassword = jPassword.getText();
   }


   // Work horse when something is to be sent to Server
   private void do_something() {

      // Prevent user from sending twice
      disable_cmds();

      // make sure data is in sync
      update_user_and_host();

      // Create a maple statement to use
      MapleStatement cmd = new MapleStatement( sHost, iPort, sUser, sPassword );
      String answer;

      // Must catch exceptions that might be generated
      try {
         // Take raw text from Command Line and forward to Server using 'execute()'
         // Store the result in answer
         answer = cmd.execute( jCommandLine.getText( ) );
      } catch( Exception ex ) {
         // Use the exception as the answer
         answer = ex.toString();
      }

      // Make sure that the buttons are enabled again
      enable_cmds();

      // Format the input and output to the Results Window
      jResultWindow.append("Input : " + jCommandLine.getText( ) + "\n" );
      jResultWindow.append("Output: " + answer + "\n_____________________________________________________________________________\n" );

      // Go back to the command line for next input
      setFocusToCommandLine();
   }

   // The SEND button has been pressed
   void jSendButton_actionPerformed(ActionEvent e) {
      do_something();
   }

   // The ENTER key has been pressed in the Command Line
   void jCommandLine_actionPerformed(ActionEvent e) {
      do_something();
   }

   // The CLEAR button has been pressed
   void jClearButton_actionPerformed(ActionEvent e) {
      disable_cmds();
      jResultWindow.setText( "" );

      // Go back to the command line for next input
      setFocusToCommandLine();

      enable_cmds();
   }

}

// INNER CLass for the SEND Button
class MapleCommandApplet_jSendButton_actionAdapter implements java.awt.event.ActionListener {
   MapleCommandApplet adaptee;

   MapleCommandApplet_jSendButton_actionAdapter(MapleCommandApplet adaptee) {
      this.adaptee = adaptee;
   }

   public void actionPerformed(ActionEvent e) {
      adaptee.jSendButton_actionPerformed(e);
   }
}

// INNER CLass for the Command Line
class MapleCommandApplet_jCommandLine_actionAdapter implements java.awt.event.ActionListener {
   MapleCommandApplet adaptee;

   MapleCommandApplet_jCommandLine_actionAdapter(MapleCommandApplet adaptee) {
      this.adaptee = adaptee;
   }

   public void actionPerformed(ActionEvent e) {
      adaptee.jCommandLine_actionPerformed(e);
   }
}

// INNER CLass for the CLEAR Button
class MapleCommandApplet_jClearButton_actionAdapter implements java.awt.event.ActionListener {
   MapleCommandApplet adaptee;

   MapleCommandApplet_jClearButton_actionAdapter(MapleCommandApplet adaptee) {
      this.adaptee = adaptee;
   }

   public void actionPerformed(ActionEvent e) {
      adaptee.jClearButton_actionPerformed(e);
   }
}

