import java.net.*;
import java.util.*;
import javax.swing.*;

/**
 * Clase principal del servidor de chat. Inicializa la conexion y crea el frame de la
 * interfaz grafica.
 * @author Luis Fuentes Weber
 *
 */

public class ChatServer extends JFrame{

    private serverPane ClientPane;

    /**
    * Constructor del frame. Setea el titulo e inicializa el panel
    */
    public ChatServer(Vector <clientData> clients){
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        
        setTitle("Chat Server");
        ClientPane = new serverPane(clients);
        add(ClientPane);
        pack();
        setVisible(true);
    }

    /**
    * Obtiene el panel del principal del frame.
    * @return Panel.
    */
    public serverPane getPane(){
        return ClientPane;
    }

     /**
     * Metodo main del servidor. Revisa los argumentos, e inicializa el frame y el socket de eschucha.
     * Posteriormente queda aceptando nuevas conexiones y creando una hebra
     * para cada conexion entrante.
     * @param args Argumentos pasados al programa desde consola.
     */
    public static void main(String args[]){
        Vector <clientData> clients = new Vector <clientData>();
        ChatServer chatServer = new ChatServer(clients);

        int port = 0;
        
        //Revision de argumentos
        if(args.length != 1){
            JOptionPane.showMessageDialog(chatServer, USAGE ,"Error",JOptionPane.ERROR_MESSAGE);
            System.exit(-3);
        } else {
            if ( (port = Integer.parseInt(args[0])) < 1){
                JOptionPane.showMessageDialog(chatServer, USAGE ,"Error",JOptionPane.ERROR_MESSAGE);
                System.exit(-3);
            }
        }


        try{
            int i = 1;
            //Creacion del socket
            ServerSocket s = new ServerSocket(port);

            //Acepta conexiones, crea la hebra y vuelve al estado de esucha.
            for (;;){
                Socket incoming = s.accept( );
                clientData  c = new clientData(incoming);
                //Sincronizado para evitar errores al agregar mientras se envian datos o se eliminan clientes.
                synchronized (clients) {clients.add(c);}
                serverThread t = new serverThread(c, clients, chatServer.getPane());
                t.start();
            }
        }
        catch (Exception e){
            //No se pudo crear el socket.
            JOptionPane.showMessageDialog(chatServer, "Could't create or bind the socket.","Error",JOptionPane.ERROR_MESSAGE);
            System.exit(1);
        }
   }

    private static String USAGE = "Usage:  java ChatServer [port]";

}

