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

#include "bet.h"

void _pokerGameActionBetOnUpdate(
  queue_t *queue, queueaction_t *action, uint8_t i
) {
  bool isHuman;
  bool turnMade = false;
  pokerturn_t turn;
  pokergame_t *game = (pokergame_t *)action->data;
  pokerplayer_t *player;


  // As of right now the queue should basically be empty besides this item, so
  // let's restack
  queueRestack(queue);

  // Are they human?
  player = game->poker.players + game->poker.bet.better;
  isHuman = game->poker.bet.better == POKER_PLAYER_HUMAN_INDEX;

  // Handle as an AI
  if(isHuman) {
    turn.type = POKER_TURN_TYPE_FOLD;
    turnMade = true;
  } else {
    turn = pokerTurnGet(&game->poker, game->poker.bet.better);
    turnMade = true;
  }

  // Now decide if we should do something.
  if(!turnMade) return;

  // What happened?
  char *debugAction;
  switch(turn.type) {
    // Player bets
    case POKER_TURN_TYPE_BET:
      debugAction = "betting";
      pokerBetPlayer(&game->poker, player, turn.chips);
      break;

    // Player folds
    case POKER_TURN_TYPE_FOLD:
      debugAction = "folding";
      player->state |= POKER_PLAYER_STATE_FOLDED;
      break;

    // Player checks
    case POKER_TURN_TYPE_CHECK:
      debugAction = "checking";
      break;
    
    // Player may be out
    default:
      debugAction = "doing nothing";
      break;
  }

  printf("Player %i is %s.\n", game->poker.bet.better, debugAction);
  queueNext(queue);
}

void _pokerGameActionBetOnEnd(
  queue_t *queue, queueaction_t *action, uint8_t i
) {
  uint8_t j;
  pokerplayer_t *player;
  queueaction_t *next;
  pokergame_t *game = (pokergame_t *)action->data;
  bool playersPending;

  // Go to the next better
  game->poker.bet.better = (game->poker.bet.better + 1) % POKER_PLAYER_COUNT;
  playersPending = false;

  // Check if each player needs to action.
  for(j = 0; j < POKER_PLAYER_COUNT; j++) {
    player = game->poker.players + j;
    if(player->state & POKER_PLAYER_STATE_FOLDED) continue;
    if(player->state & POKER_PLAYER_STATE_OUT) continue;
    if(player->currentBet >= game->poker.bet.currentBet) continue;

    // Yes, this player needs to check, raise or fold
    pokerGameActionBetAdd(game);
    playersPending = true;
    break;
  }

  // Are we waiting on any players?
  if(playersPending) return;

  printf("Not waiting on anything!\n");

  // No! Begin the next flop.
  next = pokerActionNextFlopAdd(queue, &game->poker);
  if(next != NULL) {
    pokerBetResetBetter(&game->poker);
    pokerGameActionBetAdd(game);
    return;
  }

  printf("All betting is done, reveal");
  
}

queueaction_t * pokerGameActionBetAdd(pokergame_t *game) {
  queueaction_t *action = pokerGameActionAdd(game);
  action->onUpdate = &_pokerGameActionBetOnUpdate;
  action->onEnd = &_pokerGameActionBetOnEnd;
  return action;
}