/*PLEASE DO NOT EDIT THIS CODE*/
/*This code was generated using the UMPLE @UMPLE_VERSION@ modeling language!*/

package distributed.rmi.withMethods2;
import java.util.*;
import java.lang.Thread;

// line 3 "../../../Class_DistributableRMI_WithMethods2.ump"
public class MicrowaveImpl extends CCImpl implements java.io.Serializable , IMicrowaveImpl, Runnable
{

  //------------------------
  // STATIC VARIABLES
  //------------------------

  public static final int TimeIncrementMs = 1000;

  //------------------------
  // MEMBER VARIABLES
  //------------------------

  //MicrowaveImpl Attributes
  private boolean lightOn;
  private boolean powerTubeOn;
  private boolean isDoorOpened;
  private boolean isButtonPressed;

  //MicrowaveImpl State Machines
  public enum OperatingMicrowaveStateMachine { readyToCook, doorOpen, cooking, cookingInterrupted, cookingComplete, cookingExtended }
  private OperatingMicrowaveStateMachine operatingMicrowaveStateMachine;
  
  //enumeration type of messages accepted by MicrowaveImpl
  protected enum MessageType { doorOpened_M, buttonPressed_M, doorClosed_M }
  
  MessageQueue queue;
  Thread removal;

  //------------------------
  // CONSTRUCTOR
  //------------------------

  public MicrowaveImpl()
  {
    super();
    lightOn = false;
    powerTubeOn = false;
    isDoorOpened = false;
    isButtonPressed = false;
    setOperatingMicrowaveStateMachine(OperatingMicrowaveStateMachine.readyToCook);
    queue = new MessageQueue();
    removal=new Thread(this);
    //start the thread of MicrowaveImpl
    removal.start();
  }
  //------------------------
  // Reference to the proxy
  //------------------------
  Microwave self;
  
  public void setSelf(Microwave proxy)
  {
    super.setSelf(proxy);
    self=proxy;
  }

  //------------------------
  // Returning the Hashcode
  //------------------------
  public int getHashCode()
  {
    return hashCode();
  }

  //------------------------
  // INTERFACE
  //------------------------

  public boolean setLightOn(boolean aLightOn)
  {
    boolean wasSet = false;
    lightOn = aLightOn;
    wasSet = true;
    return wasSet;
  }

  public boolean setPowerTubeOn(boolean aPowerTubeOn)
  {
    boolean wasSet = false;
    powerTubeOn = aPowerTubeOn;
    wasSet = true;
    return wasSet;
  }

  public boolean setIsDoorOpened(boolean aIsDoorOpened)
  {
    boolean wasSet = false;
    isDoorOpened = aIsDoorOpened;
    wasSet = true;
    return wasSet;
  }

  public boolean setIsButtonPressed(boolean aIsButtonPressed)
  {
    boolean wasSet = false;
    isButtonPressed = aIsButtonPressed;
    wasSet = true;
    return wasSet;
  }

  public boolean getLightOn()
  {
    return lightOn;
  }

  public boolean getPowerTubeOn()
  {
    return powerTubeOn;
  }

  public boolean getIsDoorOpened()
  {
    return isDoorOpened;
  }

  public boolean getIsButtonPressed()
  {
    return isButtonPressed;
  }

  public String getOperatingMicrowaveStateMachineFullName()
  {
    String answer = operatingMicrowaveStateMachine.toString();
    return answer;
  }

  public OperatingMicrowaveStateMachine getOperatingMicrowaveStateMachine()
  {
    return operatingMicrowaveStateMachine;
  }

  public boolean _doorOpened()
  {
    boolean wasEventProcessed = false;
    
    OperatingMicrowaveStateMachine aOperatingMicrowaveStateMachine = operatingMicrowaveStateMachine;
    switch (aOperatingMicrowaveStateMachine)
    {
      case readyToCook:
        // line 16 "../../../Class_DistributableRMI_WithMethods2.ump"
        setIsDoorOpened(true);
        setOperatingMicrowaveStateMachine(OperatingMicrowaveStateMachine.doorOpen);
        wasEventProcessed = true;
        break;
      case cooking:
        // line 38 "../../../Class_DistributableRMI_WithMethods2.ump"
        setIsDoorOpened(true);
        setOperatingMicrowaveStateMachine(OperatingMicrowaveStateMachine.cookingInterrupted);
        wasEventProcessed = true;
        break;
      case cookingComplete:
        // line 49 "../../../Class_DistributableRMI_WithMethods2.ump"
        setIsDoorOpened(true);
        setOperatingMicrowaveStateMachine(OperatingMicrowaveStateMachine.doorOpen);
        wasEventProcessed = true;
        break;
      case cookingExtended:
        // line 58 "../../../Class_DistributableRMI_WithMethods2.ump"
        setIsDoorOpened(true);
        setOperatingMicrowaveStateMachine(OperatingMicrowaveStateMachine.cookingInterrupted);
        wasEventProcessed = true;
        break;
      default:
        // Other states do respond to this event
    }

    return wasEventProcessed;
  }

