mourning-ember / src / main / java / dev / llan / model / cards / CardCollection.java
CardCollection.java
Raw
package dev.llan.model.cards;

import dev.llan.model.pieces.Entity;
import dev.llan.utils.MathUtil;

import java.util.Arrays;
import java.util.Optional;

import static dev.llan.model.cards.Constants.*;

public class CardCollection {
  private Card[] collection;
  private int addIndex = FIRST_INACTIVE_INDEX;
  private Hand hand;

  private int selectedIndex;
  private Optional<Card> selectedCard;

  public CardCollection() {
    collection = new Card[MAX_TOTAL_CARDS];
    hand = new Hand();
    selectedIndex = -1;
    selectedCard = Optional.empty();
  }

  public void initCollection(Card[] initialDeck) {
    assert initialDeck.length >= MAX_DECK_CARDS;

    for (int i = 0; i < MAX_DECK_CARDS; i++) {
      collection[i] = initialDeck[i];
    }

    hand.initHand(this);
  }

  public Deck createNewDeck() {
    Card[] deckArray = Arrays.copyOfRange(collection, 0, MAX_DECK_CARDS);
    return new Deck(deckArray);
  }

  public boolean hasCardAt(int index) {
    return collection[index] != null;
  }

  public Card getCardAt(int index) {
    return collection[index];
  }

  public Optional<Card> selectCard(int handIndex) {
    assert MathUtil.within(handIndex, -1, MAX_HAND_CARDS - 1);
    selectedIndex = handIndex;
    if (handIndex == -1) {
      selectedCard = Optional.empty();
    } else {
      if(hand.cardAt(handIndex).canPlay()) {
        selectedCard = Optional.of(hand.cardAt(handIndex));
      } else {
        selectedCard = Optional.empty();
        selectedIndex = -1;
      }
    }
    return selectedCard;
  }

  public Hand getHand() {
    return hand;
  }

  public int getSelectedIndex() {
    return selectedIndex;
  }

  public Optional<Card> getSelectedCard() {
    return selectedCard;
  }

  public void swapCards(int first, int second) {
    if (first < MAX_DECK_CARDS || second < MAX_DECK_CARDS) {
      if (hasCardAt(first) && hasCardAt(second)) {
        Card temp = collection[first];
        collection[first] = collection[second];
        collection[second] = temp;
        clearAllOnPlayed();
        hand.initHand(this);
      }
    } else {
      Card temp = collection[first];
      collection[first] = collection[second];
      collection[second] = temp;
    }
  }

  public void addNewCard(Card card) {
    for (int i = FIRST_INACTIVE_INDEX; i < MAX_TOTAL_CARDS; i++) {
      if (!hasCardAt(i)) {
        collection[i] = card;
        return;
      }
    }
  }

  public void removeCard(int index) {
    if (index >= MAX_DECK_CARDS) {
      collection[index] = null;
    }
  }

  private void clearAllOnPlayed() {
    for (int i = 0; i < MAX_TOTAL_CARDS; i++) {
      if (collection[i] != null) {
        collection[i].clearOnPlayed();
      }
    }
  }

  public void updatePlayableCards(double mana) {
    hand.updatePlayableCards(mana);
  }

  public CardCollection clone(Entity cloned) {
    CardCollection clone = new CardCollection();

    for (int i = 0; i < MAX_TOTAL_CARDS; i++) {
      if (this.collection[i] != null) {
        clone.collection[i] = this.collection[i].clone(cloned);
      }
    }

    clone.selectedIndex = this.selectedIndex;
    if (selectedCard.isPresent()) {
      clone.selectedCard = Optional.of(clone.collection[selectedIndex]);
    } else {
      clone.selectedCard = Optional.empty();
    }

    clone.addIndex = this.addIndex;
    clone.hand = this.hand.clone(clone);

    return clone;
  }
}