/****************************************************************************
* Elevator control (alpha version)                                          *
* The graphical user interface of the IndiGolog elevator control.           *
* Written by Ho Ng, March 2000                                              *
****************************************************************************/

import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.*;


/****************************************************************************
* Class ElevatorGUI                                                         *
* It contains the objects of Connector and ElevatorGUIFrame. It analyzes    *
* commands from the user and the IndiGolog control, and then performs the   *
* corresponding reactions.                                                  *
****************************************************************************/
public class ElevatorGUI extends Thread
{
    private int[] bstate = new int[7];

    private Connector        connector;
    private ElevatorGUIFrame frame;


    /**
    * It blocks the execution of the thread for the input time
    */
    private void longWait(int time)
    {
        try
        {
            sleep((long)time);
        }
        catch (InterruptedException e)
        {
        }
    }

    /**
    * It resets the internal states of the elevator. The elevator is
    * initially at 6th floor and all floor buttons are off
    */
    private void reset()
    {
        frame.moveLight(6);

        for (int i = 1; i <= 6; i++)
        {
            bstate[i] = 0;
            frame.turnOffButton(i);
        }
    }

    /**
    * It returns a string vector of which indicates the status of the
    * floor buttons. e.g. [0,1,0,0,1,0] means that the buttons for floor 2
    * and 5 are on
    */
    private String getButtonStates()
    {
        String str = "[";

        for (int i = 1; i <= 6; i++)
        {
            str = str + bstate[i];

            if (i < 6)
                str = str + ",";
        }
        str = str + "]";

        return str;
    }

    /**
    * Constructor of class ElevatorGUI
    */
    public ElevatorGUI(String name, String host, int port)
    {
        frame     = new ElevatorGUIFrame(name, this);
        connector = new Connector(name, host, port);
    }

    /**
    * It analyzes the input button event and performs the corresponding
    * reaction
    */
    public void handleButtonEvent(String button)
    {
        /* if one of the buttons has been clicked */
        if ((button.length() > 1) && (button.charAt(0) == 'b'))
        {
            int i = Character.digit(button.charAt(1),Character.MAX_RADIX);

            /* floor buttons (button[1-6]) */
            if ((i >= 1) && (i <= 6) && (bstate[i] == 0))
            {
                bstate[i] = 1;
                frame.turnOnButton(i);
            }
 
            /* connection button (button[0]) */
            else if (i == 0)
            {
                if (connector.connectedToIndi() == false)
                {
                    /* connect to IndiGolog control */
                    System.out.println("Connecting to server...");
                    connector.connectToIndi();
                    if (connector.connectedToIndi() == true)
                    {
                        bstate[0] = 1;
                        frame.turnOnButton(0);
                        frame.setButtonText(0, "Quit");
                        reset();
                        start();
                        System.out.println("Connected to server");
                    }
                }
                else // connector.connectedToIndi() == true
                {
                    /* disconnect from IndiGolog control */
                    System.out.println("Disconnecting from server...");
                    connector.disconnectFromIndi();
                    System.exit(0);
                }
            }
        }
    }

    /**
    * It analyzes the input message and performs the corresponding reaction
    */
    public void handleInputMessage(String message)
    {
        if (message == null)
            return;

        if (message.equals("look") == true)
        {
            connector.sendMessage(getButtonStates());
        }
        else if (message.equals("up") == true)
	{
	    longWait(400);    // wait for a while
            frame.moveLight(frame.lightOnPosition() + 1);
	}
        else if (message.equals("down") == true)
	{
            longWait(400);    // wait for a while
            frame.moveLight(frame.lightOnPosition() - 1);
	}
        else if (message.charAt(0) == 'o')    // off(N)
        {
            int i = Character.digit(message.charAt(4),Character.MAX_RADIX);
	    longWait(300);    // wait for a while

	    bstate[i] = 0;
            frame.turnOffButton(i);
        }
        else if (message.equals("reset") == true)
        {
            reset();
        }
    }

    /**
    * It is a thread for receiving messages from the IndiGolog control during
    * the execution of the whole application
    */
    public void run()
    {
        String message;

        while (connector.connectedToIndi() == true)
        {
	    /* try to get the next message */
            message = connector.receiveMessage();
            handleInputMessage(message);

            /* wait for a while before accepting the next message */
            longWait(30);
        }
    }

    /**
    * Main function of the graphical user interface
    */
    public static void main(String[] s)
    {
        ElevatorGUI ctrl = new ElevatorGUI("gui", s[0],
                                           Integer.valueOf(s[1]).intValue());
    }
}
