package magic.model.choice;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import magic.data.GeneralConfig;
import magic.exception.UndoClickedException;
import magic.model.IUIGameController;
import magic.model.MagicGame;
import magic.model.MagicPlayer;
import magic.model.MagicSource;
import magic.model.event.MagicEvent;
import magic.model.event.MagicMatchedCostEvent;
public class MagicMayChoice extends MagicChoice {
// translatable UI text (prefix with _S).
private static final String _S1 = "Proceed with \"may\" action?";
private final MagicChoice[] choices;
private final MagicTargetChoice targetChoice;
private final int manaChoiceResultIndex;
private final int targetChoiceResultIndex;
private static MagicChoice satisfied(final MagicMatchedCostEvent cost) {
return new MagicChoice("satisfied") {
@Override
public Collection<Object> getArtificialOptions(final MagicGame game, final MagicEvent event) {
return Collections.singletonList(null);
}
@Override
public Object[] getPlayerChoiceResults(final IUIGameController controller, final MagicGame game, final MagicEvent event) {
return new Object[1];
}
@Override
public boolean hasOptions(final MagicGame game,final MagicPlayer player,final MagicSource source,final boolean hints) {
return cost.getEvent(source).isSatisfied();
}
};
}
public MagicMayChoice(final String description,final MagicMatchedCostEvent cost) {
this(description, satisfied(cost));
}
public MagicMayChoice(final String description,final MagicChoice... aChoices) {
super(description);
int validChoices = 0;
for (final MagicChoice choice : aChoices) {
if (choice.isValid()) {
validChoices++;
}
}
choices = new MagicChoice[validChoices];
int idx = 0;
for (final MagicChoice choice : aChoices) {
if (choice.isValid()) {
choices[idx] = choice;
idx++;
}
}
MagicTargetChoice localTargetChoice = MagicTargetChoice.NONE;
int localManaChoiceResultIndex = -1;
int localTargetChoiceResultIndex = -1;
for (int index=0;index<choices.length;index++) {
final MagicChoice choice=choices[index];
if (choice instanceof MagicTargetChoice) {
localTargetChoice=(MagicTargetChoice)choice;
localTargetChoiceResultIndex=index+1;
} else if (choice instanceof MagicPayManaCostChoice) {
localManaChoiceResultIndex=index+1;
}
}
targetChoice = localTargetChoice;
targetChoiceResultIndex = localTargetChoiceResultIndex;
manaChoiceResultIndex = localManaChoiceResultIndex;
}
public MagicMayChoice(final MagicChoice... choices) {
this(_S1, choices);
}
@Override
public MagicTargetChoice getTargetChoice() {
return targetChoice;
}
@Override
public int getTargetChoiceResultIndex() {
return targetChoiceResultIndex;
}
@Override
public int getManaChoiceResultIndex() {
return manaChoiceResultIndex;
}
@Override
Collection<Object> getArtificialOptions(final MagicGame game, final MagicEvent event) {
throw new UnsupportedOperationException();
}
@Override
public List<Object[]> getArtificialChoiceResults(final MagicGame game, final MagicEvent event) {
final MagicPlayer player = event.getPlayer();
final MagicSource source = event.getSource();
final int nrOfChoices = choices.length;
if (nrOfChoices == 0) {
return NO_OTHER_CHOICE_RESULTS;
}
final int nrOfChoiceResults=nrOfChoices+1;
final Object[] noChoiceResults=new Object[nrOfChoiceResults];
noChoiceResults[0]=NO_CHOICE;
final List<Collection<?>> optionsList=new ArrayList<>(nrOfChoices);
for (int index=0;index<nrOfChoices;index++) {
if (!choices[index].hasOptions(game,player,source,true)) {
return Collections.singletonList(noChoiceResults);
}
optionsList.add(choices[index].getArtificialOptions(game,event));
}
final List<Object[]> choiceResultsList=new ArrayList<>();
final Object[] yesChoiceResults=new Object[nrOfChoiceResults];
yesChoiceResults[0]=YES_CHOICE;
int index=0;
final LinkedList<Iterator<?>> iterators=new LinkedList<>();
iterators.addLast(optionsList.get(0).iterator());
while (index>=0) {
final Iterator<?> iterator=iterators.getLast();
if (iterator.hasNext()) {
index++;
yesChoiceResults[index]=iterator.next(); // Starts from index 1.
if (index<nrOfChoices) {
iterators.addLast(optionsList.get(index).iterator());
} else {
choiceResultsList.add(Arrays.copyOf(yesChoiceResults,nrOfChoiceResults));
index--;
}
} else {
iterators.removeLast();
index--;
}
}
choiceResultsList.add(noChoiceResults);
return choiceResultsList;
}
@Override
public Object[] getPlayerChoiceResults(final IUIGameController controller, final MagicGame game, final MagicEvent event) throws UndoClickedException {
final MagicPlayer player = event.getPlayer();
final MagicSource source = event.getSource();
final Object[] choiceResults=new Object[choices.length+1];
choiceResults[0]=NO_CHOICE;
final boolean hints = GeneralConfig.getInstance().getSmartTarget();
for (final MagicChoice choice : choices) {
if (!choice.hasOptions(game,player,source,hints)) {
return choiceResults;
}
}
controller.disableActionButton(false);
final boolean chosen = controller.getMayChoice(source, getDescription());
if (chosen) {
// Yes is chosen.
choiceResults[0]=YES_CHOICE;
for (int index=0;index<choices.length;index++) {
final Object[] partialChoiceResults=choices[index].getPlayerChoiceResults(controller,game,event);
choiceResults[index+1]=partialChoiceResults[0];
}
}
game.snapshot();
return choiceResults;
}
}