/* IMPORTS */
import java.io.*;
import java.net.*;
import java.util.*;
import RoomListener;

class TerminalConnection extends Thread 
{
    /* CONSTANTS */
    // NONE

    /* MEMBER VARIABLES */
    Socket connection = null;  // Terminal's socket connection
    boolean active = false;    // Terminal's active status
    String name = "";          // Terminal's user name
    RoomListener r_listener;   // Terminal's RoomListener
    BufferedReader in = null;  // Terminal's input buffer
    PrintWriter out = null;    // Terminal's output buffer
    int cur_room = 0;          // Terminal's current room
    
    public TerminalConnection(ThreadGroup group, String name, RoomListener listener, Socket terminal) throws IOException
    {
        super(group, name);
        r_listener = listener;
        connection = terminal;
        active = true;
        in =  new BufferedReader( new InputStreamReader(
              connection.getInputStream() ));
        out = new PrintWriter( new BufferedWriter(
              new OutputStreamWriter( connection.getOutputStream() )));
              
        start(); // Calls run method
    } // constructor
    
    public String getUserName()
    {
        /* LOCAL VARIABLES */
        // NONE
        
        return(name);
    } // method getUserName
    
    private void welcome(PrintWriter out)
    {
        /* LOCAL VARIABLES */
        // NONE

        out.println();
        out.println(" ----------------------------------------------");
        out.println("   Welcome to the Cluster Chat Server System   ");
        out.println("               Version 1.0 BETA                ");
        out.println("  Created by Jon Schlueter and B. Alex Bridges ");
        out.println("           Date of Birth: 09/19/199            ");
        out.println("   ECE-488 Computer Networks - Final Project   ");
        out.println(" ----------------------------------------------");
        out.println();
        out.flush();
    } // method Welcome
    
    public void run() 
    {
        try
        {
            welcome(out);
            
            /* LOGIN LOOP */
            while(active)
            {
                out.print("What is your name? ");
                out.flush();
                name = in.readLine();
                out.println();
                out.print("You are '"+name+"'.  Is that correct? ('y' -or- 'n') ");
                out.flush();
                String response = in.readLine();
                out.println();
                if( response.toLowerCase().startsWith("y") )
                   break;
                out.flush();
            } // while
            System.out.println("User '"+name+"' just logged in on "+getName()+"\n");
            out.println("#help to get a help menu.");
            out.println();
            out.flush();
            
            /* CHATTING LOOP */
            while(active)
            {
                out.print("Room "+cur_room+" > ");
                out.flush();
                
                String str = in.readLine();
                /* COMMAND */
                if( str.startsWith("#") )
                {
                    command( str.substring(1) );
                } // if
                /* TALK MESSAGE FOR CURRENT ROOM */
                else
                {
                    talk(cur_room, str);
                } // else
                yield();
            } // while
            
            out.println("\nThank you for visiting. Please come again soon.");
            out.print("\nClosing connection . . . ");
            out.flush();
            out.close();
            in.close();
            connection.close();
            out.print("connection closed.\n");
        } // try
        catch(IOException e)
        {
            System.err.println("IOException has occurred.  The exception was:\n"+
                               e+"\n");
            e.printStackTrace(System.err);
        } // catch exception
        finally
        {
           System.out.println("Terminal closed for user '"+name+"'.\n");
           if(connection != null)
           try
           {
               connection.close();
               active = false;
           } // try
           catch(IOException e)
           {} // catch exception
        } // finally
        // NOTE: THIS NEEDS TO BE FIXED SO THAT IT WAITS UNTIL TERMINAL THREAD IS DEAD AND THEN CLEANS UP!
        r_listener.cleanup();        
    } // method run

    private void command(String str) throws IOException
    {
        /* LOCAL VARIABLES */
        String command;           // String for user's command
        TerminalConnection temp;  // Temporary TerminalConnection
        Iterator t_list;          // Iterator for list of terminals
        String response;          // String for user's response
        boolean valid;            // Validity of user's responses


        command = str.toLowerCase();
        /* HELP COMMAND */
        if( command.startsWith("help") )
        {
            out.println();
            out.println("The following commands are supported at this time:");
            out.println(" -> #help             - Prints this menu.");
            out.println(" -> [message]         - Sends message to current room.");
            out.println(" -> #yell [message]   - Sends message to every room on the server.");
            out.println(" -> #walk [room_name] - Walk to the target room.");
            out.println(" -> #who [message]    - Lists all of the users and their corresponding rooms.");
            out.println(" -> #quit/#exit       - Leaves the chat server.");
            out.println();
        } // if
        /* YELL COMMAND */
        else if( command.startsWith("yell") )
        {
            yell( str.substring(4).trim() );
        } // else if
        /* WALK COMMAND */
        else if( command.startsWith("walk") )
        {
            changeRoom( command.substring(4).trim() );
        } // else if
        /* WHO COMMAND */
        else if( command.startsWith("who") )
        {
            t_list = ((TerminalServer)r_listener).terminal_set.iterator();
            r_listener.cleanup();            
            
            //out.println("List of users on server.");
            out.println("-------------------------");
            out.println("Room  Name               ");
            out.println("-------------------------");
            while( t_list.hasNext() )
            {
                temp = (TerminalConnection)t_list.next();
                out.println(" "+temp.cur_room+"    "+temp.name);
            }
            out.println("-------------------------");
            out.println();
        } // else if
        /* QUIT/EXIT COMMAND */
        else if( command.startsWith("quit") || command.startsWith("exit") )
        {
            do
            {
                out.print("Are you sure that you wish to leave? ('y' -or- 'n') ");
                out.flush();
                response = in.readLine();
                if( response.toLowerCase().startsWith("y") || response.toLowerCase().startsWith("n") )
                    valid = true;
                else
                    valid = false;
            } while(!valid);

            if( response.toLowerCase().startsWith("y") )
                active = false;
        } // else if
        /* UNKNOWN COMMAND */
        else
        {
            out.println("Command '"+command+"' not understood.");
            out.println();
        } // else
        out.flush();
    } // method command
    
    private void yell(String msg)
    {
        /* LOCAL VARIABLES */
        // NONE

        r_listener.yell(name+" yelled '"+msg+"'");
    } // method yell
    
    private void changeRoom(String room)
    {
        /* LOCAL VARIABLES */
        // NONE

        try
        {
            cur_room = Integer.parseInt(room);
            out.println(name+" is now in room number '"+cur_room+"'.");
            System.out.println(name+" is walking to room "+cur_room);
        } // try
        catch(NumberFormatException e)
        {
            out.println("Invalid room identification, and therefore didn't change rooms.");
            out.println("Please use '#walk [int]'.\n");

        } // catch exception
        
        out.flush();
    } // method changeRoom
    
    private void talk(int room, String msg)
    {
        /* LOCAL VARIABLES */
        // NONE

        r_listener.talk(room, name+" says '"+msg+"'");
    } // method talk
    
    public void send(String msg)
    {
        /* LOCAL VARIABLES */
        // NONE

        out.println(msg);
        out.flush();
    } // method send
    
    public boolean isActive()
    {
        /* LOCAL VARIABLES */
        // NONE

        return active;
    } // method isActive
    
    public boolean inRoom(int room)
    {
        /* LOCAL VARIABLES */
        // NONE

        return (cur_room == room);
    } // method inRoom
} // class TerminalConnection
