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

#pragma once
#include "../../libs.h"
#include "../../display/shader.h"
#include "../../display/primitive.h"
#include "../../display/animation/easing.h"
#include "../../display/primitives/skywall.h"
#include "../../vn/vnscene.h"
#include "../../vn/vncharacter.h"
#include "../../engine/engine.h"
#include "../../poker/poker.h"
#include "pokergameassets.h"

/** How far away from the camera are the characters distanced */
#define POKER_WORLD_SEAT_DISTANCE -0.75f

/** How rotated is the player at a given seat */
#define POKER_WORLD_SEAT_ROTATION(n) (n * mathDeg2Rad(45.0f))

/** World X position of a given seat */
#define POKER_WORLD_SEAT_POSITION_X(n) ( \
  POKER_WORLD_SEAT_DISTANCE * (float)sin(POKER_WORLD_SEAT_ROTATION(n)) \
)
/** Y Position of seats */
#define POKER_WORLD_SEAT_POSITION_Y -0.2f
/** World Z position of a given seat */
#define POKER_WORLD_SEAT_POSITION_Z(n) ( \
  POKER_WORLD_SEAT_DISTANCE * (float)cos(POKER_WORLD_SEAT_ROTATION(n)) \
)

/** Count of seats in the world */
#define POKER_WORLD_SEAT_COUNT 8

/** The seat index for a given player index */
#define POKER_WORLD_SEAT_FOR_PLAYER(p) (p - (POKER_PLAYER_COUNT_MAX/2))

/** The seat that the dealer occupies */
#define POKER_WORLD_SEAT_DEALER POKER_WORLD_SEAT_FOR_PLAYER(\
  POKER_WORLD_DEALER_INDEX\
)

/** The seat index for a given character index */
#define pokerWorldSeatFromIndex(i) (\
  i == POKER_WORLD_DEALER_INDEX ? \
  POKER_WORLD_SEAT_DEALER : \
  POKER_WORLD_SEAT_FOR_PLAYER(i) \
)

// Penny Defs.
#define POKER_WORLD_PENNY_BASE_WIDTH 1000
#define POKER_WORLD_PENNY_BASE_HEIGHT 1920
#define POKER_WORLD_PENNY_FACE_X 367
#define POKER_WORLD_PENNY_FACE_Y 256
#define POKER_WORLD_PENNY_FACE_WIDTH 280
#define POKER_WORLD_PENNY_FACE_HEIGHT 280

typedef struct {
  primitive_t skywall;

  /** Which seat the game should look at */
  uint8_t seat;
  float seatTime;
} pokerworld_t;

/**
 * Initialize the poker renderer.
 * 
 * @param world Pointer to the world to initialize.
 * @param scene Visual Novel Engine scene to initialize.
 * @param assets Assets to use for initialization.
 */
void pokerWorldInit(
  pokerworld_t *world,
  vnscene_t *scene,
  pokergameassets_t *assets
);

/**
 * Adjusts the camera to look at a specific player. You can use this to look at
 * the dealer by referencing the POKER_PLAYER_HUMAN_INDEX as the index.
 * 
 * @param scene Visual Novel Engine scene.
 * @param playerIndex Player index to look at.
 */
void pokerWorldLookAtPlayer(
  vnscene_t *scene, uint8_t playerIndex
);

/**
 * Render the poker world.
 * 
 * @param world Poker Game World.
 * @param assets Assets to use.
 */
void pokerWorldRender(pokerworld_t *world, pokergameassets_t *assets);

/**
 * Cleanup the poker world.
 * @param world World to clean up.
 */
void pokerWorldDispose(pokerworld_t *world);