// Copyright (c) 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 <GLES2/gl2.h>
#include <math.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include "matrix.h"
#include "ppapi/cpp/graphics_3d.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/var.h"
#include "ppapi/cpp/var_array.h"
#include "ppapi/lib/gl/gles2/gl2ext_ppapi.h"
#include "ppapi/utility/completion_callback_factory.h"

#ifdef WIN32
#undef PostMessage
// Allow 'this' in initializer list
#pragma warning(disable : 4355)
#endif

extern const uint8_t kRLETextureData[];
extern const size_t kRLETextureDataLength;

namespace {

const float kMinFovY = 45.0f;
const float kZNear = 1.0f;
const float kZFar = 10.0f;
const float kCameraZ = -4.0f;
const float kXAngleDelta = 2.0f;
const float kYAngleDelta = 0.5f;

const size_t kTextureDataLength = 128 * 128 * 3;  // 128x128, 3 Bytes/pixel.

// The decompressed data is written here.
uint8_t g_texture_data[kTextureDataLength];

void DecompressTexture() {
  // The image is first encoded with a very simple RLE scheme:
  //   <value0> <count0> <value1> <count1> ...
  // Because a <count> of 0 is useless, we use it to represent 256.
  //
  // It is then Base64 encoded to make it use only printable characters (it
  // stores more easily in a source file that way).
  //
  // To decompress, we have to reverse the process.
  static const uint8_t kBase64Decode[256] = {
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 62,  0,  0,  0, 63,
   52, 53, 54, 55, 56, 57, 58, 59, 60, 61,  0,  0,  0,  0,  0,  0,
    0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
   15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,  0,  0,  0,  0,  0,
    0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
   41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
  };
  const uint8_t* input = &kRLETextureData[0];
  const uint8_t* const input_end = &kRLETextureData[kRLETextureDataLength];
  uint8_t* output = &g_texture_data[0];
#ifndef NDEBUG
  const uint8_t* const output_end = &g_texture_data[kTextureDataLength];
#endif

  uint8_t decoded[4];
  int decoded_count = 0;

  while (input < input_end || decoded_count > 0) {
    if (decoded_count < 2) {
      assert(input + 4 <= input_end);
      // Grab four base-64 encoded (6-bit) bytes.
      uint32_t data = 0;
      data |= (kBase64Decode[*input++] << 18);
      data |= (kBase64Decode[*input++] << 12);
      data |= (kBase64Decode[*input++] <<  6);
      data |= (kBase64Decode[*input++]      );
      // And decode it to 3 (8-bit) bytes.
      decoded[decoded_count++] = (data >> 16) & 0xff;
      decoded[decoded_count++] = (data >>  8) & 0xff;
      decoded[decoded_count++] = (data      ) & 0xff;

      // = is the base64 end marker. Remove decoded bytes if we see any.
      if (input[-1] == '=') decoded_count--;
      if (input[-2] == '=') decoded_count--;
    }

    int value = decoded[0];
    int count = decoded[1];
    decoded_count -= 2;
    // Move the other decoded bytes (if any) down.
    decoded[0] = decoded[2];
    decoded[1] = decoded[3];

    // Expand the RLE data.
    if (count == 0)
      count = 256;
    assert(output <= output_end);
    memset(output, value, count);
    output += count;
  }
  assert(output == output_end);
}

GLuint CompileShader(GLenum type, const char* data) {
  GLuint shader = glCreateShader(type);
  glShaderSource(shader, 1, &data, NULL);
  glCompileShader(shader);

  GLint compile_status;
  glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status);
  if (compile_status != GL_TRUE) {
    // Shader failed to compile, let's see what the error is.
    char buffer[1024];
    GLsizei length;
    glGetShaderInfoLog(shader, sizeof(buffer), &length, &buffer[0]);
    fprintf(stderr, "Shader failed to compile: %s\n", buffer);
    return 0;
  }

  return shader;
}

GLuint LinkProgram(GLuint frag_shader, GLuint vert_shader) {
  GLuint program = glCreateProgram();
  glAttachShader(program, frag_shader);
  glAttachShader(program, vert_shader);
  glLinkProgram(program);

  GLint link_status;
  glGetProgramiv(program, GL_LINK_STATUS, &link_status);
  if (link_status != GL_TRUE) {
    // Program failed to link, let's see what the error is.
    char buffer[1024];
    GLsizei length;
    glGetProgramInfoLog(program, sizeof(buffer), &length, &buffer[0]);
    fprintf(stderr, "Program failed to link: %s\n", buffer);
    return 0;
  }

  return program;
}

