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