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

#pragma once
#include "../libs.h"
#include "poker.h"
#include "winner.h"
#include "../util/rand.h"

#define POKER_TURN_TYPE_OUT 0x00
#define POKER_TURN_TYPE_FOLD 0x01
#define POKER_TURN_TYPE_BET 0x02
#define POKER_TURN_TYPE_CALL 0x03
#define POKER_TURN_TYPE_ALL_IN 0x04
#define POKER_TURN_TYPE_CALL_ALL_IN 0x04
#define POKER_TURN_TYPE_CHECK 0x05

#define POKER_TURN_MAX_RAISES 0x02

/** The turn that a player/the AI decided to do for its turn */
typedef struct {
  /** What type of action the turn is */
  uint8_t type;
  /** How many chips they did in their turn (if applicable) */
  int32_t chips;
  /** How confident the AI is about their turn. 0 = none, 1 = full */
  float confidence;
} pokerturn_t;

/**
 * Returns the AI result for a turn done by a non human player.
 * 
 * @param poker Poker game instance to use.
 * @param playerIndex Player index to get the turn for.
 * @return Some information about the move the player is trying to perform.
 */
pokerturn_t pokerTurnGet(poker_t *poker, uint8_t playerIndex);

/**
 * Perform the turn's action.
 * 
 * @param poker Poker game instance.
 * @param player Player instance.
 * @param turn Turn to action.
 */
void pokerTurnAction(poker_t *poker, pokerplayer_t *player, pokerturn_t *turn);

/**
 * Return a turn action for the player being out.
 * 
 * @param poker Poker game instance.
 * @param player Player index.
 * @return A turn for an out action.
 */
pokerturn_t pokerTurnOut(poker_t *poker, uint8_t player);

/**
 * Return a turn action for the given player to fold.
 * 
 * @param poker Poker game instance.
 * @param player Player index.
 * @return A turn for a fold action.
 */
pokerturn_t pokerTurnFold(poker_t *poker, uint8_t player);

/**
 * Perform a check as a player.
 * 
 * @param poker Poker game instance.
 * @param player Player index for who is checking.
 * @return A turn for a check action.
 */
pokerturn_t pokerTurnCheck(poker_t *poker, uint8_t player);

/**
 * Perform a call as a player
 * 
 * @param poker Poker game instance.
 * @param player Player index who is calling.
 * @return A turn for a call action.
 */
pokerturn_t pokerTurnCall(poker_t *poker, uint8_t player);

/**
 * Perform a bet as a player.
 * 
 * @param poker Poker game instance.
 * @param playerIndex Player index who is betting.
 * @param chips Chips to raise by.
 * @return A turn for a bet action.
 */
pokerturn_t pokerTurnRaise(poker_t *poker, uint8_t playerIndex, int32_t chips);

/**
 * Determine whether or not a player CAN check, given the current max bet and
 * the players current bet.
 * 
 * @param poker Poker game instance.
 * @param playerIndex Poker player index.
 * @return True if the player can check, false if they need to call first.
 */
bool pokerTurnCanPlayerCheck(poker_t *poker, uint8_t playerIndex);