// webmuck.java
// Container for status display and HttpSockets

import java.applet.*;
//import java.awt.*;
import java.io.*;
//import java.net.*;
//import java.util.*;
//import java.awt.event.*;
//import java.awt.datatransfer.*;
import netscape.javascript.*;

  /*
    The following functions must be defined in javascript:
    connected();
    disconnected();
    received(String data);
  */

public class webmuck extends Applet
  implements Runnable
{ 
  httpsocket lifeline = (httpsocket)null;
  InputStream is = null;
  OutputStream os = null;
  PrintWriter o = null;
  Thread readthread = (Thread)null;
  String newline = "\n"; //System.getProperty("line.separator");
  String jvm = System.getProperty("java.vendor");
  JSObject jscript;
  boolean readerRunning = false;

  //get these from a connect line.
  String user, password, host, proxurl, protocol, callback;
  int port;

  public void init()
  {
    debug("JVM vendor: " + jvm);
    String tmptoken;
//    user	= getParameter("user");
//    password	= getParameter("pass");
    protocol	= getParameter("protocol");
    host	= (getCodeBase()).getHost();
    port	= Integer.parseInt(getParameter("port"));
    proxurl	= getParameter("proxurl");

    jscript = JSObject.getWindow(this);
  }

  public void connect(String desthost, int destport)
  {
    //Opens a tunneled connection to the given host and port.
    try
    {
      debug("connecting to host "+desthost+"..." + newline);
      lifeline = new httpsocket(desthost, destport, protocol, host, port, proxurl, user, password);
      is = lifeline.getInputStream();
      os = lifeline.getOutputStream();
      o = new PrintWriter(os);
      debug("connected" + newline);
    }
    catch(IOException e)
    { debug("invalid host "+host+" or bad net condition: "+e.getMessage()+newline); }
    catch(NumberFormatException e)
    { debug("bad port number" + newline); }
    if(lifeline.sleeping)
    {
      lifeline.reader.interrupt();
    }
  }

  public void disconnect()
  {
    //Closes the connection
    try
    {
      lifeline.close();
    }
    catch(IOException e)
    { debug("Could not close connection: "+e.getMessage()+newline); }
    if(lifeline.sleeping)
    {
      lifeline.reader.interrupt();
    }
  }

  public void sendData(String data)
  {
    //Use this to send data
    o.print(data);
    o.flush();
    if(lifeline.sleeping)
    {
      lifeline.reader.interrupt();
    }
  }

  public void start()
  { // start reader first, in case reply to connect is big.
    if (readthread == null)
    { readthread = new Thread(this); // seperate thread for incoming messages
      readthread.setName("WebMuck");
      readthread.start();
    }
  }

  public void connected()
  {
    Object[] args = { };
    jscript.call("connected", args);
  }

  public void disconnected()
  {
    Object[] args = { };
    jscript.call("disconnected", args);
  }

  public void setAuth(String myUser, String myPass)
  {
    debug("Username: " + myUser + ", Password: " + myPass);
    user = myUser;
    password = myPass;
  }
    
  public void received(String msg)
  {
    Object[] args = { msg };
    jscript.call("received", args);
  }

  public void debug(String msg)
  {
    System.out.println(msg);
  }

  public void run()
  {
    while (true)
    {
      is = null;
      debug("Reader sleeping until socket connects...");
      while (is == null)
      { try { readthread.sleep(1000); }// give socket a chance to start up
        catch (Exception e)
        {  }
      }
      InputStreamReader i = new InputStreamReader(is);
      int len=1;
      boolean bad = false;
      char[] s = new char[1024];
      String s1="";
      debug("WebMuck reader started");
      connected();
      while (!bad)
      {
       try
       { 
         { readthread.sleep(50);
	   // debug("sleeping...");
         }
       }
       catch (Exception e)
       { //debug("sleep exception");
       }
       try 
       {
        try
        { 
	  { len = i.read(s,0,1024);
	    bad = false;
	  }
        }
        catch (Exception e)
        { if (!bad)
          { debug("read exception: "+e.getMessage());
            bad = true;
	    s = null;
          }
        }
        s1 = new String(s,0,len);

        if (s1.length()>0)
        { received(s1); }
       }
       catch (Exception e)
       { debug("exception in reply processing" + newline +
          e.getMessage());
       }
      }
      disconnected();
    } // endless loop
  }

// info functions
  public String getAppletInfo()
  { return ("SplitReflection WebMuck client"+ newline +
    "Developed by John Hanely"+ newline +
    "using HttpSocket"+ newline +
    "Developed by Peter Hanely"+ newline + newline +
    "Distribute and use as you please for noncomercial purposes"+
    ", but please " + newline + "give credit where credit is due."+ newline +
    "For comercial use (i.e the system using it charges), please contact me at"+ newline +
    "calin@splitreflection.com"+ newline +
    "or Peter Hanely at"+ newline +
    "hanelyp@calweb.com" + newline + newline);
  }

  public String[][] getParameterInfo()
  { String params[][] = {
    {"port", "numeric", "connection port on host"},
    }; 
    return (params);
  }
}
