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

/**
 *   Program Calculator
 *
 * <p>
 *   This program provides a simple four function calculator with
 *   two input fields to enter the left and right operands of an
 *   arithmetic operation. 
 *
 */
class Calculator extends Frame implements ActionListener
{

//----------------------------------
//    Data Members
//----------------------------------
    
    /**
     * For entering the left operand
     */
    private TextField   leftOperand;
  
    /**
     * For entering the right operand
     */
    private TextField   rightOperand;

    /**
     * Add operator button
     */
    private Button      plusButton;
   
    /**
     * Subtract operator button
     */
    private Button      minusButton;
   
    /**
     * Mulitplication operation button
     */
    private Button      multiplyButton;
   
    /**
     * Division operation button
     */
    private Button      divideButton;
  
    /**
     * Clear entry button
     */
    private Button      clearButton;

    /**
     * MessageBox for display error mesages
     */
    private MessageBox  errorMessageBox;

//----------------------------------
//    Constructors
//----------------------------------
                                
    /**
     * Default constructor
     */
    public Calculator()
    {
        //set window properties
        super        ( "Calculator");
  
        setSize      ( 200, 150    );
        setResizable ( false       );
        setLayout    ( null        );
        setLocation  ( 300, 200    );
  
        //create and layout components
        initGUIComponents();
  
        addWindowListener( new ProgramTerminator() );
        
        errorMessageBox = new MessageBox(this);

    }



//-------------------------------------------------
//      Public Methods:
// 
//          void    actionPerformed   (   ActionEvent    )
//
//------------------------------------------------
                                    
    /**
     * Performs the specified calculation and display
     * the result.
     *
     * @param event the ActionEvent object
     */
    public void actionPerformed (ActionEvent event)
    {
        Button clickedButton = (Button) event.getSource();
  
        if (clickedButton == clearButton) {
           clearEntries();
        }
        else {
           //an operator button is clicked, so compute
           compute( clickedButton );
        }
    }

//-------------------------------------------------
//      Private Methods:
// 
//        void        clearEntries        (            )
//        void        compute             (  Button    )
// 
//        void        displayResult       (            )
//        void        getNumberFrom       ( TextField  )
//
//        void        initGUIComponents   (            )
//        boolean     isOperandValid      ( TextField  )
//
//------------------------------------------------   
    
   /**
     * Clears the left and right operand TextField objects
     */
    private void clearEntries()
    {
        leftOperand.setText("");
        rightOperand.setText("");
    }
    
    /**
     * Determines which operation is requested and perform
     * the appropriate computation.
     *
     * @param operatorButton one of the operator buttons
     *                       clicked by the user
     */
    private void compute (Button operatorButton)
    {
        float   leftOperandValue,
                rightOperandValue,
                result = 0f;

        //are values in text fields valid numbers?
        if ( isOperandValid(leftOperand) && isOperandValid(rightOperand) ) {
  
           //okay, so get the two operands
           leftOperandValue  = getNumberFrom(leftOperand);
           rightOperandValue = getNumberFrom(rightOperand);
  
           //compute the result
           if ( operatorButton == plusButton ) {
              result = leftOperandValue + rightOperandValue;
           }
           else if ( operatorButton == minusButton ) {
              result = leftOperandValue - rightOperandValue;
           }
           else if ( operatorButton == divideButton ) {
              result = leftOperandValue / rightOperandValue;
           }
           else if ( operatorButton == multiplyButton ) {
              result = leftOperandValue * rightOperandValue;
           }
           
           displayResult(result);
        }
        else  { //invalid operands
           errorMessageBox.show("Error: Invalid Data");
        }
    }

    /**
     * Displays the argument in the left operand TextField
     *
     * @param number the number to display
     */
    private void displayResult(float number)
    {
        leftOperand.setText(Convert.toString(number));
        rightOperand.setText("");
    }

    /**
     * Retrieves the number from one of the operand TextField
     *
     * @param operand the operand to retrieve the entered value
     *
     * @return the value entered in the designated operand field
     */
    private float getNumberFrom(TextField operand)
    {
        return Convert.toFloat(operand.getText());
    }
    
    
    /**
     * Creates and initializes GUI components. Absolute positioning
     * is used.
     */
    private void initGUIComponents( )
    {
        //create buttons
        leftOperand     = new TextField();
        rightOperand    = new TextField();
  
        plusButton      = new Button("+");
        minusButton     = new Button("-");
        multiplyButton  = new Button("X");
        divideButton    = new Button("/");
        clearButton     = new Button("CLEAR");
  
  
        //position buttons
           leftOperand.setBounds ( 20,  40, 75, 25);
          rightOperand.setBounds ( 20,  75, 75, 25);
  
            plusButton.setBounds (110,  40, 30, 30);
           minusButton.setBounds (150,  40, 30, 30);
        multiplyButton.setBounds (110,  75, 30, 30);
          divideButton.setBounds (150,  75, 30, 30);
           clearButton.setBounds (110, 110, 70, 30);
  
        //add this calculator as an action listener
        //to all five buttons
            plusButton.addActionListener( this );
           minusButton.addActionListener( this );
        multiplyButton.addActionListener( this );
          divideButton.addActionListener( this );
           clearButton.addActionListener( this );
  
        //add buttons to the calculator frame
        add(leftOperand);
        add(rightOperand);
  
        add(plusButton);
        add(minusButton);
        add(multiplyButton);
        add(divideButton);
  
        add(clearButton);
    }
    
    /**
     * Determines whether the given number is valid or not
     *
     * @param operand one the operand TextField
     *
     * @return true if valid; else return false
     */
    private boolean isOperandValid(TextField operand)
    {
        boolean status;

          try {
             float number = Convert.toFloat(operand.getText());
             status = true;
          }
          catch (NumberFormatException e) {
             status = false;
          }
    
          return status;
    }

}