/**
 * This is a template.  You may modify this file.
 *
 * Runtime vendor: SunSoft, Inc.
 * Runtime version: 1
 *
 * Visual vendor: SunSoft, Inc.
 * Visual version: 1
 */


import sunsoft.jws.visual.rt.base.*;
import sunsoft.jws.visual.rt.shadow.java.awt.*;
import java.awt.*;
import java.io.*;
import java.net.*;

public class SocketClient extends Group {
  private SocketClientRoot gui;

  /**
   * Sample method call ordering during a group's lifetime:
   *
   * Constructor
   * initRoot
   * initGroup
   * (setOnGroup and getOnGroup may be called at any time in any
   *  order after initGroup has been called)
   * createGroup
   * showGroup/hideGroup + startGroup/stopGroup
   * destroyGroup
   */

  /**
   * All the attributes used by the group must be defined in the
   * constructor.  setOnGroup is called at initialization for all
   * the attributes.  If the attribute has not been set prior to
   * initialization, setOnGroup is called with the default value.
   */
  public SocketClient() {
    /**
     * Define the group's custom attributes here.
     *
     * For example:
     *
     * attributes.add("customString", "java.lang.String",
     *		      "Default String", 0);
     */

    /**
     * This method defines the attributes that will be forwarded to
     * the main child (either a window or a panel).  All attributes
     * defined by this method are marked with the FORWARD flag.
     */
    addForwardedAttributes();
  }

  /**
   * initRoot must be overridden in group subclasses to initialize
   * the shadow tree.  The return value must be the root of the
   * newly initialized shadow tree.
   */
  protected Root initRoot() {
    /**
     * Initialize the gui components
     */
    gui = new SocketClientRoot(this);

    /**
     * This method registers an attribute manager with the group, such
     * that attributes marked with the FORWARD flag will be sent to
     * this attribute manager.
     */
    addAttributeForward(gui.getMainChild());

    return gui;
  }

  /**
   * initGroup is called during initialization.  It is called just after
   * initRoot is called, but before the sub-groups are initialized and
   * before the attributes are sent to the setOnGroup method.
   *
   * initGroup is only called once in the lifetime of the Group.
   * This is because groups cannot be uninitialized.  Anything that
   * needs to be cleaned up should be created in createGroup instead
   * of initGroup, and then can be cleaned up in destroyGroup.
   * createGroup and destroyGroup may be called multiple times during
   * the lifetime of a group.
   */
  protected void initGroup() { }

  /**
   * showGroup may be overridden by group subclasses that want
   * to know when the group becomes visible.  It is called just before
   * the group becomes visible.  The group will already be initialized
   * and created at this point.
   */
  protected void showGroup() { }

  /**
   * hideGroup may be overridden by group subclasses that want
   * to know when the group becomes non-visible.  It is called just
   * before the group becomes non-visible.
   */
  protected void hideGroup() { }

  /**
   * createGroup is called during group creation.  Groups can be
   * created and destroyed multiple times during their lifetime.
   * Anything that is created in createGroup should be cleaned up
   * in destroyGroup.  createGroup is called just after the group
   * has been created.  Anything that needs to be done before the
   * group is created should be done in initGroup.
   */
  protected void createGroup() { }

  /**
   * destroyGroup is called during the destroy operation.  Groups can
   * be created and destroyed multiple times during their lifetime.
   * Anything that has been created in createGroup should be cleaned up
   * in destroyGroup.  destroyGroup is called just before the group
   * is destroyed.
   */
  protected void destroyGroup() { }

  /**
   * This method may be overridden by group subclasses that want
   * to be informed when the application is starting.  This method is
   * only called after the entire application has been initialized and
   * created.
   *
   * For applets, startGroup is called whenever start is called on the
   * applet.
   */
  protected void startGroup() {
  }

  /**
   * This method may be overridden by group subclasses that want
   * to be informed when the application is stopping.  This method
   * will be called before a destroy is done.
   *
   * For applets, stopGroup is called whenever stop is called on the
   * applet.
   */
  protected void stopGroup() { }

  /**
   * "getOnGroup" may be overridden by sub-groups that
   * store attribute values themselves, and do not depend on the
   * group superclass to store them.  This method should be overridden
   * instead of "get".  Any attributes handled in setOnGroup where
   * super.setOnGroup is not called must also be handled in getOnGroup.
   *
   * The default implementation of getOnGroup retrieves the value
   * from the attribute table.
   *
   * The reason that "getOnGroup" should be overridden instead
   * of "get" is that "getOnGroup" is guaranteed not to be called
   * until the group class is initialized.  This means that initRoot
   * will always be called before any calls to getOnGroup are made.
   *
   * Also, this method is only for attributes that are defined in the
   * sub-groups.  It is not called for forwarded attributes.
   */
  protected Object getOnGroup(String key) {
    return super.getOnGroup(key);
  }