const char kFragShaderSource[] =
    "precision mediump float;\n"
    "varying vec3 v_color;\n"
    "varying vec2 v_texcoord;\n"
    "uniform sampler2D u_texture;\n"
    "void main() {\n"
    "  gl_FragColor = texture2D(u_texture, v_texcoord);\n"
    "  gl_FragColor += vec4(v_color, 1);\n"
    "}\n";

const char kVertexShaderSource[] =
    "uniform mat4 u_mvp;\n"
    "attribute vec2 a_texcoord;\n"
    "attribute vec3 a_color;\n"
    "attribute vec4 a_position;\n"
    "varying vec3 v_color;\n"
    "varying vec2 v_texcoord;\n"
    "void main() {\n"
    "  gl_Position = u_mvp * a_position;\n"
    "  v_color = a_color;\n"
    "  v_texcoord = a_texcoord;\n"
    "}\n";

struct Vertex {
  float loc[3];
  float color[3];
  float tex[2];
};

const Vertex kCubeVerts[24] = {
  // +Z (red arrow, black tip)
  {{-1.0, -1.0, +1.0}, {0.0, 0.0, 0.0}, {1.0, 0.0}},
  {{+1.0, -1.0, +1.0}, {0.0, 0.0, 0.0}, {0.0, 0.0}},
  {{+1.0, +1.0, +1.0}, {0.5, 0.0, 0.0}, {0.0, 1.0}},
  {{-1.0, +1.0, +1.0}, {0.5, 0.0, 0.0}, {1.0, 1.0}},

  // +X (green arrow, black tip)
  {{+1.0, -1.0, -1.0}, {0.0, 0.0, 0.0}, {1.0, 0.0}},
  {{+1.0, +1.0, -1.0}, {0.0, 0.0, 0.0}, {0.0, 0.0}},
  {{+1.0, +1.0, +1.0}, {0.0, 0.5, 0.0}, {0.0, 1.0}},
  {{+1.0, -1.0, +1.0}, {0.0, 0.5, 0.0}, {1.0, 1.0}},

  // +Y (blue arrow, black tip)
  {{-1.0, +1.0, -1.0}, {0.0, 0.0, 0.0}, {1.0, 0.0}},
  {{-1.0, +1.0, +1.0}, {0.0, 0.0, 0.0}, {0.0, 0.0}},
  {{+1.0, +1.0, +1.0}, {0.0, 0.0, 0.5}, {0.0, 1.0}},
  {{+1.0, +1.0, -1.0}, {0.0, 0.0, 0.5}, {1.0, 1.0}},

  // -Z (red arrow, red tip)
  {{+1.0, +1.0, -1.0}, {0.0, 0.0, 0.0}, {1.0, 1.0}},
  {{-1.0, +1.0, -1.0}, {0.0, 0.0, 0.0}, {0.0, 1.0}},
  {{-1.0, -1.0, -1.0}, {1.0, 0.0, 0.0}, {0.0, 0.0}},
  {{+1.0, -1.0, -1.0}, {1.0, 0.0, 0.0}, {1.0, 0.0}},

  // -X (green arrow, green tip)
  {{-1.0, +1.0, +1.0}, {0.0, 0.0, 0.0}, {1.0, 1.0}},
  {{-1.0, -1.0, +1.0}, {0.0, 0.0, 0.0}, {0.0, 1.0}},
  {{-1.0, -1.0, -1.0}, {0.0, 1.0, 0.0}, {0.0, 0.0}},
  {{-1.0, +1.0, -1.0}, {0.0, 1.0, 0.0}, {1.0, 0.0}},

  // -Y (blue arrow, blue tip)
  {{+1.0, -1.0, +1.0}, {0.0, 0.0, 0.0}, {1.0, 1.0}},
  {{+1.0, -1.0, -1.0}, {0.0, 0.0, 0.0}, {0.0, 1.0}},
  {{-1.0, -1.0, -1.0}, {0.0, 0.0, 1.0}, {0.0, 0.0}},
  {{-1.0, -1.0, +1.0}, {0.0, 0.0, 1.0}, {1.0, 0.0}},
};

