/**
 * Copyright (c) 2021 Dominic Masters
 * 
 * This software is released under the MIT License.
 * https://opensource.org/licenses/MIT
 */
#include "card.h"

void cardDeal(
  card_t *source, uint8_t *sourceSize, card_t *dest, uint8_t *destSize
) {
  card_t card;
  uint8_t i;

  // Take Card
  i = *sourceSize - 1;
  card = source[i];
  *sourceSize = i;

  // Put card
  i = *destSize;
  dest[i] = card;
  *destSize = i+1;
}

void cardHandSort(card_t *cards, uint8_t length) {
  arraySort(sizeof(card_t), cards, (int32_t)length, (arraysort_t *)&_cardSorter);
}

int32_t _cardSorter(const void* left, const void* right) {
  card_t cardL = *((card_t *)left);
  card_t cardR = *((card_t *)right);

  uint8_t suitL = cardGetSuit(cardL);
  uint8_t suitR = cardGetSuit(cardR);
  if(suitL != suitR) return suitL - suitR;

  uint8_t numberL = cardGetNumber(cardL);
  uint8_t numberR = cardGetNumber(cardR);

  // Get the suit and the value of the card (reversed)
  return numberR - numberL;
}

int32_t cardContains(card_t *hand, uint8_t length, card_t card) {
  return arrayFind(sizeof(card_t), hand, (int32_t)length, &card);
}

int32_t cardContainsNumber(card_t *hand, uint8_t length, uint8_t number) {
  int32_t i;
  for(i = 0; i < length; i++) {
    if(cardGetNumber(hand[i]) == number) return i;
  }
  return -1;
}

uint8_t cardCountPairs(card_t *in, uint8_t inCount, uint8_t number,
  int32_t out[CARD_SUIT_COUNT]
) {
  uint8_t i, count;
  
  count = 0;
  for(i = 0; i < inCount; i++) {// "For each suit"
    if(cardGetNumber(in[i]) != number) continue;
    out[count++] = i;
  }
  
  return count;
}

void cardShuffle(card_t *hand, uint8_t length) {
  arrayShuffle(sizeof(card_t), hand, length);
}

uint8_t cardWriteDeck(card_t *hand) {
  uint8_t i;
  for(i = 0; i < CARD_DECK_SIZE; i++) hand[i] = i;
  return CARD_DECK_SIZE;
}

card_t cardGetHighest(card_t *cards, uint8_t cardCount) {
  uint8_t i, number, bestNumber;
  card_t card, bestCard;

  bestNumber = 0xFF;

  for(i = 0; i < cardCount; i++) {
    card = cards[i];
    number = cardGetNumber(card);
    if(number == CARD_ACE) return card;
    if(bestNumber != 0xFF && number <= bestNumber) continue;

    bestCard = card;
    bestNumber = number;
  }

  return bestCard;
}