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

#include "UIBorder.hpp"
#include "game/DawnGame.hpp"

using namespace Dawn;

UIBorder::UIBorder(UICanvas *canvas) : UIComponent(canvas) {
  this->mesh.createBuffers(QUAD_VERTICE_COUNT * 9, QUAD_INDICE_COUNT * 9);

  this->updatePositions();
}

void UIBorder::updatePositions() {
  UIComponent::updatePositions();

  glm::vec2 oneThird = this->uv1 / 3.0f;
  glm::vec2 overallDimensions = glm::vec2(this->getWidth(), this->getHeight());
  glm::vec2 innerDimensions = overallDimensions - (this->edgeDimensions * 2.0f);
  
  
  // Top Left.
  QuadMesh::bufferQuadMesh(&this->mesh,
    glm::vec2(0, 0),
    this->uv0,
    edgeDimensions,
    this->uv0 + oneThird,
    0, 0
  );

  // Top Center
  QuadMesh::bufferQuadMesh(&this->mesh,
    glm::vec2(edgeDimensions.x, 0),
    this->uv0 + glm::vec2(oneThird.x, 0),
    glm::vec2(edgeDimensions.x + innerDimensions.x, edgeDimensions.y),
    this->uv0 + glm::vec2(oneThird.x * 2.0f, oneThird.y),
    QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT
  );

  // Top Right
  QuadMesh::bufferQuadMesh(&this->mesh,
    glm::vec2(edgeDimensions.x + innerDimensions.x, 0),
    this->uv0 + glm::vec2(oneThird.x * 2.0f, 0),
    glm::vec2(overallDimensions.x, edgeDimensions.y),
    glm::vec2(this->uv1.x, this->uv0.y + oneThird.y),
    QUAD_VERTICE_COUNT * 2, QUAD_INDICE_COUNT * 2
  );

  // Middle Left
  QuadMesh::bufferQuadMesh(&this->mesh,
    glm::vec2(0, edgeDimensions.y),
    this->uv0 + glm::vec2(0, oneThird.y),
    glm::vec2(edgeDimensions.x, edgeDimensions.y + innerDimensions.y),
    this->uv0 + glm::vec2(oneThird.x, oneThird.y * 2.0f),
    QUAD_VERTICE_COUNT * 3, QUAD_INDICE_COUNT * 3
  );

  // Center
  QuadMesh::bufferQuadMesh(&this->mesh,
    edgeDimensions,
    this->uv0 + oneThird,
    edgeDimensions + innerDimensions,
    this->uv0 + (oneThird * 2.0f),
    QUAD_VERTICE_COUNT * 4, QUAD_INDICE_COUNT * 4
  );

  // Middle Right
  QuadMesh::bufferQuadMesh(&this->mesh,
    edgeDimensions + glm::vec2(innerDimensions.x, 0),
    this->uv0 + glm::vec2(oneThird.x * 2.0f, oneThird.y),
    edgeDimensions + innerDimensions + glm::vec2(edgeDimensions.x, 0),
    this->uv1 - glm::vec2(0.0f, oneThird.y),
    QUAD_VERTICE_COUNT * 5, QUAD_INDICE_COUNT * 5
  );

  // Bottom Left
  QuadMesh::bufferQuadMesh(&this->mesh,
    glm::vec2(0.0f, edgeDimensions.y + innerDimensions.y),
    this->uv0 + glm::vec2(0.0f, uv1.y - oneThird.y),
    glm::vec2(edgeDimensions.x, overallDimensions.y),
    this->uv1 - glm::vec2(oneThird.x * 2.0f, 0.0f),
    QUAD_VERTICE_COUNT * 6, QUAD_INDICE_COUNT * 6
  );

  // Bottom Center
  QuadMesh::bufferQuadMesh(&this->mesh,
    edgeDimensions + glm::vec2(0.0f, innerDimensions.y),
    this->uv1 - oneThird,
    overallDimensions - glm::vec2(edgeDimensions.x, 0.0f),
    this->uv1 - glm::vec2(oneThird.x, 0.0f),
    QUAD_VERTICE_COUNT * 7, QUAD_INDICE_COUNT * 7
  );

  // Bottom Right
  QuadMesh::bufferQuadMesh(&this->mesh,
    overallDimensions - edgeDimensions,
    this->uv1 - oneThird,
    overallDimensions,
    this->uv1,
    QUAD_VERTICE_COUNT * 8, QUAD_INDICE_COUNT * 8
  );
}

std::vector<struct ShaderPassItem> UIBorder::getSelfPassItems(
  glm::mat4 projection,
  glm::mat4 view,
  glm::mat4 transform
) {
  std::vector<struct ShaderPassItem> items;
  if(this->texture == nullptr) return items;

  items.push_back(this->getGame()->renderManager.uiShaderProgram.getUIPassItem(
    projection,
    view,
    transform,
    this->texture,
    COLOR_WHITE,
    &this->mesh,
    this->z
  ));

  return items;
}

void UIBorder::setBorderSize(glm::vec2 borderSize) {
  this->edgeDimensions = borderSize;
  this->updatePositions();
}

glm::vec2 UIBorder::getInnerSize() {
  return glm::vec2(this->getWidth(), this->getHeight()) - this->edgeDimensions;
}

glm::vec2 UIBorder::getBorderSize() {
  return this->edgeDimensions;
}

UIBorder::~UIBorder() {
}