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

#include "bet.h"

void _pokerGameActionBetOnStart(
  queue_t *queue, queueaction_t *action, uint8_t i
) {
  bool isHuman;
  pokergame_t *game = (pokergame_t *)action->data;

  // Reset the UI state.
  isHuman = game->poker.bet.better == POKER_PLAYER_HUMAN_INDEX;
  if(isHuman) pokerUiBetShow(&game->ui);
}

void _pokerGameActionBetOnUpdate(
  queue_t *queue, queueaction_t *action, uint8_t i
) {
  // Restack
  bool isHuman;
  bool turnMade = false;
  pokerturn_t turn;
  pokergame_t *game = (pokergame_t *)action->data;
  pokerplayer_t *player;
  pokerdiscussiondata_t discussion;
  
  // 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 = game->ui.betTurn;
    turnMade = game->ui.betTurnMade;
  } else {
    turn = pokerTurnGet(&game->poker, game->poker.bet.better);
    turnMade = true;
  }

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

  // Perform the action
  pokerTurnAction(&game->poker, player, &turn);

  // Speak
  switch(turn.type) {
    case POKER_TURN_TYPE_BET:
      discussion.reason = POKER_DISCUSSION_REASON_PLAYER_RAISING;
      break;

    case POKER_TURN_TYPE_CALL:
      discussion.reason = POKER_DISCUSSION_REASON_PLAYER_CALLING;
      break;

    case POKER_TURN_TYPE_ALL_IN:
      discussion.reason = POKER_DISCUSSION_REASON_PLAYER_CALLING;
      break;
    
    case POKER_TURN_TYPE_FOLD:
      discussion.reason = POKER_DISCUSSION_REASON_PLAYER_FOLDING;
      break;

    case POKER_TURN_TYPE_CHECK:
      discussion.reason = POKER_DISCUSSION_REASON_PLAYER_CHECKING;
      break;
    
    default:
      discussion.reason = POKER_DISCUSSION_REASON_TEST;
      break;
  }
  
  discussion.poker = game;
  discussion.playerCause = game->poker.bet.better;
  pokerDiscussionQueue(&discussion);

  // Next.
  queueNext(queue);
}

void _pokerGameActionBetOnEnd(
  queue_t *queue, queueaction_t *action, uint8_t i
) {
  queueaction_t *next;
  pokerdiscussiondata_t discussion;
  pokergame_t *game = (pokergame_t *)action->data;

  // Get which player is remaining to move.
  game->poker.bet.better = pokerBetGetRemainingPlayer(
    &game->poker.bet, game->poker.players, game->poker.roundSmallBlind
  );

  // Restack
  pokerGameActionRestackAdd(game);

  // Are we waiting on any players?
  if(game->poker.bet.better != 0xFF) {
    if(game->poker.bet.better == POKER_PLAYER_HUMAN_INDEX) {
      pokerGameActionLookAdd(game, POKER_DEALER_INDEX);
    } else {
      pokerGameActionLookAdd(game, game->poker.bet.better);
    }
    pokerGameActionBetAdd(game);
    return;
  }

  // Not waiting, restack and do next action.
  printf("Not waiting on anything!\n");

  // No! Begin the next flop.
  next = pokerActionNextFlopAdd(queue, &game->poker);
  if(next != NULL) {
    discussion.reason = POKER_DISCUSSION_REASON_FLOP;
    discussion.poker = game;
    pokerDiscussionQueue(&discussion);

    pokerBetResetBetter(
      &game->poker.bet, game->poker.players, game->poker.roundSmallBlind
    );
    pokerGameActionRestackAdd(game);
    pokerGameActionLookAdd(game, game->poker.bet.better);
    pokerGameActionBetAdd(game);
    return;
  }
  
  /** Queue a restack */
  printf("All betting is done, reveal\n");
}

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