package forge.card.abilityFactory;
import forge.*;
import forge.card.spellability.*;
import forge.gui.GuiUtils;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
/**
* <p>AbilityFactory_Choose class.</p>
*
* @author Forge
* @version $Id: $
*/
public class AbilityFactory_Choose {
// *************************************************************************
// ************************* ChooseType ************************************
// *************************************************************************
/**
* <p>createAbilityChooseType.</p>
*
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
* @return a {@link forge.card.spellability.SpellAbility} object.
*/
public static SpellAbility createAbilityChooseType(final AbilityFactory af) {
final SpellAbility abChooseType = new Ability_Activated(af.getHostCard(), af.getAbCost(), af.getAbTgt()) {
private static final long serialVersionUID = -7734286034988741837L;
@Override
public String getStackDescription() {
return chooseTypeStackDescription(af, this);
}
@Override
public boolean canPlayAI() {
return chooseTypeCanPlayAI(af, this);
}
@Override
public void resolve() {
chooseTypeResolve(af, this);
}
@Override
public boolean doTrigger(boolean mandatory) {
return chooseTypeTriggerAI(af, this, mandatory);
}
};
return abChooseType;
}
/**
* <p>createSpellChooseType.</p>
*
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
* @return a {@link forge.card.spellability.SpellAbility} object.
*/
public static SpellAbility createSpellChooseType(final AbilityFactory af) {
final SpellAbility spChooseType = new Spell(af.getHostCard(), af.getAbCost(), af.getAbTgt()) {
private static final long serialVersionUID = 3395765985146644736L;
@Override
public String getStackDescription() {
return chooseTypeStackDescription(af, this);
}
@Override
public boolean canPlayAI() {
return chooseTypeCanPlayAI(af, this);
}
@Override
public void resolve() {
chooseTypeResolve(af, this);
}
};
return spChooseType;
}
/**
* <p>createDrawbackChooseType.</p>
*
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
* @return a {@link forge.card.spellability.SpellAbility} object.
*/
public static SpellAbility createDrawbackChooseType(final AbilityFactory af) {
final SpellAbility dbChooseType = new Ability_Sub(af.getHostCard(), af.getAbTgt()) {
private static final long serialVersionUID = 5555184803257696143L;
@Override
public String getStackDescription() {
return chooseTypeStackDescription(af, this);
}
@Override
public void resolve() {
chooseTypeResolve(af, this);
}
@Override
public boolean chkAI_Drawback() {
return true;
}
@Override
public boolean doTrigger(boolean mandatory) {
return chooseTypeTriggerAI(af, this, mandatory);
}
};
return dbChooseType;
}
/**
* <p>chooseTypeStackDescription.</p>
*
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
* @param sa a {@link forge.card.spellability.SpellAbility} object.
* @return a {@link java.lang.String} object.
*/
private static String chooseTypeStackDescription(AbilityFactory af, SpellAbility sa) {
HashMap<String, String> params = af.getMapParams();
StringBuilder sb = new StringBuilder();
if (!(sa instanceof Ability_Sub))
sb.append(sa.getSourceCard()).append(" - ");
else
sb.append(" ");
ArrayList<Player> tgtPlayers;
Target tgt = af.getAbTgt();
if (tgt != null)
tgtPlayers = tgt.getTargetPlayers();
else
tgtPlayers = AbilityFactory.getDefinedPlayers(sa.getSourceCard(), params.get("Defined"), sa);
for (Player p : tgtPlayers) {
sb.append(p).append(" ");
}
sb.append("chooses a type.");
Ability_Sub abSub = sa.getSubAbility();
if (abSub != null) {
sb.append(abSub.getStackDescription());
}
return sb.toString();
}
/**
* <p>chooseTypeCanPlayAI.</p>
*
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
* @param sa a {@link forge.card.spellability.SpellAbility} object.
* @return a boolean.
*/
private static boolean chooseTypeCanPlayAI(final AbilityFactory af, final SpellAbility sa) {
return chooseTypeTriggerAI(af, sa, false);
}
/**
* <p>chooseTypeTriggerAI.</p>
*
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
* @param sa a {@link forge.card.spellability.SpellAbility} object.
* @param mandatory a boolean.
* @return a boolean.
*/
private static boolean chooseTypeTriggerAI(final AbilityFactory af, final SpellAbility sa, boolean mandatory) {
if (!ComputerUtil.canPayCost(sa))
return false;
Target tgt = sa.getTarget();
if (sa.getTarget() != null) {
tgt.resetTargets();
sa.getTarget().addTarget(AllZone.getComputerPlayer());
} else {
ArrayList<Player> tgtPlayers = AbilityFactory.getDefinedPlayers(sa.getSourceCard(), af.getMapParams().get("Defined"), sa);
for (Player p : tgtPlayers)
if (p.isHuman() && !mandatory)
return false;
}
return true;
}
/**
* <p>chooseTypeResolve.</p>
*
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
* @param sa a {@link forge.card.spellability.SpellAbility} object.
*/
private static void chooseTypeResolve(final AbilityFactory af, final SpellAbility sa) {
HashMap<String, String> params = af.getMapParams();
Card card = af.getHostCard();
String type = params.get("Type");
ArrayList<String> invalidTypes = new ArrayList<String>();
if (params.containsKey("InvalidTypes")) {
invalidTypes.addAll(Arrays.asList(params.get("InvalidTypes").split(",")));
}
ArrayList<Player> tgtPlayers;
Target tgt = af.getAbTgt();
if (tgt != null)
tgtPlayers = tgt.getTargetPlayers();
else
tgtPlayers = AbilityFactory.getDefinedPlayers(sa.getSourceCard(), params.get("Defined"), sa);
for (Player p : tgtPlayers) {
if (tgt == null || p.canTarget(af.getHostCard())) {
if (type.equals("Card")) {
boolean valid = false;
while (!valid) {
if (sa.getActivatingPlayer().isHuman()) {
Object o = GuiUtils.getChoice("Choose a card type", CardUtil.getCardTypes().toArray());
if (null == o) return;
String choice = (String) o;
if (CardUtil.isACardType(choice) && !invalidTypes.contains(choice)) {
valid = true;
card.setChosenType(choice);
}
} else {
//TODO
//computer will need to choose a type
//based on whether it needs a creature or land, otherwise, lib search for most common type left
//then, reveal chosenType to Human
}
}
} else if (type.equals("Creature")) {
String chosenType = "";
boolean valid = false;
while (!valid) {
if (sa.getActivatingPlayer().isHuman()) {
chosenType = JOptionPane.showInputDialog(null, "Choose a creature type:", card.getName(),
JOptionPane.QUESTION_MESSAGE);
} else {
//not implemented for AI
}
if (CardUtil.isACreatureType(chosenType) && !invalidTypes.contains(chosenType)) {
valid = true;
card.setChosenType(chosenType);
}
}
}
}
}
}
// *************************************************************************
// ************************* ChooseColor ***********************************
// *************************************************************************
/**
* <p>createAbilityChooseColor.</p>
*
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
* @return a {@link forge.card.spellability.SpellAbility} object.
* @since 1.0.15
*/
public static SpellAbility createAbilityChooseColor(final AbilityFactory af) {
final SpellAbility abChooseColor = new Ability_Activated(af.getHostCard(), af.getAbCost(), af.getAbTgt()) {
private static final long serialVersionUID = 7069068165774633355L;
@Override
public String getStackDescription() {
return chooseColorStackDescription(af, this);
}
@Override
public boolean canPlayAI() {
return chooseColorCanPlayAI(af, this);
}
@Override
public void resolve() {
chooseColorResolve(af, this);
}
@Override
public boolean doTrigger(boolean mandatory) {
return chooseColorTriggerAI(af, this, mandatory);
}
};
return abChooseColor;
}
/**
* <p>createSpellChooseColor.</p>
*
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
* @return a {@link forge.card.spellability.SpellAbility} object.
* @since 1.0.15
*/
public static SpellAbility createSpellChooseColor(final AbilityFactory af) {
final SpellAbility spChooseColor = new Spell(af.getHostCard(), af.getAbCost(), af.getAbTgt()) {
private static final long serialVersionUID = -5627273779759130247L;
@Override
public String getStackDescription() {
return chooseColorStackDescription(af, this);
}
@Override
public boolean canPlayAI() {
return chooseColorCanPlayAI(af, this);
}
@Override
public void resolve() {
chooseColorResolve(af, this);
}
};
return spChooseColor;
}
/**
* <p>createDrawbackChooseColor.</p>
*
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
* @return a {@link forge.card.spellability.SpellAbility} object.
* @since 1.0.15
*/
public static SpellAbility createDrawbackChooseColor(final AbilityFactory af) {
final SpellAbility dbChooseColor = new Ability_Sub(af.getHostCard(), af.getAbTgt()) {
private static final long serialVersionUID = 6969618586164278998L;
@Override
public String getStackDescription() {
return chooseColorStackDescription(af, this);
}
@Override
public void resolve() {
chooseColorResolve(af, this);
}
@Override
public boolean chkAI_Drawback() {
return true;
}
@Override
public boolean doTrigger(boolean mandatory) {
return chooseColorTriggerAI(af, this, mandatory);
}
};
return dbChooseColor;
}
/**
* <p>chooseColorStackDescription.</p>
*
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
* @param sa a {@link forge.card.spellability.SpellAbility} object.
* @return a {@link java.lang.String} object.
*/
private static String chooseColorStackDescription(AbilityFactory af, SpellAbility sa) {
StringBuilder sb = new StringBuilder();
if (!(sa instanceof Ability_Sub))
sb.append(sa.getSourceCard()).append(" - ");
else
sb.append(" ");
ArrayList<Player> tgtPlayers;
Target tgt = af.getAbTgt();
if (tgt != null)
tgtPlayers = tgt.getTargetPlayers();
else
tgtPlayers = AbilityFactory.getDefinedPlayers(sa.getSourceCard(), af.getMapParams().get("Defined"), sa);
for (Player p : tgtPlayers) {
sb.append(p).append(" ");
}
sb.append("chooses a color.");
Ability_Sub abSub = sa.getSubAbility();
if (abSub != null) {
sb.append(abSub.getStackDescription());
}
return sb.toString();
}
/**
* <p>chooseColorCanPlayAI.</p>
*
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
* @param sa a {@link forge.card.spellability.SpellAbility} object.
* @return a boolean.
*/
private static boolean chooseColorCanPlayAI(final AbilityFactory af, final SpellAbility sa) {
return chooseColorTriggerAI(af, sa, false);
}
/**
* <p>chooseColorTriggerAI.</p>
*
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
* @param sa a {@link forge.card.spellability.SpellAbility} object.
* @param mandatory a boolean.
* @return a boolean.
*/
private static boolean chooseColorTriggerAI(final AbilityFactory af, final SpellAbility sa, boolean mandatory) {
if (!ComputerUtil.canPayCost(sa))
return false;
Target tgt = sa.getTarget();
if (sa.getTarget() != null) {
tgt.resetTargets();
sa.getTarget().addTarget(AllZone.getComputerPlayer());
} else {
ArrayList<Player> tgtPlayers = AbilityFactory.getDefinedPlayers(sa.getSourceCard(), af.getMapParams().get("Defined"), sa);
for (Player p : tgtPlayers)
if (p.isHuman() && !mandatory)
return false;
}
return true;
}
/**
* <p>chooseColorResolve.</p>
*
* @param af a {@link forge.card.abilityFactory.AbilityFactory} object.
* @param sa a {@link forge.card.spellability.SpellAbility} object.
*/
private static void chooseColorResolve(final AbilityFactory af, final SpellAbility sa) {
HashMap<String, String> params = af.getMapParams();
Card card = af.getHostCard();
ArrayList<Player> tgtPlayers;
Target tgt = af.getAbTgt();
if (tgt != null)
tgtPlayers = tgt.getTargetPlayers();
else
tgtPlayers = AbilityFactory.getDefinedPlayers(sa.getSourceCard(), params.get("Defined"), sa);
for (Player p : tgtPlayers) {
if (tgt == null || p.canTarget(af.getHostCard())) {
if (sa.getActivatingPlayer().isHuman()) {
Object o = GuiUtils.getChoice("Choose a color", Constant.Color.onlyColors);
if (null == o) return;
String choice = (String) o;
card.setChosenColor(choice);
} else {
//TODO - needs improvement
card.setChosenColor(Constant.Color.Black);
JOptionPane.showMessageDialog(null, "Computer chooses "+Constant.Color.Black, ""+card, JOptionPane.PLAIN_MESSAGE);
}
}
}
}
}//end class AbilityFactory_Choose