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 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 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 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; } }