package senseiTests.domainsTest;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

import sensei.util.IntWrapper;

class StateTransferInfoPanel extends JPanel implements PhasePanelUser, TransferInfoPrintable, ActionListener
{
  public StateTransferInfoPanel(StateTransferInfoPanelUser user)
  {
    super(new BorderLayout());
    this.user=user;
    init();
    makeUnvisible();
    wrapper = new IntWrapper();
  }

  public void makeUnvisible()
  {
    ((CardLayout) (statusPanel.getLayout())).last(statusPanel);
    disableFields();
  }

  void showFields()
  {
    ((CardLayout) (statusPanel.getLayout())).first(statusPanel);
  }

  /**
   * Called from the PhasePanel when the output phase changes
   */
  public void phaseChanged(int phase)
  {
    String state = user.phaseChanged(phase);
    if (state!=null)
      transferState.displayIfVisible(state);
  }

  public void showAssumeState(int subgroupId)
  {
  }

  public void showSyncTransferFields(int subgroupId, int coordinator, int inPhase, int outPhase, boolean outPhaseEnded)
  {
    disableFields();
    displaySubgroupId(subgroupId);
    displayTransferMember(coordinator);
    inputPhase.display(inPhase);
    showOutputPhase(outPhase, MAX_NUM_PHASES, outPhaseEnded);
    displayAction("sync_transfer");
    showFields();
  }

  public void showStartTransferFields(int subgroupId, int coordinated, int inPhase, int maxPhases,
    int outPhase, boolean outPhaseEnded)
  {
    disableFields();
    displaySubgroupId(subgroupId);
    displayTransferMember(coordinated);
    inputPhase.display(inPhase);
    showOutputPhase(outPhase, maxPhases, outPhaseEnded);
    displayAction("start_transfer");
    showFields();
  }

  public void showGetStateFields(int subgroupId, int inPhase, int maxPhases, int outPhase, boolean outPhaseEnded)
  {
    disableFields();
    displaySubgroupId(subgroupId);
    inputPhase.display(inPhase);
    showOutputPhase(outPhase, maxPhases, outPhaseEnded);
    displayAction("get_state");
    transferState.makeVisible();
    showFields();
  }

  public void showSetStateFields(int subgroupId, String substate, int inPhase)
  {
    disableFields();
    displaySubgroupId(subgroupId);
    inputPhase.display(inPhase);
    displayAction("set_state");
    transferState.display(substate);
    showFields();
  }

  public void showGetStateFields(int subgroupId)
  {
    disableFields();
    displaySubgroupId(subgroupId);
    displayAction("get_state");
    showFields();
  }

  public void showSetStateFields(int subgroupId, String substate)
  {
    disableFields();
    displaySubgroupId(subgroupId);
    displayAction("set_state");
    transferState.display(substate);
    showFields();
  }

  public void showStopTransferFields(int subgroupId, int member, boolean transferEnded)
  {
    disableFields();
    displaySubgroupId(subgroupId);
    displayTransferMember(member);
    displayTransferFinished(transferEnded);
    displayAction("stop_transfer");
    showFields();
  }

  public void showInterruptTransferFields(int subgroupId, int inPhase, int maxPhases, int outPhase,
    boolean outPhaseEnded)
  {
    disableFields();
    displaySubgroupId(subgroupId);
    inputPhase.display(inPhase);
    showOutputPhase(outPhase, maxPhases, outPhaseEnded);
    displayAction("interrupt_transfer");
    showFields();
  }

  public void showContinueTransferFields(int subgroupId, int member, int inPhase, int maxPhases, int clientPhase,
    int outPhase, boolean outPhaseEnded)
  {
    disableFields();
    displaySubgroupId(subgroupId);
    displayTransferMember(member);
    inputPhase.display(inPhase);
    showOutputPhase(outPhase, maxPhases, outPhaseEnded);
    additionalPhase.display(clientPhase);
    displayAction("continue_transfer");
    showFields();
  }

  void showOutputPhase(int phase, int maxOutPhases, boolean phaseEnded)
  {
    outputPhase.display(phase, maxOutPhases, phaseEnded);
    phaseChanged(phase);
  }

  void displaySubgroupId(int id)
  {
    wrapper.i=id;
    subgroup.display(wrapper.toString());
  }

  void displayTransferFinished(boolean finished)
  {
    status.display(finished? "YES" : "NO");
  }

  void displayStateSent(String stateSent)
  {
    transferState.display(stateSent);
  }

  void displayAction(String actionString)
  {
    action.display(actionString);
  }

  void displayTransferMember(int member)
  {
    transferMember.display(String.valueOf(member));
  }

  void disableFields()
  {
    transferMember.makeUnvisible();
    action.makeUnvisible();
    transferState.makeUnvisible();
    status.makeUnvisible();
    inputPhase.makeUnvisible();
    outputPhase.makeUnvisible();
    additionalPhase.makeUnvisible();
  }

  JPanel createTransferStatusPanel()
  {
    inputPhase = new PhasePanel("Input phase");
    outputPhase = new EditablePhasePanel("Output phase", this);
    additionalPhase = new PhasePanel("Input client phase");
    action = new FieldPanel("action: ", 9);
    transferMember = new FieldPanel("xfer member: ", 7);
    transferState = new FieldPanel("xfer state: ", 6);
    status = new FieldPanel("ended ok: ", 3);
    subgroup = new FieldPanel("subgroup id: ",9);
    confirmButton = new JButton("Confirm");

    confirmButton.addActionListener(this);

    Box boxv = Box.createVerticalBox();
    Box boxh1 = Box.createHorizontalBox();
    Box boxh2 = Box.createHorizontalBox();
    Box boxh3 = Box.createHorizontalBox();

    boxv.add(boxh1);
    boxv.add(Box.createVerticalStrut(5));
    boxv.add(boxh2);
    boxv.add(Box.createVerticalStrut(5));
    boxv.add(boxh3);

    boxh1.add(subgroup);
    boxh1.add(action);
    boxh1.add(confirmButton);

    boxh2.add(transferMember);
    boxh2.add(transferState);
    boxh2.add(status);

    boxh3.add(inputPhase);
    boxh3.add(outputPhase);
    boxh3.add(additionalPhase);

    JPanel ret = new JPanel();
    ret.add(boxv);
    return ret;
  }

  JPanel createEmptyPanel()
  {
    JPanel ret = new JPanel(new BorderLayout());
    ret.add(new JLabel("There is currently no state transfer operation", SwingConstants.CENTER), BorderLayout.CENTER);
    return ret;
  }

  void init()
  {
    JPanel panel = new JPanel(new FlowLayout());
    add(panel, BorderLayout.WEST);
    statusPanel = new JPanel(new CardLayout());
    statusPanel.add(createTransferStatusPanel(),"1");//string not used
    statusPanel.add(createEmptyPanel(),"0");
    panel.add(statusPanel);
    setBorder(BorderFactory.createTitledBorder("State Transfer Info"));
  }

  public void actionPerformed(ActionEvent e)
  {
    if (e.getSource()==confirmButton)
    {
      user.confirmed(outputPhase.getPhase(), outputPhase.getPhaseTermination());
    }
  }

  JPanel statusPanel;
  JButton confirmButton;
  FieldPanel transferMember, action, transferState, status, subgroup;
  PhasePanel inputPhase, additionalPhase;
  EditablePhasePanel outputPhase;

  StateTransferInfoPanelUser user;
  IntWrapper wrapper;
  static public final int MAX_NUM_PHASES=PhasePanel.MAXNUMPHASES;
};