package forge.gui.input;
import forge.*;
import java.util.LinkedList;
import java.util.Stack;
/**
* <p>InputControl class.</p>
*
* @author Forge
* @version $Id: $
*/
public class InputControl extends MyObservable implements java.io.Serializable {
/** Constant <code>serialVersionUID=3955194449319994301L</code> */
private static final long serialVersionUID = 3955194449319994301L;
private Input input;
/** Constant <code>n=0</code> */
static int n = 0;
private Stack<Input> inputStack = new Stack<Input>();
private Stack<Input> resolvingStack = new Stack<Input>();
private LinkedList<Input> resolvingQueue = new LinkedList<Input>();
/**
* <p>Setter for the field <code>input</code>.</p>
*
* @param in a {@link forge.gui.input.Input} object.
*/
public void setInput(final Input in) {
if (AllZone.getStack().getResolving() || !(input == null || input instanceof Input_PassPriority))
inputStack.add(in);
else
input = in;
updateObservers();
}
/**
* <p>Setter for the field <code>input</code>.</p>
*
* @param in a {@link forge.gui.input.Input} object.
* @param bAddToResolving a boolean.
*/
public void setInput(final Input in, boolean bAddToResolving) {
// Make this
if (!bAddToResolving) {
setInput(in);
return;
}
Input old = input;
resolvingStack.add(old);
changeInput(in);
}
/**
* <p>changeInput.</p>
*
* @param in a {@link forge.gui.input.Input} object.
*/
private void changeInput(final Input in) {
input = in;
updateObservers();
}
/**
* <p>Getter for the field <code>input</code>.</p>
*
* @return a {@link forge.gui.input.Input} object.
*/
public Input getInput() {
return input;
}
/**
* <p>clearInput.</p>
*/
public void clearInput() {
input = null;
resolvingQueue.clear();
inputStack.clear();
}
/**
* <p>resetInput.</p>
*/
public void resetInput() {
input = null;
updateObservers();
}
/**
* <p>resetInput.</p>
*
* @param update a boolean.
*/
public void resetInput(boolean update) {
input = null;
if (update)
updateObservers();
}
/**
* <p>updateInput.</p>
*
* @return a {@link forge.gui.input.Input} object.
*/
public Input updateInput() {
final String phase = AllZone.getPhase().getPhase();
final Player playerTurn = AllZone.getPhase().getPlayerTurn();
final Player priority = AllZone.getPhase().getPriorityPlayer();
// TODO: this resolving portion needs more work, but fixes Death Cloud issues
if (resolvingStack.size() > 0) {
if (input != null) {
return input;
}
// if an SA is resolving, only change input for something that is part of the resolving SA
changeInput(resolvingStack.pop());
return input;
}
if (AllZone.getStack().getResolving())
return null;
if (input != null)
return input;
else if (inputStack.size() > 0) { // incoming input to Control
changeInput(inputStack.pop());
return input;
}
if (Phase.getGameBegins() != 0 && AllZone.getPhase().doPhaseEffects()) {
// Handle begin phase stuff, then start back from the top
AllZone.getPhase().handleBeginPhase();
return updateInput();
}
// If the Phase we're in doesn't allow for Priority, return null to move to next phase
if (AllZone.getPhase().isNeedToNextPhase())
return null;
// Special Inputs needed for the following phases:
if (phase.equals(Constant.Phase.Combat_Declare_Attackers)) {
AllZone.getStack().freezeStack();
if (playerTurn.isHuman())
return new Input_Attack();
} else if (phase.equals(Constant.Phase.Combat_Declare_Blockers)) {
AllZone.getStack().freezeStack();
if (playerTurn.isHuman()) {
AllZone.getComputer().getComputer().declare_blockers();
return null;
} else {
if (AllZone.getCombat().getAttackers().length == 0) {
// no active attackers, skip the Blocking phase
AllZone.getPhase().setNeedToNextPhase(true);
return null;
} else
return new Input_Block();
}
} else if (phase.equals(Constant.Phase.Cleanup)) // Player needs to discard
if (AllZone.getStack().size() == 0) // fall through to resolve things like Madness
return new Input_Cleanup();
// *********************
// Special phases handled above, everything else is handled simply by priority
if (priority.isHuman()) {
boolean skip = AllZone.getPhase().doSkipPhase();
AllZone.getPhase().setSkipPhase(false);
if (AllZone.getStack().size() == 0 && !AllZone.getDisplay().stopAtPhase(playerTurn, phase) && skip) {
AllZone.getPhase().passPriority();
return null;
} else
return new Input_PassPriority();
} else if (playerTurn.isComputer())
return AllZone.getComputer();
else {
AllZone.getComputer().getComputer().stack_not_empty();
return null;
}
}//getInput()
}//InputControl