/*
The MIT License (MIT)

Copyright (c) 2015 - 2016 Light Transport Entertainment, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

#ifdef _MSC_VER
#pragma warning(disable : 4244)
#endif

#define USE_OPENGL2
#include "OpenGLWindow/OpenGLInclude.h"
#ifdef _WIN32
#include "OpenGLWindow/Win32OpenGLWindow.h"
#elif defined __APPLE__
#include "OpenGLWindow/MacOpenGLWindow.h"
#else
// assume linux
#include "OpenGLWindow/X11OpenGLWindow.h"
#endif

#ifdef _WIN32
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>
#else
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#endif

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <limits>
#include <string>
#include <vector>
#include <sstream>
#include <map>

#include <atomic>  // C++11
#include <chrono>  // C++11
#include <mutex>   // C++11
#include <thread>  // C++11

#include "imgui.h"
#include "imgui_impl_btgui.h"

#include "ImGuizmo.h"

#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable: 4201)
#endif

#include "glm/mat4x4.hpp"
#include "glm/gtc/quaternion.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/type_ptr.hpp"

#if defined(_MSC_VER)
#pragma warning(pop)
#endif

#include "nanosg.h"
#include "render-config.h"
#include "render.h"
#include "gltf-loader.h"
#include "trackball.h"

#ifdef WIN32
#ifndef NOMINMAX
#define NOMINMAX
#endif
#endif

#define SHOW_BUFFER_COLOR (0)
#define SHOW_BUFFER_NORMAL (1)
#define SHOW_BUFFER_POSITION (2)
#define SHOW_BUFFER_DEPTH (3)
#define SHOW_BUFFER_TEXCOORD (4)
#define SHOW_BUFFER_VARYCOORD (5)

b3gDefaultOpenGLWindow* window = 0;
int gWidth = 512;
int gHeight = 512;
int gMousePosX = -1, gMousePosY = -1;
bool gMouseLeftDown = false;
int gShowBufferMode = SHOW_BUFFER_COLOR;
bool gTabPressed = false;
bool gShiftPressed = false;
float gShowPositionScale = 1.0f;
float gShowDepthRange[2] = {10.0f, 20.f};
bool gShowDepthPeseudoColor = true;
float gCurrQuat[4] = {0.0f, 0.0f, 0.0f, 0.0f};
float gPrevQuat[4] = {0.0f, 0.0f, 0.0f, 0.0f};

static nanosg::Scene<float, example::Mesh<float> > gScene;
static example::Asset gAsset;
static std::vector<nanosg::Node<float, example::Mesh<float> > > gNodes;

std::atomic<bool> gRenderQuit;
std::atomic<bool> gRenderRefresh;
std::atomic<bool> gRenderCancel;
std::atomic<bool> gSceneDirty;
example::RenderConfig gRenderConfig;
std::mutex gMutex;

struct RenderLayer
{
  std::vector<float> displayRGBA;  // Accumurated image.
  std::vector<float> rgba;
  std::vector<float> auxRGBA;        // Auxiliary buffer
  std::vector<int> sampleCounts;     // Sample num counter for each pixel.
  std::vector<float> normalRGBA;     // For visualizing normal
  std::vector<float> positionRGBA;   // For visualizing position
  std::vector<float> depthRGBA;      // For visualizing depth
  std::vector<float> texCoordRGBA;   // For visualizing texcoord
  std::vector<float> varyCoordRGBA;  // For visualizing varycentric coord
};

RenderLayer gRenderLayer;

struct Camera
{
  glm::mat4 view;
  glm::mat4 projection;
};

struct ManipConfig
{
  glm::vec3 snapTranslation;
  glm::vec3 snapRotation;
  glm::vec3 snapScale;
};

void RequestRender() {
  {
    std::lock_guard<std::mutex> guard(gMutex);
    gRenderConfig.pass = 0;
  }

  gRenderRefresh = true;
  gRenderCancel = true;
}

void RenderThread() {
  {
    std::lock_guard<std::mutex> guard(gMutex);
    gRenderConfig.pass = 0;
  }

  while (1) {
    if (gRenderQuit) return;

    if (!gRenderRefresh || gRenderConfig.pass >= gRenderConfig.max_passes) {
      // Give some cycles to this thread.
      std::this_thread::sleep_for(std::chrono::milliseconds(10));
      continue;
    }

    auto startT = std::chrono::system_clock::now();

    // Initialize display buffer for the first pass.
    bool initial_pass = false;
    {
      std::lock_guard<std::mutex> guard(gMutex);
      if (gRenderConfig.pass == 0) {
        initial_pass = true;
      }
    }

    if (gSceneDirty) {
      gScene.Commit();
      gSceneDirty = false;
    }

    gRenderCancel = false;
    // gRenderCancel may be set to true in main loop.
    // Render() will repeatedly check this flag inside the rendering loop.

    bool ret =
        example::Renderer::Render(&gRenderLayer.rgba.at(0), &gRenderLayer.auxRGBA.at(0), &gRenderLayer.sampleCounts.at(0),
                         gCurrQuat, gScene, gAsset, gRenderConfig, gRenderCancel);

    if (ret) {
      std::lock_guard<std::mutex> guard(gMutex);

      gRenderConfig.pass++;
    }

    auto endT = std::chrono::system_clock::now();

    std::chrono::duration<double, std::milli> ms = endT - startT;

    // std::cout << ms.count() << " [ms]\n";
  }
}

void InitRender(example::RenderConfig* rc) {
  rc->pass = 0;

  rc->max_passes = 128;

  gRenderLayer.sampleCounts.resize(rc->width * rc->height);
  std::fill(gRenderLayer.sampleCounts.begin(), gRenderLayer.sampleCounts.end(), 0.0);

  gRenderLayer.displayRGBA.resize(rc->width * rc->height * 4);
  std::fill(gRenderLayer.displayRGBA.begin(), gRenderLayer.displayRGBA.end(), 0.0);

  gRenderLayer.rgba.resize(rc->width * rc->height * 4);
  std::fill(gRenderLayer.rgba.begin(), gRenderLayer.rgba.end(), 0.0);

  gRenderLayer.auxRGBA.resize(rc->width * rc->height * 4);
  std::fill(gRenderLayer.auxRGBA.begin(), gRenderLayer.auxRGBA.end(), 0.0);

  gRenderLayer.normalRGBA.resize(rc->width * rc->height * 4);
  std::fill(gRenderLayer.normalRGBA.begin(), gRenderLayer.normalRGBA.end(), 0.0);

  gRenderLayer.positionRGBA.resize(rc->width * rc->height * 4);
  std::fill(gRenderLayer.positionRGBA.begin(), gRenderLayer.positionRGBA.end(), 0.0);

  gRenderLayer.depthRGBA.resize(rc->width * rc->height * 4);
  std::fill(gRenderLayer.depthRGBA.begin(), gRenderLayer.depthRGBA.end(), 0.0);

  gRenderLayer.texCoordRGBA.resize(rc->width * rc->height * 4);
  std::fill(gRenderLayer.texCoordRGBA.begin(), gRenderLayer.texCoordRGBA.end(), 0.0);

  gRenderLayer.varyCoordRGBA.resize(rc->width * rc->height * 4);
  std::fill(gRenderLayer.varyCoordRGBA.begin(), gRenderLayer.varyCoordRGBA.end(), 0.0);

  rc->normalImage = &gRenderLayer.normalRGBA.at(0);
  rc->positionImage = &gRenderLayer.positionRGBA.at(0);
  rc->depthImage = &gRenderLayer.depthRGBA.at(0);
  rc->texcoordImage = &gRenderLayer.texCoordRGBA.at(0);
  rc->varycoordImage = &gRenderLayer.varyCoordRGBA.at(0);

  trackball(gCurrQuat, 0.0f, 0.0f, 0.0f, 0.0f);
}

void checkErrors(std::string desc) {
  GLenum e = glGetError();
  if (e != GL_NO_ERROR) {
    fprintf(stderr, "OpenGL error in \"%s\": %d (%d)\n", desc.c_str(), e, e);
    exit(20);
  }
}


static int CreateDisplayTextureGL(const float *data, int width,
                                   int height, int components) {
  GLuint id;                       
  glGenTextures(1, &id);           
  
  GLint last_texture;
  glGetIntegerv(GL_TEXTURE_BINDING_2D, &last_texture);
  
  glBindTexture(GL_TEXTURE_2D, id);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  
  GLenum format = GL_RGBA;
  if (components == 1) {
    format = GL_LUMINANCE;
  } else if (components == 2) {
    format = GL_LUMINANCE_ALPHA;
  } else if (components == 3) {
    format = GL_RGB;
  } else if (components == 4) {
    format = GL_RGBA;
  } else { 
    assert(0); // "Invalid components"
  } 
  
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, format,
               GL_FLOAT, data);
               
  glBindTexture(GL_TEXTURE_2D, last_texture);
  
  return static_cast<int>(id);
}

void keyboardCallback(int keycode, int state) {
  printf("hello key %d, state %d(ctrl %d)\n", keycode, state,
         window->isModifierKeyPressed(B3G_CONTROL));
  // if (keycode == 'q' && window && window->isModifierKeyPressed(B3G_SHIFT)) {
  if (keycode == 27) {
    if (window) window->setRequestExit();
  } else if (keycode == ' ') {
    // reset.
    trackball(gCurrQuat, 0.0f, 0.0f, 0.0f, 0.0f);
    // clear buffer.
    memset(gRenderLayer.rgba.data(), 0, sizeof(float) * gRenderConfig.width * gRenderConfig.height * 4);
    memset(gRenderLayer.sampleCounts.data(), 0, sizeof(int) * gRenderConfig.width * gRenderConfig.height);
  } else if (keycode == 9) {
    gTabPressed = (state == 1);
  } else if (keycode == B3G_SHIFT) {
    gShiftPressed = (state == 1);
  }

  ImGui_ImplBtGui_SetKeyState(keycode, (state == 1));

  if (keycode >= 32 && keycode <= 126) {
    if (state == 1) {
      ImGui_ImplBtGui_SetChar(keycode);
    }
  }
}

void mouseMoveCallback(float x, float y) {

  if (gMouseLeftDown) {
    if (ImGuizmo::IsOver() || ImGuizmo::IsUsing()) {
    } else {
      float w = static_cast<float>(gRenderConfig.width);
      float h = static_cast<float>(gRenderConfig.height);

      float y_offset = gHeight - h;

      if (gTabPressed) {
        const float dolly_scale = 0.1f;
        gRenderConfig.eye[2] += dolly_scale * (gMousePosY - y);
        gRenderConfig.look_at[2] += dolly_scale * (gMousePosY - y);
      } else if (gShiftPressed) {
        const float trans_scale = 0.02f;
        gRenderConfig.eye[0] += trans_scale * (gMousePosX - x);
        gRenderConfig.eye[1] -= trans_scale * (gMousePosY - y);
        gRenderConfig.look_at[0] += trans_scale * (gMousePosX - x);
        gRenderConfig.look_at[1] -= trans_scale * (gMousePosY - y);

      } else {
        // Adjust y.
        trackball(gPrevQuat, (2.f * gMousePosX - w) / (float)w,
                  (h - 2.f * (gMousePosY - y_offset)) / (float)h,
                  (2.f * x - w) / (float)w,
                  (h - 2.f * (y - y_offset)) / (float)h);
        add_quats(gPrevQuat, gCurrQuat, gCurrQuat);
      }
      RequestRender();
    }
  }

  gMousePosX = (int)x;
  gMousePosY = (int)y;
}

void mouseButtonCallback(int button, int state, float x, float y) {
  (void)x;
  (void)y;
  ImGui_ImplBtGui_SetMouseButtonState(button, (state == 1));

  ImGuiIO& io = ImGui::GetIO();
  if (io.WantCaptureMouse || io.WantCaptureKeyboard) {
    return;
  }

  // left button
  if (button == 0) {
    if (state) {
      gMouseLeftDown = true;
      if (ImGuizmo::IsOver() || ImGuizmo::IsUsing()) {
      } else {
        trackball(gPrevQuat, 0.0f, 0.0f, 0.0f, 0.0f);
      }
    } else {
      gMouseLeftDown = false;
      if (ImGuizmo::IsOver() || ImGuizmo::IsUsing()) {
        gSceneDirty = true;
        RequestRender();
      }
    }
  }
}

void resizeCallback(float width, float height) {
  //GLfloat h = (GLfloat)height / (GLfloat)width;
  GLfloat xmax, znear, zfar;

  znear = 1.0f;
  zfar = 1000.0f;
  xmax = znear * 0.5f;

  gWidth = static_cast<int>(width);
  gHeight = static_cast<int>(height);
}

inline float pesudoColor(float v, int ch) {
  if (ch == 0) {  // red
    if (v <= 0.5f)
      return 0.f;
    else if (v < 0.75f)
      return (v - 0.5f) / 0.25f;
    else
      return 1.f;
  } else if (ch == 1) {  // green
    if (v <= 0.25f)
      return v / 0.25f;
    else if (v < 0.75f)
      return 1.f;
    else
      return 1.f - (v - 0.75f) / 0.25f;
  } else if (ch == 2) {  // blue
    if (v <= 0.25f)
      return 1.f;
    else if (v < 0.5f)
      return 1.f - (v - 0.25f) / 0.25f;
    else
      return 0.f;
  } else {  // alpha
    return 1.f;
  }
}

void UpdateDisplayTextureGL(GLint tex_id, int width, int height) {
  if (tex_id < 0) {
    // ???
    return;
  }

  std::vector<float> buf;
  buf.resize(width * height * 4);

  if (gShowBufferMode == SHOW_BUFFER_COLOR) {
    // normalize
    for (size_t i = 0; i < buf.size() / 4; i++) {
      buf[4 * i + 0] = gRenderLayer.rgba[4 * i + 0];
      buf[4 * i + 1] = gRenderLayer.rgba[4 * i + 1];
      buf[4 * i + 2] = gRenderLayer.rgba[4 * i + 2];
      buf[4 * i + 3] = gRenderLayer.rgba[4 * i + 3];
      if (gRenderLayer.sampleCounts[i] > 0) {
        buf[4 * i + 0] /= static_cast<float>(gRenderLayer.sampleCounts[i]);
        buf[4 * i + 1] /= static_cast<float>(gRenderLayer.sampleCounts[i]);
        buf[4 * i + 2] /= static_cast<float>(gRenderLayer.sampleCounts[i]);
        buf[4 * i + 3] /= static_cast<float>(gRenderLayer.sampleCounts[i]);
      }
    }
  } else if (gShowBufferMode == SHOW_BUFFER_NORMAL) {
    for (size_t i = 0; i < buf.size(); i++) {
      buf[i] = gRenderLayer.normalRGBA[i];
    }
  } else if (gShowBufferMode == SHOW_BUFFER_POSITION) {
    for (size_t i = 0; i < buf.size(); i++) {
      buf[i] = gRenderLayer.positionRGBA[i] * gShowPositionScale;
    }
  } else if (gShowBufferMode == SHOW_BUFFER_DEPTH) {
    float d_min = std::min(gShowDepthRange[0], gShowDepthRange[1]);
    float d_diff = fabsf(gShowDepthRange[1] - gShowDepthRange[0]);
    d_diff = std::max(d_diff, std::numeric_limits<float>::epsilon());
    for (size_t i = 0; i < buf.size(); i++) {
      float v = (gRenderLayer.depthRGBA[i] - d_min) / d_diff;
      if (gShowDepthPeseudoColor) {
        buf[i] = pesudoColor(v, i % 4);
      } else {
        buf[i] = v;
      }
    }
  } else if (gShowBufferMode == SHOW_BUFFER_TEXCOORD) {
    for (size_t i = 0; i < buf.size(); i++) {
      buf[i] = gRenderLayer.texCoordRGBA[i];
    }
  } else if (gShowBufferMode == SHOW_BUFFER_VARYCOORD) {
    for (size_t i = 0; i < buf.size(); i++) {
      buf[i] = gRenderLayer.varyCoordRGBA[i];
    }
  }

  // Flip Y
  std::vector<float> disp;
  disp.resize(width * height * 4);
  {
    for (size_t y = 0; y < height; y++) {
      memcpy(&disp[4 * (y * width)], &buf[4 * ((height - y - 1) * width)], sizeof(float) * 4 * width);
    }
  
  }

  glBindTexture(GL_TEXTURE_2D, tex_id);
  glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_FLOAT, disp.data());
  glBindTexture(GL_TEXTURE_2D, 0);

  //glRasterPos2i(-1, -1);
  //glDrawPixels(width, height, GL_RGBA, GL_FLOAT,
  //             static_cast<const GLvoid*>(&buf.at(0)));
}

void EditTransform(const ManipConfig &config, const Camera& camera, glm::mat4& matrix)
{
  static ImGuizmo::OPERATION mCurrentGizmoOperation(ImGuizmo::ROTATE);
  static ImGuizmo::MODE mCurrentGizmoMode(ImGuizmo::WORLD);
  if (ImGui::IsKeyPressed(90))
    mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
  if (ImGui::IsKeyPressed(69))
    mCurrentGizmoOperation = ImGuizmo::ROTATE;
  if (ImGui::IsKeyPressed(82)) // r Key
    mCurrentGizmoOperation = ImGuizmo::SCALE;
  if (ImGui::RadioButton("Translate", mCurrentGizmoOperation == ImGuizmo::TRANSLATE))
    mCurrentGizmoOperation = ImGuizmo::TRANSLATE;
  ImGui::SameLine();
  if (ImGui::RadioButton("Rotate", mCurrentGizmoOperation == ImGuizmo::ROTATE))
    mCurrentGizmoOperation = ImGuizmo::ROTATE;
  ImGui::SameLine();
  if (ImGui::RadioButton("Scale", mCurrentGizmoOperation == ImGuizmo::SCALE))
    mCurrentGizmoOperation = ImGuizmo::SCALE;
  float matrixTranslation[3], matrixRotation[3], matrixScale[3];
  ImGuizmo::DecomposeMatrixToComponents(&matrix[0][0], matrixTranslation, matrixRotation, matrixScale);
  ImGui::InputFloat3("Tr", matrixTranslation, 3);
  ImGui::InputFloat3("Rt", matrixRotation, 3);
  ImGui::InputFloat3("Sc", matrixScale, 3);
  ImGuizmo::RecomposeMatrixFromComponents(matrixTranslation, matrixRotation, matrixScale, &matrix[0][0]);

  if (mCurrentGizmoOperation != ImGuizmo::SCALE)
  {
    if (ImGui::RadioButton("Local", mCurrentGizmoMode == ImGuizmo::LOCAL))
      mCurrentGizmoMode = ImGuizmo::LOCAL;
    ImGui::SameLine();
    if (ImGui::RadioButton("World", mCurrentGizmoMode == ImGuizmo::WORLD))
      mCurrentGizmoMode = ImGuizmo::WORLD;
  }
  static bool useSnap(false);
  if (ImGui::IsKeyPressed(83))
    useSnap = !useSnap;
  ImGui::Checkbox("", &useSnap);
  ImGui::SameLine();
  glm::vec3 snap;
  switch (mCurrentGizmoOperation)
  {
  case ImGuizmo::TRANSLATE:
    snap = config.snapTranslation;
    ImGui::InputFloat3("Snap", &snap.x);
    break;
  case ImGuizmo::ROTATE:
    snap = config.snapRotation;
    ImGui::InputFloat("Angle Snap", &snap.x);
    break;
  case ImGuizmo::SCALE:
    snap = config.snapScale;
    ImGui::InputFloat("Scale Snap", &snap.x);
    break;
  }
  ImGuiIO& io = ImGui::GetIO();
  ImGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y);
  ImGuizmo::Manipulate(&camera.view[0][0], &camera.projection[0][0], mCurrentGizmoOperation, mCurrentGizmoMode, &matrix[0][0], NULL, useSnap ? &snap.x : NULL);
}

void DrawMesh(const example::Mesh<float> *mesh)
{
  // TODO(LTE): Use vertex array or use display list.

  glBegin(GL_TRIANGLES);

  if (!mesh->facevarying_normals.empty()) {
    for (size_t i = 0; i < mesh->faces.size() / 3; i++) {
      unsigned int f0 = mesh->faces[3 * i + 0];
      unsigned int f1 = mesh->faces[3 * i + 1];
      unsigned int f2 = mesh->faces[3 * i + 2];

      glNormal3f(mesh->facevarying_normals[9 * i + 0],
                 mesh->facevarying_normals[9 * i + 1],
                 mesh->facevarying_normals[9 * i + 2]);
      glVertex3f(mesh->vertices[3 * f0 + 0],
                 mesh->vertices[3 * f0 + 1],
                 mesh->vertices[3 * f0 + 2]);
      glNormal3f(mesh->facevarying_normals[9 * i + 3],
                 mesh->facevarying_normals[9 * i + 4],
                 mesh->facevarying_normals[9 * i + 5]);
      glVertex3f(mesh->vertices[3 * f1 + 0],
                 mesh->vertices[3 * f1 + 1],
                 mesh->vertices[3 * f1 + 2]);
      glNormal3f(mesh->facevarying_normals[9 * i + 6],
                 mesh->facevarying_normals[9 * i + 7],
                 mesh->facevarying_normals[9 * i + 8]);
      glVertex3f(mesh->vertices[3 * f2 + 0],
                 mesh->vertices[3 * f2 + 1],
                 mesh->vertices[3 * f2 + 2]);
    }

  } else {
    for (size_t i = 0; i < mesh->faces.size() / 3; i++) {
      unsigned int f0 = mesh->faces[3 * i + 0];
      unsigned int f1 = mesh->faces[3 * i + 1];
      unsigned int f2 = mesh->faces[3 * i + 2];

      glVertex3f(mesh->vertices[3 * f0 + 0],
                 mesh->vertices[3 * f0 + 1],
                 mesh->vertices[3 * f0 + 2]);
      glVertex3f(mesh->vertices[3 * f1 + 0],
                 mesh->vertices[3 * f1 + 1],
                 mesh->vertices[3 * f1 + 2]);
      glVertex3f(mesh->vertices[3 * f2 + 0],
                 mesh->vertices[3 * f2 + 1],
                 mesh->vertices[3 * f2 + 2]);
    }
  }

  glEnd(); 
}

void DrawNode(const nanosg::Node<float, example::Mesh<float> > &node)
{
  glPushMatrix();
  glMultMatrixf(node.GetLocalXformPtr());

  if (node.GetMesh()) {
    DrawMesh(node.GetMesh());
  }

  for (size_t i = 0; i < node.GetChildren().size(); i++) {
    DrawNode(node.GetChildren()[i]);
  }

  glPopMatrix();
}

// Draw scene with OpenGL
void DrawScene(const nanosg::Scene<float, example::Mesh<float> > &scene, const Camera &camera)
{
  glEnable(GL_DEPTH_TEST);

  glEnable(GL_LIGHTING);
  glEnable(GL_LIGHT0);
  glEnable(GL_LIGHT1);

  // FIXME(LTE): Use scene bounding box.
  const float light0_pos[4] = {1000.0f, 1000.0f, 1000.0f, 0.0f};
  const float light1_pos[4] = {-1000.0f, -1000.0f, -1000.0f, 0.0f};

  const float light_diffuse[4] = {0.5f, 0.5f, 0.5f, 1.0f};

  glLightfv(GL_LIGHT0, GL_POSITION, &light0_pos[0]);
  glLightfv(GL_LIGHT0, GL_DIFFUSE,  &light_diffuse[0]);
  glLightfv(GL_LIGHT1, GL_POSITION, &light1_pos[0]);
  glLightfv(GL_LIGHT1, GL_DIFFUSE,  &light_diffuse[0]);

  const std::vector<nanosg::Node<float, example::Mesh<float> > > &root_nodes = scene.GetNodes(); 

  glMatrixMode(GL_PROJECTION);
  glPushMatrix();
  glLoadMatrixf(&camera.projection[0][0]);
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  glLoadMatrixf(&camera.view[0][0]);

  for (size_t i = 0; i < root_nodes.size(); i++) {
    DrawNode(root_nodes[i]);
  }

  glMatrixMode(GL_PROJECTION);
  glPopMatrix();
  glMatrixMode(GL_MODELVIEW);
  glPopMatrix();

  glDisable(GL_LIGHT0);
  glDisable(GL_LIGHT1);
  glDisable(GL_LIGHTING);
  glDisable(GL_DEPTH_TEST);

}

void BuildSceneItems(
  std::vector<std::string> *display_names,
  std::vector<std::string> *names,
  const nanosg::Node<float, example::Mesh<float> > &node,
  int indent)
{
  if (node.GetName().empty()) {
    // Skip a node with empty name.
    return;
  }

  std::stringstream ss;
  for (int i = 0; i < indent; i++) {
    ss << " ";
  }

  ss << node.GetName();
  std::string display_name = ss.str();

  display_names->push_back(display_name);
  names->push_back(node.GetName());
    
  for (size_t i = 0; i < node.GetChildren().size(); i++) {
    BuildSceneItems(display_names, names, node.GetChildren()[i], indent + 1);
  }

}

int main(int argc, char** argv) {
  std::string config_filename = "config.json";

  if (argc > 1) {
    config_filename = argv[1];
  }

  // load config
  {
    bool ret =
        example::LoadRenderConfig(&gRenderConfig, config_filename.c_str());
    if (!ret) {
      std::cerr << "Failed to load [ " << config_filename << " ]" << std::endl;
      return -1;
    }
  }

  // construct the scene
  {
    std::vector<example::Mesh<float> > meshes;
    std::vector<example::Material> materials;
    std::vector<example::Texture> textures;

    bool ret = LoadGLTF(gRenderConfig.gltf_filename, gRenderConfig.scene_scale, &meshes, &materials, &textures);
    if (!ret) {
      std::cerr << "Failed to load glTF [ " << gRenderConfig.gltf_filename << " ]" << std::endl;
      return -1;
    }

    gAsset.materials = materials;
    gAsset.textures = textures;

    for (size_t n = 0; n < meshes.size(); n++) {
      size_t mesh_id = gAsset.meshes.size();
      gAsset.meshes.push_back(meshes[mesh_id]);
    }

    for (size_t n = 0; n < gAsset.meshes.size(); n++) {

      nanosg::Node<float, example::Mesh<float> > node(&gAsset.meshes[n]);
      node.SetName(meshes[n].name);
      node.SetLocalXform(meshes[n].pivot_xform); // Use mesh's pivot transform as node's local transform.
      gNodes.push_back(node);
     
      gScene.AddNode(node);
    }

    if (!gScene.Commit()) {
      std::cerr << "Failed to commit the scene." << std::endl;
      return -1;
    }

    float bmin[3], bmax[3];
    gScene.GetBoundingBox(bmin, bmax);
    printf("  # of nodes               : %d\n", int(gNodes.size()));
    printf("  Scene Bmin               : %f, %f, %f\n", bmin[0], bmin[1], bmin[2]);
    printf("  Scene Bmax               : %f, %f, %f\n", bmax[0], bmax[1], bmax[2]);

  }
  
  std::vector<const char *> imgui_node_names;
  std::vector<std::string> display_node_names;
  std::vector<std::string> node_names;
  std::map<int, nanosg::Node<float, example::Mesh<float> > *> node_map;

  {
    for (size_t i = 0; i < gScene.GetNodes().size(); i++) {
      BuildSceneItems(&display_node_names, &node_names, gScene.GetNodes()[i], /* indent */0);
    }

    // List of strings for imgui.
    // Assume nodes in the scene does not change.
    for (size_t i = 0; i < display_node_names.size(); i++) {
      //std::cout << "name : " << display_node_names[i] << std::endl;
      imgui_node_names.push_back(display_node_names[i].c_str());
    }

    // Construct list index <-> Node ptr map.
    for (size_t i = 0; i < node_names.size(); i++) {
      nanosg::Node<float, example::Mesh<float> > *node;

      if (gScene.FindNode(node_names[i], &node)) {
        //std::cout << "id : " << i << ", name : " << node_names[i] << std::endl;
        node_map[i] = node;
      }
    }
  }


  window = new b3gDefaultOpenGLWindow;
  b3gWindowConstructionInfo ci;
