/* (non-Javadoc)
   * @see forge.card.abilityfactory.SpellAiLogic#canPlayAI(forge.game.player.Player, forge.card.spellability.SpellAbility)
   */
  @Override
  protected boolean canPlayAI(Player aiPlayer, SpellAbility sa) {
    String logic = sa.getParam("AILogic");
    Game game = aiPlayer.getGame();

    if ("ZeroToughness".equals(logic)) {
      // If Creature has Zero Toughness, make sure some static ability is in play
      // That will grant a toughness bonus

      final List<Card> list = aiPlayer.getCardsIn(ZoneType.Battlefield);
      if (!Iterables.any(
          list,
          Predicates.or(
              CardPredicates.nameEquals("Glorious Anthem"),
              CardPredicates.nameEquals("Gaea's Anthem")))) {
        return false;
      }

      // TODO See if card ETB will survive after Static Effects
      /*
      List<Card> cards = game.getCardsIn(ZoneType.Battlefield);

      for(Card c : cards) {
          ArrayList<StaticAbility> statics = c.getStaticAbilities();
          for(StaticAbility s : statics) {
              final Map<String, String> stabMap = s.parseParams();

              if (!stabMap.get("Mode").equals("Continuous")) {
                  continue;
              }

              final String affected = stabMap.get("Affected");

              if (affected == null) {
                  continue;
              }
          }
      }
      */
    }

    // Wait for Main2 if possible
    if (game.getPhaseHandler().is(PhaseType.MAIN1)
        && !ComputerUtil.castPermanentInMain1(aiPlayer, sa)) {
      return false;
    }

    // AI shouldn't be retricted all that much for Creatures for now
    return true;
  }
  @Override
  public PaymentDecision visit(CostPutCardToLib cost) {
    Integer c = cost.convertAmount();
    final Game game = player.getGame();
    List<Card> chosen = new ArrayList<Card>();
    List<Card> list;

    if (cost.isSameZone()) {
      list = new ArrayList<Card>(game.getCardsIn(cost.getFrom()));
    } else {
      list = new ArrayList<Card>(player.getCardsIn(cost.getFrom()));
    }

    if (c == null) {
      final String sVar = ability.getSVar(cost.getAmount());
      // Generalize cost
      if (sVar.equals("XChoice")) {
        return null;
      }

      c = AbilityUtils.calculateAmount(source, cost.getAmount(), ability);
    }

    list = CardLists.getValidCards(list, cost.getType().split(";"), player, source);

    if (cost.isSameZone()) {
      // Jotun Grunt
      // TODO: improve AI
      final List<Player> players = game.getPlayers();
      for (Player p : players) {
        List<Card> enoughType = CardLists.filter(list, CardPredicates.isOwner(p));
        if (enoughType.size() >= c) {
          chosen.addAll(enoughType);
          break;
        }
      }
      chosen = chosen.subList(0, c);
    } else {
      chosen =
          ComputerUtil.choosePutToLibraryFrom(
              player, cost.getFrom(), cost.getType(), source, ability.getTargetCard(), c);
    }
    return chosen.isEmpty() ? null : PaymentDecision.card(chosen);
  }
  private boolean sacrificeTgtAI(final Player ai, final SpellAbility sa) {

    final Card source = sa.getHostCard();
    final TargetRestrictions tgt = sa.getTargetRestrictions();
    final boolean destroy = sa.hasParam("Destroy");

    Player opp = ai.getOpponent();
    if (tgt != null) {
      sa.resetTargets();
      if (!opp.canBeTargetedBy(sa)) {
        return false;
      }
      sa.getTargets().add(opp);
      final String valid = sa.getParam("SacValid");
      String num = sa.getParam("Amount");
      num = (num == null) ? "1" : num;
      final int amount = AbilityUtils.calculateAmount(sa.getHostCard(), num, sa);

      List<Card> list =
          CardLists.getValidCards(
              ai.getOpponent().getCardsIn(ZoneType.Battlefield),
              valid.split(","),
              sa.getActivatingPlayer(),
              sa.getHostCard());
      for (Card c : list) {
        if (c.hasSVar("SacMe") && Integer.parseInt(c.getSVar("SacMe")) > 3) {
          return false;
        }
      }
      if (!destroy) {
        list = CardLists.filter(list, CardPredicates.canBeSacrificedBy(sa));
      } else {
        if (!CardLists.getKeyword(list, "Indestructible").isEmpty()) {
          // human can choose to destroy indestructibles
          return false;
        }
      }

      if (list.isEmpty()) {
        return false;
      }

      if (num.equals("X") && source.getSVar(num).equals("Count$xPaid")) {
        // Set PayX here to maximum value.
        final int xPay = Math.min(ComputerUtilMana.determineLeftoverMana(sa, ai), amount);
        source.setSVar("PayX", Integer.toString(xPay));
      }

      final int half = (amount / 2) + (amount % 2); // Half of amount
      // rounded up

      // If the Human has at least half rounded up of the amount to be
      // sacrificed, cast the spell
      if (!sa.isTrigger() && list.size() < half) {
        return false;
      }
    }

    final String defined = sa.getParam("Defined");
    final String valid = sa.getParam("SacValid");
    if (defined == null) {
      // Self Sacrifice.
    } else if (defined.equals("Each") || (defined.equals("Opponent") && !sa.isTrigger())) {
      // If Sacrifice hits both players:
      // Only cast it if Human has the full amount of valid
      // Only cast it if AI doesn't have the full amount of Valid
      // TODO: Cast if the type is favorable: my "worst" valid is
      // worse than his "worst" valid
      final String num = sa.hasParam("Amount") ? sa.getParam("Amount") : "1";
      int amount = AbilityUtils.calculateAmount(source, num, sa);

      if (num.equals("X") && source.getSVar(num).equals("Count$xPaid")) {
        // Set PayX here to maximum value.
        amount = Math.min(ComputerUtilMana.determineLeftoverMana(sa, ai), amount);
      }

      List<Card> humanList =
          CardLists.getValidCards(
              opp.getCardsIn(ZoneType.Battlefield),
              valid.split(","),
              sa.getActivatingPlayer(),
              sa.getHostCard());

      // Since all of the cards have remAIDeck:True, I enabled 1 for 1
      // (or X for X) trades for special decks
      if (humanList.size() < amount) {
        return false;
      }
    } else if (defined.equals("You")) {
      List<Card> computerList =
          CardLists.getValidCards(
              ai.getCardsIn(ZoneType.Battlefield),
              valid.split(","),
              sa.getActivatingPlayer(),
              sa.getHostCard());
      for (Card c : computerList) {
        if (c.hasSVar("SacMe") || ComputerUtilCard.evaluateCreature(c) <= 135) {
          return true;
        }
      }
      return false;
    }

    return true;
  }