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

#pragma once
#include "../libs.h"
#include "player.h"
#include "../util/math.h"
#include "../util/array.h"

/** How many chips each player has by defautl */
#define POKER_BET_PLAYER_CHIPS_DEFAULT 1200

/** The default blind cost for the big blind. */
#define POKER_BET_BLIND_BIG_DEFAULT 600

/** The default blind cost for the small blind. (Defaults half big blind) */
#define POKER_BET_BLIND_SMALL_DEFAULT (POKER_BET_BLIND_BIG_DEFAULT/2)

typedef struct {
  /** Blinds */
  int32_t blindSmall, blindBig;

  /** How big the current bet is for the round. */
  int32_t currentBet;
  
  /** For Betting round, which player is currently betting */
  uint8_t better;

  /** Current pot of chips */
  int32_t pot;
} pokerbet_t;

/**
 * Initializes/resets the poker bet context.
 * 
 * @param bet Poker bet instance.
 */
void pokerBetInit(pokerbet_t *bet);

/**
 * Resets the bet state (for a new round).
 * 
 * @param bet Betting stating.
 */
void pokerBetReset(pokerbet_t *bet);

/**
 * The default betting player for the round.
 * 
 * @param roundSmallBlind Current round small blind player index.
 * @return The Poker round default betting player index.
 */
uint8_t pokerBetGetRoundPlayerDefault(uint8_t roundSmallBlind);

/**
 * Let a player bet chips into the pot.
 * 
 * @param bet Poker bet instance.
 * @param player Poker player instance.
 * @param chips Chips to bet.
 */
void pokerBetPlayer(pokerbet_t *bet, pokerplayer_t *player, int32_t chips);

/**
 * Reset the current better back to the round/turns default. The better will
 * always be the player to the right of the small blind player.
 * 
 * @param bet Poker betting structure.
 * @param player Array of poker players.
 * @param roundSmallBlind Current round small blind player index.
 */
void pokerBetResetBetter(
  pokerbet_t *poker, pokerplayer_t *players, uint8_t roundSmallBlind
);

/**
 * Returns whether or not a player can bet for the current round.
 * 
 * @param bet Game bet state.
 * @param player Player to check.
 * @return True if the player can bet, otherwise false.
 */
bool pokerBetPlayerCanBet(pokerbet_t *bet, pokerplayer_t *player);

/**
 * Returns the index of the first player that remains to bet for the current
 * round.
 * 
 * @param bet Poker betting structure.
 * @param player Array of poker players.
 * @param roundSmallBlind Current round small blind player index.
 * @return The player index of the remaining player, otherwise 0xFF.
 */
uint8_t pokerBetGetRemainingPlayer(
  pokerbet_t *bet, pokerplayer_t *players, uint8_t roundSmallBlind
);

/**
 * Returns the count of players who are still needing to bet.
 * 
 * @param bet Betting instance
 * @param players Players array.
 * @return Count of players who can still bet.
 */
uint8_t pokerBetGetRemainingPlayerCount(pokerbet_t *bet,pokerplayer_t *players);

/**
 * Takes the current blinds from the correct players.
 * 
 * @param poker Poker game to take the blinds from.
 */
void pokerBetTakeBlinds(
  pokerbet_t *bet, pokerplayer_t *players,
  uint8_t roundSmallBlind, uint8_t roundBigBlind
);