// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "services/js/modules/gl/context.h"

#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#include "base/bind.h"
#include "gin/arguments.h"
#include "gin/array_buffer.h"
#include "gin/object_template_builder.h"
#include "gin/per_context_data.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "mojo/public/c/gles2/gles2.h"
#include "mojo/public/cpp/environment/environment.h"
#include "mojo/public/cpp/environment/logging.h"

namespace gin {
template<>
struct Converter<GLboolean> {
  static bool FromV8(v8::Isolate* isolate, v8::Handle<v8::Value> val,
                     GLboolean* out) {
    bool bool_val = false;
    if (!Converter<bool>::FromV8(isolate, val, &bool_val))
      return false;
    *out = static_cast<GLboolean>(bool_val);
    return true;
  }
};
}

namespace js {
namespace gl {

gin::WrapperInfo Context::kWrapperInfo = { gin::kEmbedderNativeGin };

gin::Handle<Context> Context::Create(
    v8::Isolate* isolate,
    mojo::Handle handle,
    v8::Handle<v8::Function> context_lost_callback) {
  return gin::CreateHandle(isolate,
                           new Context(isolate, handle, context_lost_callback));
}

void Context::BufferData(GLenum target, const gin::ArrayBufferView& buffer,
                         GLenum usage) {
  glBufferData(target, static_cast<GLsizeiptr>(buffer.num_bytes()),
               buffer.bytes(), usage);
}

void Context::CompileShader(const gin::Arguments& args, GLuint shader) {
  glCompileShader(shader);
  GLint compiled = 0;
  // TODO(ggowan): Do something similar to this for linkProgram() as well, for
  // consistency.
  glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
  if (!compiled) {
    std::string log = GetShaderInfoLog(shader);
    MOJO_LOG(WARNING) << "Shader compilation failed: " << log;
    args.ThrowTypeError(std::string("Could not compile shader: ") + log);
  }
}

GLuint Context::CreateBuffer() {
  GLuint result = 0;
  glGenBuffers(1, &result);
  return result;
}

void Context::DrawElements(GLenum mode, GLsizei count, GLenum type,
                           uint64_t indices) {
  // This looks scary, but it's what WebGL does too:
  // http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.1
  glDrawElements(mode, count, type, reinterpret_cast<void*>(indices));
}

GLint Context::GetAttribLocation(GLuint program, const std::string& name) {
  return glGetAttribLocation(program, name.c_str());
}

std::string Context::GetProgramInfoLog(GLuint program) {
  GLint info_log_length = 0;
  glGetProgramiv(program, GL_INFO_LOG_LENGTH, &info_log_length);
  if (info_log_length > 1) {
    std::string info_log(info_log_length, 0);
    glGetProgramInfoLog(program, info_log_length, NULL, &info_log.at(0));
    return info_log;
  } else {
    return std::string();
  }
}

std::string Context::GetShaderInfoLog(GLuint shader) {
  GLint info_log_length = 0;
  glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &info_log_length);
  if (info_log_length > 1) {
    std::string info_log(info_log_length, 0);
    glGetShaderInfoLog(shader, info_log_length, NULL, &info_log.at(0));
    return info_log;
  } else {
    return std::string();
  }
}

GLint Context::GetUniformLocation(GLuint program, const std::string& name) {
  return glGetUniformLocation(program, name.c_str());
}

void Context::ShaderSource(GLuint shader, const std::string& source) {
  const char* source_chars = source.c_str();
  glShaderSource(shader, 1, &source_chars, NULL);
}

void Context::UniformMatrix4fv(GLint location, GLboolean transpose,
                               const gin::ArrayBufferView& buffer) {
  glUniformMatrix4fv(location, 1, transpose,
                     static_cast<float*>(buffer.bytes()));
}

void Context::VertexAttribPointer(GLuint index, GLint size, GLenum type,
                                  GLboolean normalized, GLsizei stride,
                                  uint64_t offset) {
  glVertexAttribPointer(index, size, type, normalized, stride,
                        reinterpret_cast<void*>(offset));
}

gin::ObjectTemplateBuilder Context::GetObjectTemplateBuilder(
    v8::Isolate* isolate) {
  return gin::ObjectTemplateBuilder(isolate)
      .SetValue("ARRAY_BUFFER", GL_ARRAY_BUFFER)
      .SetValue("COLOR_BUFFER_BIT", GL_COLOR_BUFFER_BIT)
      .SetValue("DEPTH_BUFFER_BIT", GL_DEPTH_BUFFER_BIT)
      .SetValue("DEPTH_TEST", GL_DEPTH_TEST)
      .SetValue("ELEMENT_ARRAY_BUFFER", GL_ELEMENT_ARRAY_BUFFER)
      .SetValue("FLOAT", GL_FLOAT)
      .SetValue("FRAGMENT_SHADER", GL_FRAGMENT_SHADER)
      .SetValue("STATIC_DRAW", GL_STATIC_DRAW)
      .SetValue("TRIANGLES", GL_TRIANGLES)
      .SetValue("UNSIGNED_SHORT", GL_UNSIGNED_SHORT)
      .SetValue("VERTEX_SHADER", GL_VERTEX_SHADER)
      .SetMethod("attachShader", glAttachShader)
      .SetMethod("bindBuffer", glBindBuffer)
      .SetMethod("bufferData", BufferData)
      .SetMethod("clear", glClear)
      .SetMethod("clearColor", glClearColor)
      .SetMethod("compileShader", CompileShader)
      .SetMethod("createBuffer", CreateBuffer)
      .SetMethod("createProgram", glCreateProgram)
      .SetMethod("createShader", glCreateShader)
      .SetMethod("deleteShader", glDeleteShader)
      .SetMethod("drawElements", DrawElements)
      .SetMethod("enable", glEnable)
      .SetMethod("enableVertexAttribArray", glEnableVertexAttribArray)
      .SetMethod("getAttribLocation", GetAttribLocation)
      .SetMethod("getProgramInfoLog", GetProgramInfoLog)
      .SetMethod("getShaderInfoLog", GetShaderInfoLog)
      .SetMethod("getUniformLocation", GetUniformLocation)
      .SetMethod("linkProgram", glLinkProgram)
      .SetMethod("resize", base::Bind(&Context::Resize, base::Unretained(this)))
      .SetMethod("shaderSource", ShaderSource)
      .SetMethod("swapBuffers", MojoGLES2SwapBuffers)
      .SetMethod("uniformMatrix4fv", UniformMatrix4fv)
      .SetMethod("useProgram", glUseProgram)
      .SetMethod("vertexAttribPointer", VertexAttribPointer)
      .SetMethod("viewport", glViewport);
}

Context::Context(v8::Isolate* isolate,
                 mojo::Handle handle,
                 v8::Handle<v8::Function> context_lost_callback) {
  v8::Handle<v8::Context> context = isolate->GetCurrentContext();
  runner_ = gin::PerContextData::From(context)->runner()->GetWeakPtr();
  context_lost_callback_.Reset(isolate, context_lost_callback);
  context_ = MojoGLES2CreateContext(handle.value(),
                                    &ContextLostThunk,
                                    this,
                                    mojo::Environment::GetDefaultAsyncWaiter());
  MojoGLES2MakeCurrent(context_);
}

Context::~Context() {
  MojoGLES2DestroyContext(context_);
}

void Context::Resize(GLuint width, GLuint height, GLfloat scale_factor) {
  static_cast<gpu::gles2::GLES2Interface*>(
      MojoGLES2GetGLES2Interface(context_))->ResizeCHROMIUM(width,
                                                            height,
                                                            scale_factor);
}

void Context::ContextLost() {
  if (!runner_)
    return;
  gin::Runner::Scope scope(runner_.get());
  v8::Isolate* isolate = runner_->GetContextHolder()->isolate();

  v8::Handle<v8::Function> callback = v8::Local<v8::Function>::New(
      isolate, context_lost_callback_);

  runner_->Call(callback, runner_->global(), 0, NULL);
}

void Context::ContextLostThunk(void* closure) {
  static_cast<Context*>(closure)->ContextLost();
}

}  // namespace gl
}  // namespace js
