
import java.awt.*;	import java.awt.event.*;

import java.net.*;	import java.io.*;
import java.util.Hashtable;

		// all methods for a client, and event handling for PeerListFrame
public class Client extends WindowAdapter implements ActionListener, Runnable {
	
	String mynick;
	PeerListFrame app;
	public Hashtable mypeers;		//hashtable of all open peerwindows by peername
													
	public Socket me;								
	public boolean connected = false;
	
								
	Commlinks mylinks;
			
	public Client(String nick, String serv, int port) {
		
		String server = serv;
		int qryport = port;
		
		try	{	
			me = new Socket(server, qryport);
			
			mylinks = new Commlinks(me);
			
			connected = true;
			
			app = new PeerListFrame(nick +" 's client");
			
			app.addWindowListener(this);
			app.mywords.addActionListener(this);
			app.refresh.addActionListener(this);
			app.exit.addActionListener(this);
			
			mypeers = new Hashtable();
			
			mynick = nick;
			sendCommand(Commands.NICK, new String[] {mynick});	//this command has no response
			//to check response of the nick command, press refresh, to see your name
			
			Thread receiver = new Thread(this);
			receiver.start();
			app.show();
		} catch (Exception e) {System.err.println(e);}
	}
	
	
	public void actionPerformed(ActionEvent ae) {

		Object cli = ae.getSource();
		
		if(cli instanceof TextField) {
			String tosend = ((TextField)cli).getText();
			String peer = app.peerlist.getSelectedItem();
			if(peer == null) return;
			sendMessage(peer, tosend);
			printmsg(peer, "me:" + tosend);
					//System.err.println("/to "+peer + ":" + tosend);
		}
		
		else if( (Button)cli == app.exit ) {
			send(Commands.BYE);
			System.exit(0);
		}
		else if((Button)cli == app.refresh) {
					//System.err.println("refreshing");
			sendCommand(Commands.LIST, new String[]{ });
		}
	}

	public void send(String msg) {
		
		mylinks.out.println(msg);
	}
		
	public void sendCommand(String cmd, String [] params) {
		String msg = cmd;
		
		for( int i = 0; i<params.length; i++)
			msg += " " + params[i];
		
		mylinks.out.println(msg);
	}

	public void sendMessage(String peernick, String message) {
		
		mylinks.out.println(Commands.TO + peernick + " " + message);
	}

	public void run() {
		
		String [] words;
		String message;
		
		while(true) try {
			message = mylinks.in.readLine();
			words = Msg_Parser.makeArray(message);
					//System.err.println("received "+ words[0]);
			if(words[0].equals("list")) {		//special response
				
				app.peerlist.removeAll();
				for( int i = 1; i < words.length ; i ++ )
					app.peerlist.add(words[i]);
				app.show();
			}		//add other special responses here as done above
			else {
				words[0] = words[0].substring(0, words[0].length() -1);	//find the name of the peer who sent this message
				printmsg(words[0], message);
			}					
		} catch(Exception e) { }
	}
	


	public void printmsg(String peername, String msg) {
	
		
		if (peername.equals(mynick)) return;
		PeerWindow peerframe;
		
		if(mypeers.containsKey(peername)) 
			peerframe = (PeerWindow)mypeers.get(peername);
					
		else {
			mypeers.put(peername, peerframe = new PeerWindow(peername));
			peerframe.addWindowListener(this);
		}
		peerframe.text.append("\n"+msg);
		peerframe.show();
	}

	
	public void windowClosing(WindowEvent we) {
		if(we.getSource() == app) {
			send(Commands.BYE);
			System.exit(0);
		}
		else if(we.getSource() instanceof PeerWindow) {
					//System.err.println("closing peerwindow");
			PeerWindow pw = (PeerWindow)we.getSource();
			mypeers.remove(pw.getTitle());
			pw.hide();		//find a way to destroy pw
			pw.finalize();
		}
	}

	static void usage() {
		System.err.println("java Client <nickname> ");
		System.err.println("or");
		System.err.println("java Client -n <nickname> -s <server_ip> -p <server_port>");
	}

	public static void main(String [] args) throws Exception {
	
		String mynick = "default0"; 
		String server = "localhost";
		int port = 9001;		//default values
		
		switch(args.length) {		
			
			case 0: System.err.println("command line: nickname not provided");
					Client.usage();
					System.exit(1);
			
			case 1: mynick = args[0];
					break;
					
			default: 
					for (int i = 0; i < args.length; i+=2) try {
						if(args[i].equals("-n"))	mynick = args[i+1];
						if(args[i].equals("-s"))	server = args[i+1];
						if(args[i].equals("-p")) 	port = Integer.parseInt(args[i+1]);
					}catch(Exception e) {
						System.err.println("command line: invalid number of arguments");
						Client.usage();
						System.exit(2);
					}
		}
		 
		Client myclient = new Client (mynick, server, port);
	
	}
}
		