package senseiTests.domainsTest;

class Answerer implements StateTransferInfoPanelUser, StateTransferAnswerer
{
  public Answerer(int delay)
  {
    answer = new PhaseAnswer();
    ui=null;
    current=null;
    output=null;
    this.delay=delay;
  }

  public void setListener(TransferInfoPrintable output)
  {
    this.output=output;
  }

  public synchronized void setAutomatic()
  {
    ui=null;
  }

  public synchronized void setAutomaticDelay(int newDelay)
  {
    delay=newDelay;
  }

  public synchronized int getAutomaticDelay()
  {
    return delay;
  }

  public synchronized void doDelay()
  {
    try{Thread.currentThread().sleep(delay);}catch(InterruptedException ex){}
  }

  public synchronized void setManual(StateTransferInfoPanel ui)
  {
    this.ui=ui;
  }

  /**
   * called when the confirm button is pressed. Cannot be called after makeUnvisible()
   */
  public synchronized void confirmed(int phase, boolean finished)
  {
    answer.set(phase,finished);
    notifyAll();
    ui.makeUnvisible();
  }

  /**
   * Informs that the phase has changed. The associated substring should be returned, or null if it's not valid
   * or displayable
   */
  public String phaseChanged(int phase)
  {
    return current==null? null : current.getColour(phase);
  }

  public void onAssumeState(ColoursSubgroup subgroup)
  {
    if (output!=null)
      output.showAssumeState(subgroup.getId());
  }

  //shows the current sync_transfer process, requesting the new phase coordination
  public synchronized PhaseAnswer onSyncTranfer(ColoursSubgroup subgroup, int coordinator, int phase)
  {
    current=subgroup;
    if (output!=null)
      output.showSyncTransferFields(subgroup.getId(), coordinator, phase, phase, false);
    if (ui==null)
    {
      answer.set(phase,false);
      doDelay();
    }
    else
    {
      ui.showSyncTransferFields(subgroup.getId(), coordinator, phase, phase, false);
      try{wait();}catch(InterruptedException ex){}
    }
    current=null;
    return answer;
  }

  //shows the current interrupt_transfer process, requesting the new phase coordination
  public synchronized PhaseAnswer onInterruptTransfer(ColoursSubgroup subgroup, int phase)
  {
    current=subgroup;
    if (output!=null)
      output.showInterruptTransferFields(subgroup.getId(), phase, MAX_NUM_PHASES, phase, false);
    if (ui==null)
    {
      answer.set(phase,false);
      doDelay();
    }
    else
    {
      ui.showInterruptTransferFields(subgroup.getId(), phase, MAX_NUM_PHASES, phase, false);
      try{wait();}catch(InterruptedException ex){}
    }
    current=null;
    return answer;
  }

  //shows the current continue_transfer process, requesting the new phase coordination
  public synchronized PhaseAnswer onContinueTransfer(ColoursSubgroup subgroup, int joiningMember, int phase, int joiningPhase, int maxPhases)
  {
    current=subgroup;
    if (output!=null)
      output.showContinueTransferFields(subgroup.getId(), joiningMember, phase, maxPhases, joiningPhase, phase, maxPhases==0);
    if (ui==null)
    {
      answer.set(0,maxPhases==0);
      doDelay();
    }
    else
    {
      ui.showContinueTransferFields(subgroup.getId(), joiningMember, phase, maxPhases, joiningPhase, phase, maxPhases==0);
      try{wait();}catch(InterruptedException ex){}
    }
    current=null;
    return answer;
  }

  //shows the current start_transfer process, requesting the new phase coordination
  public synchronized PhaseAnswer onStartTransfer(ColoursSubgroup subgroup, int joiningMember, int phase, int maxPhases)
  {
    current=subgroup;
    if (output!=null)
      output.showStartTransferFields(subgroup.getId(), joiningMember, phase, maxPhases, phase, maxPhases==0);
    if (ui==null)
    {
      answer.set(0,maxPhases==0);
      doDelay();
    }
    else
    {
      ui.showStartTransferFields(subgroup.getId(), joiningMember, phase, maxPhases, phase, maxPhases==0);
      try{wait();}catch(InterruptedException ex){}
    }
    current=null;
    return answer;
  }

  //shows the current get_state process, requesting the new phase coordination and the state
  public synchronized PhaseAnswer onGetState(ColoursSubgroup subgroup, int phase, int maxPhases)
  {
    current=subgroup;
    boolean finished=(phase+1)>=maxPhases;
    if (output!=null)
      output.showGetStateFields(subgroup.getId(), phase, maxPhases, phase, finished);
    if (ui==null)
    {
      answer.set(phase,finished);
      doDelay();
    }
    else
    {
      ui.showGetStateFields(subgroup.getId(), phase, maxPhases, phase, finished);
      try{wait();}catch(InterruptedException ex){}
    }
    current=null;
    return answer;
  }

  //shows the current set_state process
  public synchronized void onSetState(ColoursSubgroup subgroup, String subState, int phase)
  {
    current=subgroup;
    if (output!=null)
      output.showSetStateFields(subgroup.getId(), subState, phase);
    if (ui==null)
      doDelay();
    else
    {
      ui.showSetStateFields(subgroup.getId(), subState, phase);
      try{wait();}catch(InterruptedException ex){}
    }
    current=null;
  }

  //shows the current stop_transfer process
  public synchronized void onStopTransfer(ColoursSubgroup subgroup, int joiningMember, boolean transferFinished)
  {
    current=subgroup;
    if (output!=null)
      output.showStopTransferFields(subgroup.getId(), joiningMember, transferFinished);
    if (ui==null)
      doDelay();
    else
    {
      ui.showStopTransferFields(subgroup.getId(), joiningMember, transferFinished);
      try{wait();}catch(InterruptedException ex){}
    }
    current=null;
  }

  //shows the current get_state process, on a one-step process
  public synchronized void onGetState(ColoursSubgroup subgroup)
  {
    current=subgroup;
    if (output!=null)
      output.showGetStateFields(subgroup.getId());
    if (ui==null)
    {
      doDelay();
    }
    else
    {
      ui.showGetStateFields(subgroup.getId());
      try{wait();}catch(InterruptedException ex){}
    }
    current=null;
  }

  //shows the current set_state process, on a one-step process
  public synchronized void onSetState(ColoursSubgroup subgroup, String subState)
  {
    current=subgroup;
    if (output!=null)
      output.showSetStateFields(subgroup.getId(), subState);
    if (ui==null)
      doDelay();
    else
    {
      ui.showSetStateFields(subgroup.getId(), subState);
      try{wait();}catch(InterruptedException ex){}
    }
    current=null;
  }

  int delay;
  PhaseAnswer answer;
  StateTransferInfoPanel ui;
  ColoursSubgroup current;
  TransferInfoPrintable output;
}