  public boolean _buttonPressed()
  {
    boolean wasEventProcessed = false;
    
    OperatingMicrowaveStateMachine aOperatingMicrowaveStateMachine = operatingMicrowaveStateMachine;
    switch (aOperatingMicrowaveStateMachine)
    {
      case readyToCook:
        // line 17 "../../../Class_DistributableRMI_WithMethods2.ump"
        setIsButtonPressed(true);
        setOperatingMicrowaveStateMachine(OperatingMicrowaveStateMachine.cooking);
        wasEventProcessed = true;
        break;
      case cooking:
        // line 39 "../../../Class_DistributableRMI_WithMethods2.ump"
        setIsButtonPressed(true);
        setOperatingMicrowaveStateMachine(OperatingMicrowaveStateMachine.cookingExtended);
        wasEventProcessed = true;
        break;
      case cookingComplete:
        // line 50 "../../../Class_DistributableRMI_WithMethods2.ump"
        setIsButtonPressed(true);
        setOperatingMicrowaveStateMachine(OperatingMicrowaveStateMachine.cooking);
        wasEventProcessed = true;
        break;
      case cookingExtended:
        // line 59 "../../../Class_DistributableRMI_WithMethods2.ump"
        setIsButtonPressed(true);
        setOperatingMicrowaveStateMachine(OperatingMicrowaveStateMachine.cookingExtended);
        wasEventProcessed = true;
        break;
      default:
        // Other states do respond to this event
    }

    return wasEventProcessed;
  }

  public boolean _doorClosed()
  {
    boolean wasEventProcessed = false;
    
    OperatingMicrowaveStateMachine aOperatingMicrowaveStateMachine = operatingMicrowaveStateMachine;
    switch (aOperatingMicrowaveStateMachine)
    {
      case doorOpen:
        // line 25 "../../../Class_DistributableRMI_WithMethods2.ump"
        setIsDoorOpened(false);
        setOperatingMicrowaveStateMachine(OperatingMicrowaveStateMachine.readyToCook);
        wasEventProcessed = true;
        break;
      case cookingInterrupted:
        // line 44 "../../../Class_DistributableRMI_WithMethods2.ump"
        setIsDoorOpened(false);
        setOperatingMicrowaveStateMachine(OperatingMicrowaveStateMachine.readyToCook);
        wasEventProcessed = true;
        break;
      default:
        // Other states do respond to this event
    }

    return wasEventProcessed;
  }

  private void setOperatingMicrowaveStateMachine(OperatingMicrowaveStateMachine aOperatingMicrowaveStateMachine)
  {
    operatingMicrowaveStateMachine = aOperatingMicrowaveStateMachine;

    // entry actions and do activities
    switch(operatingMicrowaveStateMachine)
    {
      case readyToCook:
        // line 12 "../../../Class_DistributableRMI_WithMethods2.ump"
        // turn off light
        turnOff();
        break;
      case doorOpen:
        // line 21 "../../../Class_DistributableRMI_WithMethods2.ump"
        // turn on light
        turnLightOn(true);
        break;
      case cooking:
        // line 29 "../../../Class_DistributableRMI_WithMethods2.ump"
        // turn on light
        turnLightOn(true);
        // energize power tube
        energizePowerTube(true);
        //release a button
        setIsButtonPressed(false);
        break;
      case cookingInterrupted:
        // line 43 "../../../Class_DistributableRMI_WithMethods2.ump"
        turnOff();
        break;
      case cookingComplete:
        // line 48 "../../../Class_DistributableRMI_WithMethods2.ump"
        turnOff();
        break;
      case cookingExtended:
        // line 54 "../../../Class_DistributableRMI_WithMethods2.ump"
        //release a button
        setIsButtonPressed(false);
        break;
    }
  }

  public void delete()
  {
    removal.interrupt();
    super.delete();
  }

  protected class Message
  {
    MessageType type;
    
    //Message parameters
    Vector<Object> param;
    
    public Message(MessageType t, Vector<Object> p)
    {
      type = t; 
      param = p;
    }

    @Override
    public String toString()
    {
      return type + "," + param;
    }
  }
  
  protected class MessageQueue {
    Queue<Message> messages = new LinkedList<Message>();
    
    public synchronized void put(Message m)
    {
      messages.add(m); 
      notify();
    }

    public synchronized Message getNext()
    {
      try {
        while (messages.isEmpty()) 
        {
          wait();
        }
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        return null;
      }

      //The element to be removed
      Message m = messages.remove(); 
      return (m);
    }
  }

  //------------------------------
  //messages accepted 
  //------------------------------

  public void doorOpened ()
  {
    queue.put(new Message(MessageType.doorOpened_M, null));
  }

  public void buttonPressed ()
  {
    queue.put(new Message(MessageType.buttonPressed_M, null));
  }

  public void doorClosed ()
  {
    queue.put(new Message(MessageType.doorClosed_M, null));
  }

  
  @Override
  public void run ()
  {
    boolean status=false;
    while (true) 
    {
      Message m = queue.getNext();
      if(m == null)  return;
      
      switch (m.type)
      {
        case doorOpened_M:
          status = _doorOpened();
          break;
        case buttonPressed_M:
          status = _buttonPressed();
          break;
        case doorClosed_M:
          status = _doorClosed();
          break; 
        default:
      }
      if(!status)
      {
        // Error message is written or  exception is raised
      }
    }
  }

  /**
   * turn on light
   */
  // line 66 "../../../Class_DistributableRMI_WithMethods2.ump"
   public void turnLightOn(boolean on){
    System.out.println("turns the light "+ (on ? "on" : "off"));
    System.out.println("light " + (on ? "on" : "off"));
    setLightOn(on);
  }

  // line 72 "../../../Class_DistributableRMI_WithMethods2.ump"
   public static  void someMethod(){
    
  }


  public String toString()
  {
    return super.toString() + "["+
            "lightOn" + ":" + getLightOn()+ "," +
            "powerTubeOn" + ":" + getPowerTubeOn()+ "," +
            "isDoorOpened" + ":" + getIsDoorOpened()+ "," +
            "isButtonPressed" + ":" + getIsButtonPressed()+ "]";
  }
}