const GLubyte kCubeIndexes[36] = {
   2,  1,  0,  3,  2,  0,
   6,  5,  4,  7,  6,  4,
  10,  9,  8, 11, 10,  8,
  14, 13, 12, 15, 14, 12,
  18, 17, 16, 19, 18, 16,
  22, 21, 20, 23, 22, 20,
};

}  // namespace


class CubeInstance : public pp::Instance {
 public:
  explicit CubeInstance(PP_Instance instance)
      : pp::Instance(instance),
        callback_factory_(this),
        width_(0),
        height_(0),
        frag_shader_(0),
        vertex_shader_(0),
        program_(0),
        texture_loc_(0),
        position_loc_(0),
        color_loc_(0),
        mvp_loc_(0),
        x_angle_(0),
        y_angle_(0),
        animating_(true) {}

  virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
    return true;
  }

  virtual void DidChangeView(const pp::View& view) {
    int32_t new_width = view.GetRect().width();
    int32_t new_height = view.GetRect().height();

    if (context_.is_null()) {
      if (!InitGL(new_width, new_height)) {
        // failed.
        return;
      }

      InitShaders();
      InitBuffers();
      InitTexture();
      MainLoop(0);
    } else {
      // Resize the buffers to the new size of the module.
      int32_t result = context_.ResizeBuffers(new_width, new_height);
      if (result < 0) {
        fprintf(stderr,
                "Unable to resize buffers to %d x %d!\n",
                new_width,
                new_height);
        return;
      }
    }

    width_ = new_width;
    height_ = new_height;
    glViewport(0, 0, width_, height_);
  }

  virtual void HandleMessage(const pp::Var& message) {
    // A bool message sets whether the cube is animating or not.
    if (message.is_bool()) {
      animating_ = message.AsBool();
      return;
    }

    // An array message sets the current x and y rotation.
    if (!message.is_array()) {
      fprintf(stderr, "Expected array message.\n");
      return;
    }

    pp::VarArray array(message);
    if (array.GetLength() != 2) {
      fprintf(stderr, "Expected array of length 2.\n");
      return;
    }

    pp::Var x_angle_var = array.Get(0);
    if (x_angle_var.is_int()) {
      x_angle_ = x_angle_var.AsInt();
    } else if (x_angle_var.is_double()) {
      x_angle_ = x_angle_var.AsDouble();
    } else {
      fprintf(stderr, "Expected value to be an int or double.\n");
    }

    pp::Var y_angle_var = array.Get(1);
    if (y_angle_var.is_int()) {
      y_angle_ = y_angle_var.AsInt();
    } else if (y_angle_var.is_double()) {
      y_angle_ = y_angle_var.AsDouble();
    } else {
      fprintf(stderr, "Expected value to be an int or double.\n");
    }
  }

 private:
  bool InitGL(int32_t new_width, int32_t new_height) {
    if (!glInitializePPAPI(pp::Module::Get()->get_browser_interface())) {
      fprintf(stderr, "Unable to initialize GL PPAPI!\n");
      return false;
    }

    const int32_t attrib_list[] = {
      PP_GRAPHICS3DATTRIB_ALPHA_SIZE, 8,
      PP_GRAPHICS3DATTRIB_DEPTH_SIZE, 24,
      PP_GRAPHICS3DATTRIB_WIDTH, new_width,
      PP_GRAPHICS3DATTRIB_HEIGHT, new_height,
      PP_GRAPHICS3DATTRIB_NONE
    };

    context_ = pp::Graphics3D(this, attrib_list);
    if (!BindGraphics(context_)) {
      fprintf(stderr, "Unable to bind 3d context!\n");
      context_ = pp::Graphics3D();
      glSetCurrentContextPPAPI(0);
      return false;
    }

    glSetCurrentContextPPAPI(context_.pp_resource());
    return true;
  }

  void InitShaders() {
    frag_shader_ = CompileShader(GL_FRAGMENT_SHADER, kFragShaderSource);
    if (!frag_shader_)
      return;

    vertex_shader_ = CompileShader(GL_VERTEX_SHADER, kVertexShaderSource);
    if (!vertex_shader_)
      return;

    program_ = LinkProgram(frag_shader_, vertex_shader_);
    if (!program_)
      return;

    texture_loc_ = glGetUniformLocation(program_, "u_texture");
    position_loc_ = glGetAttribLocation(program_, "a_position");
    texcoord_loc_ = glGetAttribLocation(program_, "a_texcoord");
    color_loc_ = glGetAttribLocation(program_, "a_color");
    mvp_loc_ = glGetUniformLocation(program_, "u_mvp");
  }

  void InitBuffers() {
    glGenBuffers(1, &vertex_buffer_);
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
    glBufferData(GL_ARRAY_BUFFER, sizeof(kCubeVerts), &kCubeVerts[0],
                 GL_STATIC_DRAW);

    glGenBuffers(1, &index_buffer_);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(kCubeIndexes),
                 &kCubeIndexes[0], GL_STATIC_DRAW);
  }

  void InitTexture() {
    DecompressTexture();
    glGenTextures(1, &texture_);
    glBindTexture(GL_TEXTURE_2D, texture_);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexImage2D(GL_TEXTURE_2D,
                 0,
                 GL_RGB,
                 128,
                 128,
                 0,
                 GL_RGB,
                 GL_UNSIGNED_BYTE,
                 &g_texture_data[0]);
  }

  void Animate() {
    if (animating_) {
      x_angle_ = fmod(360.0f + x_angle_ + kXAngleDelta, 360.0f);
      y_angle_ = fmod(360.0f + y_angle_ + kYAngleDelta, 360.0f);

      // Send new values to JavaScript.
      pp::VarArray array;
      array.SetLength(2);
      array.Set(0, x_angle_);
      array.Set(1, y_angle_);
      PostMessage(array);
    }
  }

  void Render() {
    glClearColor(0.5, 0.5, 0.5, 1);
    glClearDepthf(1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);

    //set what program to use
    glUseProgram(program_);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture_);
    glUniform1i(texture_loc_, 0);

    //create our perspective matrix
    float mvp[16];
    float trs[16];
    float rot[16];

    identity_matrix(mvp);
    const float aspect_ratio = static_cast<float>(width_) / height_;
    float fovY = kMinFovY / aspect_ratio;
    if (fovY < kMinFovY)
      fovY = kMinFovY;

    glhPerspectivef2(&mvp[0], fovY, aspect_ratio, kZNear, kZFar);

    translate_matrix(0, 0, kCameraZ, trs);
    rotate_matrix(x_angle_, y_angle_, 0.0f, rot);
    multiply_matrix(trs, rot, trs);
    multiply_matrix(mvp, trs, mvp);
    glUniformMatrix4fv(mvp_loc_, 1, GL_FALSE, mvp);

    //define the attributes of the vertex
    glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_);
    glVertexAttribPointer(position_loc_,
                          3,
                          GL_FLOAT,
                          GL_FALSE,
                          sizeof(Vertex),
                          reinterpret_cast<void*>(offsetof(Vertex, loc)));
    glEnableVertexAttribArray(position_loc_);
    glVertexAttribPointer(color_loc_,
                          3,
                          GL_FLOAT,
                          GL_FALSE,
                          sizeof(Vertex),
                          reinterpret_cast<void*>(offsetof(Vertex, color)));
    glEnableVertexAttribArray(color_loc_);
    glVertexAttribPointer(texcoord_loc_,
                          2,
                          GL_FLOAT,
                          GL_FALSE,
                          sizeof(Vertex),
                          reinterpret_cast<void*>(offsetof(Vertex, tex)));
    glEnableVertexAttribArray(texcoord_loc_);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer_);
    glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, 0);
  }

  void MainLoop(int32_t) {
    Animate();
    Render();
    context_.SwapBuffers(
        callback_factory_.NewCallback(&CubeInstance::MainLoop));
  }

  pp::CompletionCallbackFactory<CubeInstance> callback_factory_;
  pp::Graphics3D context_;
  int32_t width_;
  int32_t height_;
  GLuint frag_shader_;
  GLuint vertex_shader_;
  GLuint program_;
  GLuint vertex_buffer_;
  GLuint index_buffer_;
  GLuint texture_;

  GLuint texture_loc_;
  GLuint position_loc_;
  GLuint texcoord_loc_;
  GLuint color_loc_;
  GLuint mvp_loc_;

  float x_angle_;
  float y_angle_;
  bool animating_;
};

class CubeModule : public pp::Module {
 public:
  CubeModule() : pp::Module() {}
  virtual ~CubeModule() {}

  virtual pp::Instance* CreateInstance(PP_Instance instance) {
    return new CubeInstance(instance);
  }
};

namespace pp {
Module* CreateModule() { return new CubeModule(); }
}  // namespace pp
