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

#include "pokerui.h"

void pokerUiInit(pokerui_t *ui) {
  uint8_t i;

  // Initialize card render(s)
  imageInit(&ui->card);

  // Initialize the player face quad.
  quadInit(&ui->quad, 0,
    0, 0, 0, 1,
    POKER_UI_PLAYER_IMAGE_SIZE, POKER_UI_PLAYER_IMAGE_SIZE, 1, 0
  );

  // Initialize the grid
  gridInit(&ui->grid);
  
  ui->grid.gutterX = POKER_UI_PLAYER_PADDING;
  ui->grid.columns = 2;
  ui->grid.rows = 2;
  ui->grid.columnDefinitions[1] = POKER_UI_PLAYER_IMAGE_SIZE;
  ui->grid.rowDefinitions[0] = POKER_UI_PLAYER_IMAGE_SIZE / 2.0f;
  ui->grid.rowDefinitions[1] = POKER_UI_PLAYER_IMAGE_SIZE / 2.0f;

  gridResize(&ui->grid, POKER_UI_PLAYER_WIDTH, POKER_UI_PLAYER_HEIGHT);

  // Initialize the label
  labelInit(&ui->label);
  
  // Initialize the frames for each player.
  for(i = 0; i < POKER_PLAYER_COUNT_MAX; i++) {
    frameBufferInit(ui->frames + i,
      POKER_UI_PLAYER_IMAGE_RESOLUTION,
      POKER_UI_PLAYER_IMAGE_RESOLUTION
    );
  }

  // Rest the betting ui
  ui->betShow = false;
}

void pokerUiUpdate(
  pokerui_t *ui, engine_t *engine, shader_t *shader,
  vncharacter_t *characters, pokerplayer_t *players
) {
  uint8_t i, j;
  camera_t camera;
  uint8_t seat;
  float x, y, z;
  pokerplayer_t *player;

  // Set up the camera perspective
  cameraPerspective(&camera, 45,
    (float)POKER_UI_PLAYER_IMAGE_SIZE / (float)POKER_UI_PLAYER_IMAGE_SIZE,
    0.03f, 100.0f
  );

  // Render the face of each player.
  j = 0;
  shaderUse(shader);
  for(i = 0; i < POKER_PLAYER_COUNT_MAX; i++) {
    player = players + j;

    // Locate the XYZ position of the camera to look at the player
    seat = pokerWorldSeatFromIndex(i);
    x = POKER_WORLD_SEAT_POSITION_X(seat);
    y = POKER_UI_PLAYER_IMAGE_Y;
    z = POKER_WORLD_SEAT_POSITION_Z(seat);

    cameraLookAt(&camera,
      x * POKER_UI_PLAYER_IMAGE_DIST, y, z * POKER_UI_PLAYER_IMAGE_DIST,
      x, y, z
    );
    
    // Bind the frame buffer
    frameBufferUse(ui->frames + j, true);

    // Render the VN character
    shaderUseCamera(shader, &camera);
    // shaderUsePosition(shader, 0,0,0, 0,0,0);
    vnCharacterRender(characters + i, shader);

    // Increment
    j++;
  }

  renderResetFramebuffer(&engine->render);
}

