#include <poly/Log.h>
#include <TestWorker.h>

using namespace poly;

static const char* WORKER_VS = ""
  "#version 330\n"
  ""
  " const vec2[] pos = vec2[4]("
  "   vec2(-1.0, 1.0),"
  "   vec2(-1.0, -1.0),"
  "   vec2(1.0, 1.0),"
  "   vec2(1.0, -1.0)"
  "   );"
  ""
  "const vec2 tex[] = vec2[4]("
  "  vec2(0.0, 1.0), "
  "  vec2(0.0, 0.0), "
  "  vec2(1.0, 1.0), "
  "  vec2(1.0, 0.0)  "
  ");"
  ""
  "out vec2 v_tex;"
  ""
  "void main() { "
  "  gl_Position = vec4(pos[gl_VertexID], 0.0, 1.0);"
  "  v_tex = tex[gl_VertexID];"
  "};"
  "";

static const char* WORKER_FS = ""
  "#version 330\n"
  ""
  "uniform sampler2D u_tex;"
  "in vec2 v_tex;"
  "layout (location = 0) out vec4 fragcolor;"
  ""
  "void main() {"
  ""
  "  vec4 src = texture(u_tex, v_tex); "
  "  src.r += 0.01;"
  "  src.a = 1.0;"
  "  fragcolor = src;"
  "}"
  "";

TestWorker::TestWorker()
  :vert(0)
  ,frag(0)
  ,prog(0)
  ,vao(0)
  ,u_tex(-1)
{
  
}

int TestWorker::init() {
  
  if (0 != vert) {
    SX_ERROR("Cannot initialize the TestWorker because it's already initialized.");
    return -1;
  }

  vert = rx_create_shader(GL_VERTEX_SHADER, WORKER_VS);
  frag = rx_create_shader(GL_FRAGMENT_SHADER, WORKER_FS);
  prog = rx_create_program(vert, frag, true);

  glUseProgram(prog);

  u_tex = glGetUniformLocation(prog, "u_tex");

  if (-1 == u_tex) {
    SX_ERROR("u_tex < 0, not used in shader?");
    return -2;
  }

  glUniform1i(u_tex, 0);

  glGenVertexArrays(1, &vao);
  if (0 == vao) {
    SX_ERROR("Failed to create the vao.");
    return -3;
  }
  
  return 0;
}

int TestWorker::performWork(GLuint sourceTexture) {
  
  if (0 == sourceTexture) {
    SX_ERROR("Given texture id is invald.");
    return -1;
  }

  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_2D, sourceTexture);

  glUseProgram(prog);
  glBindVertexArray(vao);
  glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

  return 0;
}