  /**
   * "setOnGroup" may be overridden by sub-groups that
   * want notification when attributes are changed.  This method
   * should be overridden instead of "set".  Any attributes handled
   * in setOnGroup where super.setOnGroup is not called must also be
   * handled in getOnGroup.
   *
   * The default implementation of setOnGroup puts the value
   * in the attribute table.
   *
   * The reason that "setOnGroup" should be overridden instead
   * of "set" is that "setOnGroup" is guaranteed not to be called
   * until the group class is initialized.  This means that initRoot
   * will always be called before any calls to setOnGroup are made.
   *
   * During initialization, "setOnGroup" will be called for all
   * the group's attributes even if they have not be changed from
   * the default value.  But for attributes that have the DEFAULT
   * flag set, "setOnGroup" will only be called if the value
   * of the attribute has changed from the default.
   *
   * Also, this method is only called when attributes defined in the
   * sub-groups are updated.  It is not called for forwarded attributes.
   */
  protected void setOnGroup(String key, Object value) {
    super.setOnGroup(key, value);
  }

  /**
   * handleMessage may be overridden by subclasses that want to act
   * on messages that are sent to the group.  Typically, messages are
   * either AWT events that have been translated to messages, or they
   * are messages that have been sent by other groups.
   * super.handleMessage should be called for any messages that aren't
   * handled.  If super.handleMessage is not called, then handleEvent
   * will not be called.
   *
   * The default implementation of handleMessage returns "true".  This
   * means that no events will be passed up the group tree, unless a
   * subclass overrides this method to return "false".  AWT events are
   * not propagated regardless of the return value from handleEvent.
   *
   * If you want a message to go to the parent group, override
   * handleMessage to return false for that message.
   *
   * If you want an AWT event to go to the parent group, you need to
   * call postMessageToParent() with the event message.
   */
  public boolean handleMessage(Message msg) {
    return super.handleMessage(msg);
  }

  /**
   * handleEvent may be overridden by subclasses that want to get
   * notified when AWT events that are sent by the gui components.
   * The return value should be true for handled events, and
   * super.handleEvent should be called for unhandled events.
   * If super.handleEvent is not called, then the specific event
   * handling methods will not be called.
   *
   * The message's target is set to the shadow that sent the event.
   * The event's target is set to the AWT component that sent the event.
   *
   *
   * The following specific event handling methods may also be overridden:
   *
   * public boolean mouseDown(Message msg, Event evt, int x, int y);
   * public boolean mouseDrag(Message msg, Event evt, int x, int y);
   * public boolean mouseUp(Message msg, Event evt, int x, int y);
   * public boolean mouseMove(Message msg, Event evt, int x, int y);
   * public boolean mouseEnter(Message msg, Event evt, int x, int y);
   * public boolean mouseExit(Message msg, Event evt, int x, int y);
   * public boolean keyDown(Message msg, Event evt, int key);
   * public boolean keyUp(Message msg, Event evt, int key);
   * public boolean action(Message msg, Event evt, Object what);
   * public boolean gotFocus(Message msg, Event evt, Object what);
   * public boolean lostFocus(Message msg, Event evt, Object what);
   */
  public boolean handleEvent(Message msg, Event evt) {
    return super.handleEvent(msg, evt);
  }
}

class Client extends Thread
{
  TextFieldShadow privateTextField;
  TextAreaShadow privateTextArea;

  Client(TextFieldShadow textfield1, TextAreaShadow textarea1) {
    privateTextField=textfield1;
    privateTextArea=textarea1;
  }

  public void run() {

      try {
		// Open a new socket connection
		Socket ClientSocket=new Socket("localhost",7523);
	
		// Start a new thread
		ClientHandleConnection thread=
		  new ClientHandleConnection(ClientSocket,
			privateTextField,
			privateTextArea);
		thread.start();
	
      } catch (IOException e) {
		System.out.println(e);
      }	
  }
}

class ClientHandleConnection extends Thread {

  Socket ConnectSocket;
  TextFieldShadow privateTextField;
  TextAreaShadow privateTextArea;

  ClientHandleConnection(Socket socket, TextFieldShadow textfield1,
			 TextAreaShadow textarea1) {
    ConnectSocket=socket;
    privateTextField=textfield1;
    privateTextArea=textarea1;
  }

  public void run() {

    try {

      // Get the input stream from the socket and convert
      // it into a data input stream
      DataInputStream Input=
	new DataInputStream(ConnectSocket.getInputStream());
      
      // Get the output stream from the socket and convert
      // it into a print stream
      PrintStream Output=
	new PrintStream(ConnectSocket.getOutputStream());
      
      // Send the server the command
      Output.println((String)privateTextField.get("text"));
      privateTextField.set("text","");
      
      // The output buffer
      String line;
      
      // Read the results from the server until the socket closes
      String text=(String)privateTextArea.get("text");
      while((line=Input.readLine())!=null) {
	text+=line;
        privateTextArea.set("text",text + "\n");
      }
	
    } catch (IOException e) {
      System.out.println(e);
    }

  }    
}