#ifdef USE_OPENGL2
  ci.m_openglVersion = 2;
#endif
  ci.m_width = 1024;
  ci.m_height = 800;
  window->createWindow(ci);

  window->setWindowTitle("view");

#ifndef __APPLE__
#ifndef _WIN32
  // some Linux implementations need the 'glewExperimental' to be true
  glewExperimental = GL_TRUE;
#endif
  if (glewInit() != GLEW_OK) {
    fprintf(stderr, "Failed to initialize GLEW\n");
    exit(-1);
  }

  if (!GLEW_VERSION_2_1) {
    fprintf(stderr, "OpenGL 2.1 is not available\n");
    exit(-1);
  }
#endif

  InitRender(&gRenderConfig);

  checkErrors("init");

  window->setMouseButtonCallback(mouseButtonCallback);
  window->setMouseMoveCallback(mouseMoveCallback);
  checkErrors("mouse");
  window->setKeyboardCallback(keyboardCallback);
  checkErrors("keyboard");
  window->setResizeCallback(resizeCallback);
  checkErrors("resize");

  ImGui_ImplBtGui_Init(window);

  ImGuiIO& io = ImGui::GetIO();
  io.Fonts->AddFontDefault();
  //io.Fonts->AddFontFromFileTTF("./DroidSans.ttf", 15.0f);

  glm::mat4 projection(1.0f);
  glm::mat4 view(1.0f);
  glm::mat4 matrix(1.0f);

  Camera camera;

  std::thread renderThread(RenderThread);

  // Trigger initial rendering request
  RequestRender();

  while (!window->requestedExit()) {
    window->startRendering();

    checkErrors("begin frame");

    ImGui_ImplBtGui_NewFrame(gMousePosX, gMousePosY);

    ImGuizmo::BeginFrame();
    ImGuizmo::Enable(true);

    //ImGuiIO &io = ImGui::GetIO();
    ImGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y);

    ImGui::Begin("UI");
    {
      static float col[3] = {0, 0, 0};
      static float f = 0.0f;
      // if (ImGui::ColorEdit3("color", col)) {
      //  RequestRender();
      //}
      // ImGui::InputFloat("intensity", &f);
      if (ImGui::InputFloat3("eye", gRenderConfig.eye)) {
        RequestRender();
      }
      if (ImGui::InputFloat3("up", gRenderConfig.up)) {
        RequestRender();
      }
      if (ImGui::InputFloat3("look_at", gRenderConfig.look_at)) {
        RequestRender();
      }

      ImGui::RadioButton("color", &gShowBufferMode, SHOW_BUFFER_COLOR);
      ImGui::SameLine();
      ImGui::RadioButton("normal", &gShowBufferMode, SHOW_BUFFER_NORMAL);
      ImGui::SameLine();
      ImGui::RadioButton("position", &gShowBufferMode, SHOW_BUFFER_POSITION);
      ImGui::SameLine();
      ImGui::RadioButton("depth", &gShowBufferMode, SHOW_BUFFER_DEPTH);
      ImGui::SameLine();
      ImGui::RadioButton("texcoord", &gShowBufferMode, SHOW_BUFFER_TEXCOORD);
      ImGui::SameLine();
      ImGui::RadioButton("varycoord", &gShowBufferMode, SHOW_BUFFER_VARYCOORD);

      ImGui::InputFloat("show pos scale", &gShowPositionScale);

      ImGui::InputFloat2("show depth range", gShowDepthRange);
      ImGui::Checkbox("show depth pesudo color", &gShowDepthPeseudoColor);
    }

    ImGui::End();

    glViewport(0, 0, window->getWidth(), window->getHeight());
    glClearColor(0.0f, 0.1f, 0.2f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

    checkErrors("clear");


    // Render display window
    {
      static GLint gl_texid = -1;
      if (gl_texid < 0) {
        gl_texid = CreateDisplayTextureGL(NULL, gRenderConfig.width, gRenderConfig.height, 4);
      }

      // Refresh texture until rendering finishes.
      if (gRenderConfig.pass < gRenderConfig.max_passes) {
        // FIXME(LTE): Do not update GL texture frequently.
        UpdateDisplayTextureGL(gl_texid, gRenderConfig.width, gRenderConfig.height);
      }

      ImGui::Begin("Render");
      ImTextureID tex_id = reinterpret_cast<void *>(
                    static_cast<intptr_t>(gl_texid));
      ImGui::Image(tex_id, ImVec2(256, 256), ImVec2(0, 0),
                   ImVec2(1, 1));// Setup camera and draw imguizomo

      ImGui::End();
  
    }

    // scene graph tree
    glm::mat4 node_matrix;
    static int node_selected = 0;
    {
      ImGui::Begin("Scene");

      ImGui::ListBox("Node list", &node_selected, imgui_node_names.data(), imgui_node_names.size(), 16);
      node_matrix = glm::make_mat4(node_map[node_selected]->GetLocalXformPtr());

      ImGui::End();
    }

    {
      ImGui::Begin("Transform");

      static ImGuizmo::OPERATION guizmo_op(ImGuizmo::ROTATE);
      static ImGuizmo::MODE guizmo_mode(ImGuizmo::WORLD);

      glm::vec3 eye, lookat, up;
      eye[0] = gRenderConfig.eye[0];
      eye[1] = gRenderConfig.eye[1];
      eye[2] = gRenderConfig.eye[2];

      lookat[0] = gRenderConfig.look_at[0];
      lookat[1] = gRenderConfig.look_at[1];
      lookat[2] = gRenderConfig.look_at[2];

      up[0] = gRenderConfig.up[0];
      up[1] = gRenderConfig.up[1];
      up[2] = gRenderConfig.up[2];

      // NOTE(LTE): w, then (x,y,z) for glm::quat.
      glm::quat rot = glm::quat(gCurrQuat[3], gCurrQuat[0], gCurrQuat[1], gCurrQuat[2]);
      glm::mat4 rm = glm::mat4_cast(rot);

      view = glm::lookAt(eye, lookat, up) * glm::inverse(glm::mat4_cast(rot));
      projection = glm::perspective (45.0f, float(window->getWidth()) / float(window->getHeight()), 0.01f, 1000.0f);

      camera.view = view;
      camera.projection = projection;
      ManipConfig manip_config;

      EditTransform(manip_config, camera, node_matrix);

      float mat[4][4];
      memcpy(mat, &node_matrix[0][0], sizeof(float) * 16);
      node_map[node_selected]->SetLocalXform(mat);

      checkErrors("edit_transform");
 
      ImGui::End();
    }

    // Draw scene in OpenGL
    DrawScene(gScene, camera);

    // Draw imgui
    ImGui::Render();

    checkErrors("im render");

    window->endRendering();

    // Give some cycles to this thread.
    std::this_thread::sleep_for(std::chrono::milliseconds(16));
  }

  {
    gRenderCancel = true;
    gRenderQuit = true;
    renderThread.join();
  }

  ImGui_ImplBtGui_Shutdown();
  delete window;

  return EXIT_SUCCESS;
}