void pokerUiRender(
  pokerui_t *ui, engine_t *engine, pokergameassets_t *assets, poker_t *poker
) {
  // uint8_t i, j;
  // pokerplayer_t *player;
  float scale;
  // align_t align;
  // float gx, gy, gw, gh, x, y;
  // char message[128];

  // Get the default font scale size.
  scale = fontGetScale(FONT_SIZE_DEFAULT);

  // <testing>
  // if(poker->state >= POKER_STATE_DEALING) {
  //   for(j = 0; j < POKER_PLAYER_COUNT_MAX; j++) {
  //     player = poker->players + j;
  //     for(i = 0; i < player->cardCount; i++) {
  //       pokerUiSetImageToCard(&ui->card,&assets->cardTexture,player->cards[i]);
  //       imageRender(&ui->card, &assets->shader, i * 64.0f, j * 100.0f);
  //     }
  //   }

  //   for(j = 0; j < poker->communitySize; j++) {
  //     pokerUiSetImageToCard(
  //       &ui->card, &assets->cardTexture, poker->community[j]
  //     );
  //     imageRender(&ui->card, &assets->shader, 200, j * 100.0f);
  //   }
  // // }

  // // Betting UI
  // if(ui->betShow) {
  //   sprintf(message, "Press down to fold, up to raise, right to check/call.");
  //   labelSetText(&ui->label, &assets->font, message);
  //   labelRender(&ui->label, &assets->shader, 300, 100);

  //   if(inputIsPressed(&engine->input, INPUT_DOWN)) {
  //     ui->betTurn = pokerTurnFold(poker, poker->bet.better);
  //     ui->betTurnMade = true;
  //   } else if(inputIsPressed(&engine->input, INPUT_RIGHT)) {
  //     if(pokerTurnCanPlayerCheck(poker, poker->bet.better)) {
  //       ui->betTurn = pokerTurnCheck(poker, poker->bet.better);
  //     } else {
  //       ui->betTurn = pokerTurnCall(poker, poker->bet.better);
  //     }
  //     ui->betTurnMade = true;
  //   }

  //   if(ui->betTurnMade) ui->betShow = false;
  // }

  // // Player UI
  // j = 0;
  // for(i = 0; i < POKER_PLAYER_COUNT; i++) {
  //   // Get the player.
  //   player = poker->players + i;

  //   // Position the grid itself.
  //   x = engine->render.width - POKER_UI_PLAYER_WIDTH;
  //   y = (float)(POKER_UI_PLAYER_HEIGHT * j);

  //   // Render face
  //   gridGetChild(&ui->grid, 1, 0, 1, 2, &gx, &gy, &gw, &gh);
  //   shaderUseTexture(&assets->shader, &(ui->frames + j)->texture);
  //   shaderUsePosition(&assets->shader, x + gx, y + gy, 0, 0,0,0);
  //   primitiveDraw(&ui->quad, 0, -1);

  //   // Render chips
  //   sprintf(message, "$%i", player->chips);
  //   ui->label.maxWidth = -1;
  //   labelSetText(&ui->label, &assets->font, message);
  //   align = gridGetAndAlignChild(
  //     &ui->grid, 0, 0, 1, 1, 
  //     ALIGN_POS_END|ALIGN_SIZE_ORIGINAL, ALIGN_POS_CENTER|ALIGN_SIZE_ORIGINAL,
  //     ui->label.info.width, ui->label.info.height
  //   );
  //   labelRender(&ui->label, &assets->shader, x+align.x, y+align.y);
    
  //   // Render state
  //   if(player->state & POKER_PLAYER_STATE_OUT) {
  //     sprintf(message, "Out");
  //   } else if(player->state & POKER_PLAYER_STATE_FOLDED) {
  //     sprintf(message, "Folded");
  //   } else if(player->state & POKER_PLAYER_STATE_SHOWING) {
  //     sprintf(message, "Showing");
  //   } else if(poker->bet.better == j) {
  //     sprintf(message, "Thinking");
  //   } else {
  //     sprintf(message, "Whatever");
  //   }
  //   labelSetText(&ui->label, &assets->font, message);
  //   align = gridGetAndAlignChild(
  //     &ui->grid, 0, 1, 1, 1, 
  //     ALIGN_POS_END | ALIGN_SIZE_ORIGINAL, ALIGN_POS_CENTER | ALIGN_SIZE_ORIGINAL,
  //     ui->label.info.width, ui->label.info.height
  //   );
  //   labelRender(&ui->label, &assets->shader, x+align.x, y+align.y);

  //   // Increment.
  //   j++;
  // }
}

void pokerUiDispose(pokerui_t *ui) {
  uint8_t i;

  for(i = 0; i < POKER_PLAYER_COUNT_MAX; i++) {
    frameBufferDispose(ui->frames + i);
  }
  labelDispose(&ui->label);
  primitiveDispose(&ui->quad);
  imageDispose(&ui->card);
}

void pokerUiSetImageToCard(image_t *image, texture_t *texture, card_t card) {
  uint8_t cardImageIndex = (
    cardGetNumber(card) == CARD_ACE ? (
      card - CARD_COUNT_PER_SUIT + 1
    ) : card+0x01
  );

  imageSetTextureAndCrop(
    image, texture,
    cardGetNumber(cardImageIndex) * 71.0f,
    cardGetSuit(card) * 96.0f,
    71, 96
  );
}

void pokerUiBetShow(pokerui_t *ui) {
  ui->betShow = true;
  ui->betTurnMade = false;
}