import java.io.*;
import java.net.*;
import java.awt.*;
import java.util.*;
import java.applet.*;

/********************************************************************
 *
 * Example Applet to demonstrate Java sockets.
 * Sends messages to the Java Demo Server on the host (port
 * number 6666), and displays the replies.
 *
 * @author  Dave Wylie
 * @version 1.0, 01-Aug-1996
 *
 ********************************************************************/

public class Pinglet extends Applet
{
   static Socket pingSock;             // The socket we connect through
   static DataInputStream inStream;    // Data stream into socket
   static DataOutputStream outStream;  // Data stream out of socket
   final String PINGBUTTON = "Ping";   // Text to put on our button
   Button pingButton;                  // A button to press
   TextArea pingText;                  // For displaying sent messages
   TextArea pongText;                  // For displaying received messages

   /*****************************************************************
    *
    * Applet initialisation method. We create our user interface
    * which consists of a button and two text areas. We
    * make sure that neither text area can be edited by the
    * user, as they are for display only.
    *
    *****************************************************************/
   public void init()
   {
      // Add a ping button to our applet display
      add( pingButton = new Button( PINGBUTTON ) );

      // Add two new blank text areas to the display
      add( pingText = new TextArea( 4, 64 ) );
      add( pongText = new TextArea( 4, 64 ) );

      // Make the two text areas read only
      pingText.setEditable( false );
      pongText.setEditable( false );

      // Make sure we are visible
      show();
   }

   /*****************************************************************
    *
    * Called each time the browser displays the page.
    * This is where we create our socket, and obtain the data streams
    * we need to talk through it. We make sure that our "ping" button
    * is only enabled if we succeed in setting up the socket.
    *
    *****************************************************************/
   public void start()
   {
      // Start off with the ping button is disabled
      pingButton.disable();

      // The socket creation etc. may fail
      try
      {
         // Show the host name in the upper text area
         pingText.appendText( "Host = " + getCodeBase().getHost() + "\n" );

         // Create a socket to talk to the host that we were downloaded
         // from, using the echo server ("ping") port.
         pingSock = new Socket( getCodeBase().getHost(), 6666 );

         // Create new data streams using the socket's Input
         // and Output streams
         inStream  = new DataInputStream(  pingSock.getInputStream()  );
         outStream = new DataOutputStream( pingSock.getOutputStream() );

         // Enable the button now we've got the socket
         pingButton.enable();
      }
      catch( IOException e )
      {
         // Display an error in the second label
         pongText.appendText( "Socket setup error: " + e + "\n" );
      }
   }

   /*****************************************************************
    *
    * Called each time the browser leaves the page.
    * We disable our "ping" button and close down the socket.
    *
    *****************************************************************/
   public void stop()
   {
      // Disable the button again
      pingButton.disable();

      // The socket close may fail
      try
      {
         // Close the socket
         pingSock.close();
      }
      catch( IOException e )
      {
         // Display an error in the second label
         pongText.appendText( "Socket close error: " + e + "\n" );
      }
   }

   /*****************************************************************
    *
    * Called each time something happens on the user interface.
    * We only deal with the "ping" button here. When this is pressed
    * we send a message through the socket to the server machine,
    * and read the reply. The sent and received messages are
    * displayed in our text areas.
    *
    * @param event         Identifies what happened in the GUI
    * @param arg           The GUI object that was affected
    * @return              always "true" (shows we handled the event)
    *
    *****************************************************************/
   public boolean action(Event event, Object arg)
   {
      String pingMsg;
      String pongMsg;

      // Check for pressing a button:
      if( event.target instanceof Button )
      {
         // Check for out PING button
         if( ((String)arg).equals( PINGBUTTON ) )
         {
            // Build up a message containing the time (with a newline!)
            pingMsg = "Hello Server : " + new Date().toGMTString() + "\n";

            // Show the message in the first label
            pingText.appendText( pingMsg );

            // Socket I/O may fail
            try
            {
               // Send a message to the server
               outStream.writeChars( pingMsg );

               // Read the reply from the server
               pongMsg = inStream.readLine( );

               // Show the reply in the second label
               pongText.appendText( pongMsg + "\n" );
            }
            catch( IOException e )
            {
               // Display an error in the second label
               pongText.appendText( "Comms error: " + e + "\n" );
            }
         }
      }

      // Indicate that we've done the processing
      return true;
   }
}
