package beacon;

import java.util.*;
import java.io.*;

public class LineModeClient implements ChatterListener {
  Vector clist = new Vector();
  Hashtable names = new Hashtable();
  Hashtable cons = new Hashtable();

  public static void main(String args[])
  throws IOException, NotConnectedException {
    new LineModeClient(args);
  }

  LineModeClient(String args[]) 
  throws IOException, NotConnectedException {
    String what;

    // Create the local SimpleChat server
    Chatter c = new Chatter(true, this);
    c.lineBuffered(true);
    Thread.currentThread().yield();

    // Create the BClient and set identity
    BClient bc = new BClient();
    bc.setServer(args[0]);
    bc.setIdentity(args[1], args[2]);

    // Publish location
    System.out.println("Publishing location: "+c.port);
    bc.setLocation(c.port);

    // Start the pong thread to tell the server we still exist
    (new PongThread(bc)).start();

    // Start linemode
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    System.out.print("--> ");
    while(true){
      // Any new commands?
      while(br.ready() && ((what = br.readLine()) != null)){
	String cmd, cargs[];

	// Allocate some space for some args
	// and chop it up into a command "cmd" and some
	// args, in cargs[]
	cargs = new String[4];
	int ct=0;
	cmd = new String("");
	StringTokenizer stok = new StringTokenizer(what);
	if(stok.hasMoreTokens())
	  cmd = stok.nextToken();
	while(stok.hasMoreTokens()){
	  cargs[ct] = stok.nextToken();
	  ct++;
	}

	// Handle the "to" command
	if(cmd.equals("line")){
	  // If we don't already have an open "line" connection, start one
	  if(cons.get(cargs[0]) == null){
	    // Get their location
	    String loc = bc.requestLocation(cargs[0]);
	    System.out.println(cargs[0]+" is at "+loc);
	    Chatter newconv = new Chatter(false, this);
	    // Set who we are talking to.  This is gross.
	    newconv.talkTo((loc.substring(0, loc.indexOf(":"))).substring(loc.indexOf("/")+1), 
			   Integer.parseInt(loc.substring(loc.indexOf(":")+1)));
	    newconv.go();
	    Thread.currentThread().yield();
	    clist.addElement(newconv);
	    cons.put(cargs[0], newconv);
	    names.put(newconv, cargs[0]);
	    newconv.send(args[1]+" line reverse .\n");
	  }

	  // Get the lines to send and send them.
	  Chatter conv = ((Chatter) cons.get(cargs[0]));
	  String msg = new String("");
	GETINFO: while(true){
	  while(br.ready() && ((what = br.readLine()) != null)){
	    if(what.equals("."))
	      break GETINFO;
	    conv.send(what+"\n");
	  }
	}
	}


	System.out.print("--> ");
      }
      Thread.currentThread().yield();
    }
  }

  public void newConnection(Chatter nc){
    clist.addElement(nc);
  }

  public void received(String m, Chatter c){
    if(cons.get(c) == null) {
      // If we don't know the identity of the connection
      // This must be the opening line
      // This is handled wrong now
      cons.put(c, m);
      names.put(m, c);
    }
    // Put out whatever they said
    else
      System.out.println(((String) cons.get(c))+": "+m);
  }

  public void exception(java.io.IOException e, boolean fatal){
    System.out.println("Exception in chatter: "+e);
    if(fatal)
      System.exit(1);
  }
}
