import java.awt.*;
import java.awt.event.*;
 
 /**
 * CSC 442F:    Software Engineering
 * Software:    Calendar Client
 * Component:   DurationPanel class
 * Description: The DurationPanel class produces an duration panel. This panel
 *              accepts date input from the user. It also enforces type
 *              restrictions.
 *
 * @author David Tam
 * @version 1.0
 */
public class DurationPanel extends Panel implements TextListener
{ 
  protected EventId eventId;
  protected Frame frame;
  protected boolean restrict;

  // Text input areas
  protected Label colon;

  // Text input areas
  public TextField hour;
  public TextField min;

  // GridBagLayout constraints
  protected GridBagConstraints constraints;

 /**
  * Constructor 1 -- Create panel with specific values
  * =============
  *
  * @param frame_in          Used to create error message dialogs.
  * @param eventId_in        Used to set specific values for temporal fields.
  */
  public DurationPanel (Frame frame_in, EventId eventId_in)
  {
    eventId = eventId_in;
    basicInit(frame_in);
    fillSpecific();
    arrange();
  }
  

 /**
  * Constructor 2 -- Create panel with empty values
  * =============
  *
  * @param frame_in          Used to create error message dialogs.
  */
  public DurationPanel (Frame frame_in)
  {
    basicInit(frame_in);
    arrange();
  }
  
  
 /**
  * Method to perform basic initialization
  * ======================================
  *
  * @param frame_in          Used to create error message dialogs.
  */
  protected void basicInit(Frame frame_in)
  {
    frame = frame_in;
    restrict = false;
  
    // Label instantiation
    colon = new Label(":", Label.CENTER);

    // Text input instantiation
    hour = new TextField(2);
    min = new TextField(2);

    // Constraints instantiation
    constraints = new GridBagConstraints();   

    // Text event receivers
    hour.addTextListener(this);
    min.addTextListener(this);
  }
      
    
 /**
  * Function that enters specific values into fields
  * ================================================
  * Since no error checking is performed in the time values
  * errors could potentially appear 
  */
  protected void fillSpecific()
  {
    // Fill hour field
    if (eventId.hour.length()!=0)
      hour.setText(eventId.hour);
    
    // Fill minute field
    if (eventId.minute.length()!=0)
      min.setText(eventId.minute);
  }


 /**
  * Function that does layout of panel
  * ==================================
  */
  protected void arrange()
  {
    setLayout(new GridBagLayout());
    constraints.anchor=constraints.WEST;
    constraints.gridx=0;
    constraints.gridy=0;
    add(hour, constraints);
    constraints.gridx=1;
    add(colon, constraints);
    constraints.gridx=2;
    add(min, constraints);
  }
   
   
 /**
  * Method to toggle input fields between editable and noneditable
  * ==============================================================
  *
  * @param value   A boolean value that set field to editable or noneditable
  */
  public void setEditable(boolean value)
  {
    hour.setEditable(value);
    min.setEditable(value);
  }
  
  
 /**
  * Method to handle TextField events
  * =================================
  */
  public void textValueChanged(TextEvent event)
  {
    // Local variables
    TextField textField;
    String stringIn;
      
    // Determine who caused the event
    textField = (TextField) event.getSource();

    // Need to disable TextListener to prevent infinite loop
    textField.removeTextListener(this);
  
    stringIn = textField.getText();

    // Restrict input to length of two
    if (stringIn.length() > 2)
      textField.setText(stringIn.substring(2,3));

    // Restrict input to integers
    stringIn = textField.getText();
    if (stringIn.length() == 1)
    {
      if (stringIn.charAt(0) < '0' || stringIn.charAt(0) > '9')
        textField.setText("");
      // If hour field, and flag set, restrict to min of 1
      else if (textField == hour && Integer.parseInt(stringIn) < 1 &&
               restrict==true)
        textField.setText("1");
  
    }
    else if (stringIn.length() == 2)
    {
      // Restrict to integers first, ignoring max range
      if (stringIn.charAt(0) < '0' || stringIn.charAt(0) > '9')
        textField.setText("");
      else if (stringIn.charAt(1) < '0' || stringIn.charAt(1) > '9')
        textField.setText("");
      // If all digits are integer, then check ranges
      else
      {
        // If hour field, and flag set, restrict to max of 12
        if (textField == hour && Integer.parseInt(stringIn) > 12 &&
            restrict==true)
          textField.setText("12");
        // Else if minute field, restrict to max of 59
        else if (textField == min && Integer.parseInt(stringIn) > 59)
          textField.setText("59");
      }
    }

    // Restore TextListener
    textField.addTextListener(this);
  }


 /**
  * Method to send duration back to calling function
  * ================================================
  * 
  * @return   Returns a String in the form of the protocol.
  *           Returns total minutes
  */
  public String buildResponse()
  {
    // Local variables
    MsgBox msgbox;
    String result;
    int hour_out;
    int min_out;
    
    // Error check hour field
    if (hour.getText().length()!=0)
      hour_out = Integer.parseInt(hour.getText());
    else
      hour_out = 0;
    
    // Error check minute field  
    if (min.getText().length()!=0)
      min_out = Integer.parseInt(min.getText());
    else
      min_out = 0;

    // Make sure all fields have values
    if (hour_out != 0  ||  min_out != 0)
    {
      result = String.valueOf(min_out + (hour_out * 60));
      result = result.concat(",");
    }
    // Else there is at least one field without a value
    else
    {
      msgbox = new MsgBox(frame, "Error -- Invalid Duration",
     "The DURATION of the meeting is inappropriate. Please fix the appropriate fields.",850,150);
      msgbox.setVisible(true);
      result = "";
    }
    
    return result;
  }

}
