#include "GridLine.hpp"
#include "ShaderCodes.hpp"
#include "glew.h"

GridLine::GridLine(int iHeight, int iRow) {
  iType = GRID_LINE;
  this->iHeight = iHeight;
  this->iRow = iRow;

  pShader = new Shader(sSolidColorVertSource, sSolidColorFragSource);
  
  //calculate the y-value of the GL line
  fRelativeHeight = (float) iRow * (UPPER_Y - ORIGIN_Y) / (float) GRID_LINES + ORIGIN_Y;

  vVertices = new glm::vec4[2];
  vVertices[0] = glm::vec4(ORIGIN_X, fRelativeHeight, 0.0f, 1.0f);
  vVertices[1] = glm::vec4(UPPER_X, fRelativeHeight, 0.0f, 1.0f);

  vColors = new glm::vec4[2];
  vColors[0] = glm::vec4(GRID_LINE_COLOR, GRID_LINE_COLOR, GRID_LINE_COLOR, 1.0f);
  vColors[1] = glm::vec4(GRID_LINE_COLOR, GRID_LINE_COLOR, GRID_LINE_COLOR, 1.0f);

  vIndices = new int[2];
  vIndices[0] = 0;
  vIndices[1] = 1;

  //label
  pLabel = new Label(QString::number(iHeight), FONTSTYLE_ELEMENT, GRID_LINE_TEXT_OFFSET,
    HEIGHT * (1.0f - (fRelativeHeight + 1.0f) / 2.0f), ORIENTATION_HORIZONTAL, Qt::AlignRight);
}

GridLine::~GridLine() {
  delete vVertices;
  delete vColors;
  delete vIndices;
  delete pLabel;
  delete pShader;
}

float GridLine::GetRelativeHeight() {
  return fRelativeHeight;
}

float GridLine::GetValue() {
  return (float) iHeight;
}

float GridLine::GetRed() {
  return vColors[0].r;
}

float GridLine::GetGreen() {
  return vColors[0].g;
}

float GridLine::GetBlue() {
  return vColors[0].b;
}

float GridLine::GetAlpha() {
  return vColors[0].a;
}

int GridLine::GetHeight() {
  return iHeight;
}

int GridLine::GetRow() {
  return iRow;
}

void GridLine::Draw(QPainter* pPainter) {
  if (fRelativeHeight <= UPPER_Y + 0.01f) {
    pPainter->setRenderHint(QPainter::Antialiasing);
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
    glLineWidth(GRID_LINE_WIDTH);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    pShader->Bind();

    glEnableVertexAttribArray(pShader->GetVertexLocation());
    glVertexAttribPointer(pShader->GetVertexLocation(), 4, GL_FLOAT, GL_FALSE, 0, vVertices);

    glEnableVertexAttribArray(pShader->GetColorLocation());
    glVertexAttribPointer(pShader->GetColorLocation(), 4, GL_FLOAT, GL_FALSE, 0, vColors);

    glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, vIndices);

    pShader->Unbind();

    glLineWidth(1.0f);
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  }
}

void GridLine::DrawLabels(QPainter* pPainter) {
  if (fRelativeHeight <= UPPER_Y + 0.01f) {
    pLabel->Draw(pPainter);
  }
}

void GridLine::ChangePosition(float fDeltaLeft, float fDeltaTop, float fDeltaBottom) {
  UNREFERENCED(fDeltaLeft);
  UNREFERENCED(fDeltaBottom);

  fRelativeHeight += fDeltaTop;

  vVertices[0] = glm::vec4(ORIGIN_X, fRelativeHeight, 0.0f, 1.0f);
  vVertices[1] = glm::vec4(UPPER_X, fRelativeHeight, 0.0f, 1.0f);

  pLabel->ChangePosition((float) GRID_LINE_TEXT_OFFSET,
    HEIGHT * (1.0f - (fRelativeHeight + 1.0f) / 2.0f));
}

void GridLine::ChangeAlpha(float fDeltaAlpha) {
  for (int i = 0; i < 2; i++) {
    vColors[i] = glm::vec4(GRID_LINE_COLOR, GRID_LINE_COLOR, GRID_LINE_COLOR, fDeltaAlpha + vColors[i].a);
  }

  pLabel->ChangeAlpha(fDeltaAlpha);
}