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

public class TerminalServer extends Thread implements RoomListener
{
    /* CONSTANT */
    // NONE

    /* CLASS MEMBERS */
    ServerSocket TrmSock;       // Terminal Server's ServerSocket
    ThreadGroup terminals;      // Terminal Server's ThreadGroup
    Set terminal_set            // Collection of Terminal Servers
     = Collections.synchronizedSet( new HashSet() );
    ServerListener s_listener;  // Terminal Server's ServerListener
    int trm_count = 0;          // Coutn of Terminal Servers

    public TerminalServer(int port)
    {
        try
        {
            TrmSock = new ServerSocket(port);
        } // try
        catch(IOException e)
        {
            System.err.println("IOException has occurred.  The exception was:\n"+
                               e+"\n");
            e.printStackTrace(System.err);
        } // catch exception
        
        setDaemon(true); // Make this thread a daemon thread

        start();
    } // constructor

    public void run()
    {
        /* LOCAL VARIABLES */
        Socket s = null;  // Working Socket variable

        terminals = new ThreadGroup("TerminalConnections");
        
        while(true)
        {
            try
            {
                s = TrmSock.accept();
                System.out.println("Terminal socket accepted: "+s);
                terminal_set.add( new TerminalConnection(terminals, "tty"+trm_count, this, s) );
                trm_count++;
            } // try
            catch(IOException e1)
            {
                System.err.println("IOException has occurred.  The exception was:\n"+
                                   e1+"\n");
                e1.printStackTrace(System.err);
                try
                {
                    if(s != null)
                        s.close();
                } // try
                catch(IOException e2)
                {
                    System.err.println("IOException has occurred.  The exception was:\n"+
                                       e2+"\n");
                    e2.printStackTrace(System.err);
                } // catch exception
            } // catch exception
             
            yield();
        } // while
    } // method run

    public void talk(int room_ID, String msg)
    {
        /* LOCAL VARIABLES */
        Iterator t_list;          // Iterator for list of Terminal Servers
        TerminalConnection temp;  // Temporary TerminalConnection
        
        System.out.println("talk: The message '"+msg+"' was given for room '"+room_ID+"'.");

        t_list = terminal_set.iterator();
        
        while( t_list.hasNext() )
        {
            temp = (TerminalConnection) t_list.next();
            if( temp != null && temp.inRoom(room_ID) )
            {
                temp.send(msg);
            } // if
        } // while

        if(s_listener != null) 
            s_listener.send(room_ID, msg);
    } // talk
    
    public void yell(String msg)
    {
        /* LOCAL VARIABLES */
        Iterator t_list;          // Iterator for list of Terminal Servers
        TerminalConnection temp;  // Temporary TerminalConnection

        System.out.println("yell: The message '"+msg+"' was recieved.");

        t_list = terminal_set.iterator();
        
        while( t_list.hasNext() )
        {
            temp = (TerminalConnection) t_list.next();
            System.out.print("Yell: term: "+temp.getName()+"  ");
            if(temp != null)
            {
                temp.send(msg);
            } // if
        } // while
    } // method yell

    public void command(String cmd)
    {
        /* LOCAL VARIABLES */
        // NONE
        
        System.out.println("command: The given command was '"+cmd+"'.");
    } // method command

    public void addServerListener(ServerListener listener)
    {
        /* LOCAL VARIABLES */
        // NONE
        
        s_listener = listener;
    } // method addServerListener
    
    public void removeServerListener(ServerListener listener)
    {
        /* LOCAL VARIABLES */
        // NONE
        
        if( listener == s_listener)
            s_listener = null;
    } // method removeServerListener
    
    public void status()
    {
        /* LOCAL VARIABLES */
        Iterator t_list;  // Iterator for list of Terminal Servers
    
        System.out.println("Status of Terminal Server:\n"+
                           " -> There are "+terminals.activeCount()+" Terminals that are connected and alive.\n"+
                           " -> There are "+terminal_set.size()+" TerminalConnections in the list.");

        t_list = terminal_set.iterator();
        while( t_list.hasNext() )
        {
            System.out.println("    * "+t_list.next());
        } // while
        
        System.out.println();
    } // method status
    
    public void cleanup()
    {
        TerminalConnection temp;
        Iterator t_list = terminal_set.iterator();
        while( t_list.hasNext() )
        {
            temp = (TerminalConnection) t_list.next();
            if( temp != null && !temp.isAlive() )
                t_list.remove();
        } // while
    } // method cleanup
} // class TerminalServer
