//
// Simple .obj viewer(vertex only)
//
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <limits>
#include <cmath>
#include <cassert>
#include <cstring>	
#include <algorithm>	

#if defined(ENABLE_ZLIB)
#include <zlib.h>
#endif

#if defined(ENABLE_ZSTD)
#include <zstd.h>
#endif

#include <GL/glew.h>

#ifdef __APPLE__
#include <OpenGL/glu.h>
#else
#include <GL/glu.h>
#endif

#include <GLFW/glfw3.h>

#include "trackball.h"

#define TINYOBJ_LOADER_OPT_IMPLEMENTATION
#include "tinyobj_loader_opt.h"

typedef struct {
  GLuint vb;    // vertex buffer
  int numTriangles;
} DrawObject;

std::vector<DrawObject> gDrawObjects;

int width = 768;
int height = 768;

double prevMouseX, prevMouseY;
bool mouseLeftPressed;
bool mouseMiddlePressed;
bool mouseRightPressed;
float curr_quat[4];
float prev_quat[4];
float eye[3], lookat[3], up[3];

GLFWwindow* window;

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);
  }
}

void CalcNormal(float N[3], float v0[3], float v1[3], float v2[3]) {
  float v10[3];
  v10[0] = v1[0] - v0[0];
  v10[1] = v1[1] - v0[1];
  v10[2] = v1[2] - v0[2];

  float v20[3];
  v20[0] = v2[0] - v0[0];
  v20[1] = v2[1] - v0[1];
  v20[2] = v2[2] - v0[2];

  N[0] = v20[1] * v10[2] - v20[2] * v10[1];
  N[1] = v20[2] * v10[0] - v20[0] * v10[2];
  N[2] = v20[0] * v10[1] - v20[1] * v10[0];

  float len2 = N[0] * N[0] + N[1] * N[1] + N[2] * N[2];
  if (len2 > 0.0f) {
    float len = sqrtf(len2);
    
    N[0] /= len;
    N[1] /= len;
  }
}

const char *mmap_file(size_t *len, const char* filename)
{
  (*len) = 0;
#ifdef _WIN32
  HANDLE file = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
  assert(file != INVALID_HANDLE_VALUE);

  HANDLE fileMapping = CreateFileMapping(file, NULL, PAGE_READONLY, 0, 0, NULL);
  assert(fileMapping != INVALID_HANDLE_VALUE);
 
  LPVOID fileMapView = MapViewOfFile(fileMapping, FILE_MAP_READ, 0, 0, 0);
  auto fileMapViewChar = (const char*)fileMapView;
  assert(fileMapView != NULL);

  LARGE_INTEGER fileSize;
  fileSize.QuadPart = 0;
  GetFileSizeEx(file, &fileSize);

  (*len) = static_cast<size_t>(fileSize.QuadPart);
  return fileMapViewChar;

#else

  FILE* f = fopen(filename, "rb" );
  if (!f) {
    fprintf(stderr, "Failed to open file : %s\n", filename);
    return nullptr;
  }
  fseek(f, 0, SEEK_END);
  long fileSize = ftell(f);
  fclose(f);

  if (fileSize < 16) {
    fprintf(stderr, "Empty or invalid .obj : %s\n", filename);
    return nullptr;
  }

  struct stat sb;
  char *p;
  int fd;

  fd = open (filename, O_RDONLY);
  if (fd == -1) {
    perror ("open");
    return nullptr;
  }

  if (fstat (fd, &sb) == -1) {
    perror ("fstat");
    return nullptr;
  }

  if (!S_ISREG (sb.st_mode)) {
    fprintf (stderr, "%s is not a file\n", "lineitem.tbl");
    return nullptr;
  }

  p = (char*)mmap (0, fileSize, PROT_READ, MAP_SHARED, fd, 0);

  if (p == MAP_FAILED) {
    perror ("mmap");
    return nullptr;
  }

  if (close (fd) == -1) {
    perror ("close");
    return nullptr;
  }

  (*len) = fileSize;

  return p;
  
#endif
}

bool gz_load(std::vector<char>* buf, const char* filename)
{
#ifdef ENABLE_ZLIB
    gzFile file;
    file = gzopen (filename, "r");
    if (! file) {
        fprintf (stderr, "gzopen of '%s' failed: %s.\n", filename,
                 strerror (errno));
        exit (EXIT_FAILURE);
        return false;
    }
    while (1) {
        int err;                    
        int bytes_read;
        unsigned char buffer[1024];
        bytes_read = gzread (file, buffer, 1024);
        buf->insert(buf->end(), buffer, buffer + 1024); 
        //printf ("%s", buffer);
        if (bytes_read < 1024) {
            if (gzeof (file)) {
                break;
            }
            else {
                const char * error_string;
                error_string = gzerror (file, & err);
                if (err) {
                    fprintf (stderr, "Error: %s.\n", error_string);
                    exit (EXIT_FAILURE);
                    return false;
                }
            }
        }
    }
    gzclose (file);
    return true;
#else
  return false;
#endif
}

#ifdef ENABLE_ZSTD
static off_t fsize_X(const char *filename)
{
    struct stat st;
    if (stat(filename, &st) == 0) return st.st_size;
    /* error */
    printf("stat: %s : %s \n", filename, strerror(errno));
    exit(1);
}

static FILE* fopen_X(const char *filename, const char *instruction)
{
    FILE* const inFile = fopen(filename, instruction);
    if (inFile) return inFile;
    /* error */
    printf("fopen: %s : %s \n", filename, strerror(errno));
    exit(2);
}

static void* malloc_X(size_t size)
{
    void* const buff = malloc(size);
    if (buff) return buff;
    /* error */
    printf("malloc: %s \n", strerror(errno));
    exit(3);
}
#endif

bool zstd_load(std::vector<char>* buf, const char* filename)
{
#ifdef ENABLE_ZSTD
    off_t const buffSize = fsize_X(filename);
    FILE* const inFile = fopen_X(filename, "rb");
    void* const buffer = malloc_X(buffSize);
    size_t const readSize = fread(buffer, 1, buffSize, inFile);
    if (readSize != (size_t)buffSize) {
        printf("fread: %s : %s \n", filename, strerror(errno));
        exit(4);
    }
    fclose(inFile);

    unsigned long long const rSize = ZSTD_getDecompressedSize(buffer, buffSize);
    if (rSize==0) {
        printf("%s : original size unknown \n", filename);
        exit(5);
    }

    buf->resize(rSize);

    size_t const dSize = ZSTD_decompress(buf->data(), rSize, buffer, buffSize);

    if (dSize != rSize) {
        printf("error decoding %s : %s \n", filename, ZSTD_getErrorName(dSize));
        exit(7);
    }

    free(buffer);

    return true;
#else
  return false;
#endif
}

const char* get_file_data(size_t *len, const char* filename)
{

  const char *ext = strrchr(filename, '.');

  size_t data_len = 0;
  const char* data = nullptr;

  if (strcmp(ext, ".gz") == 0) {
    // gzipped data.

    std::vector<char> buf;
    bool ret = gz_load(&buf, filename);

    if (ret) {
      char *p = static_cast<char*>(malloc(buf.size() + 1));  // @fixme { implement deleter }
      memcpy(p, &buf.at(0), buf.size());
      p[buf.size()] = '\0';
      data = p;
      data_len = buf.size();
    }

  } else if (strcmp(ext, ".zst") == 0) {
    printf("zstd\n");
    // Zstandard data.

    std::vector<char> buf;
    bool ret = zstd_load(&buf, filename);

    if (ret) {
      char *p = static_cast<char*>(malloc(buf.size() + 1));  // @fixme { implement deleter }
      memcpy(p, &buf.at(0), buf.size());
      p[buf.size()] = '\0';
      data = p;
      data_len = buf.size();
    }
  } else {
    
    data = mmap_file(&data_len, filename);

  }

  (*len) = data_len;
  return data;
}


bool LoadObjAndConvert(float bmin[3], float bmax[3], const char* filename, int num_threads, bool verbose)
{
  tinyobj_opt::attrib_t attrib;
  std::vector<tinyobj_opt::shape_t> shapes;
  std::vector<tinyobj_opt::material_t> materials;

  auto load_t_begin = std::chrono::high_resolution_clock::now();
  size_t data_len = 0;
  const char* data = get_file_data(&data_len, filename);
  if (data == nullptr) {
    printf("failed to load file\n");
    exit(-1);
    return false;
  }
  auto load_t_end = std::chrono::high_resolution_clock::now();
  std::chrono::duration<double, std::milli> load_ms = load_t_end - load_t_begin;
  if (verbose) {
    std::cout << "filesize: " << data_len << std::endl;
    std::cout << "load time: " << load_ms.count() << " [msecs]" << std::endl;
  }


  tinyobj_opt::LoadOption option;
  option.req_num_threads = num_threads;
  option.verbose = verbose;
  bool ret = parseObj(&attrib, &shapes, &materials, data, data_len, option);

  if (!ret) {
	  std::cerr << "Failed to parse .obj" << std::endl;
	  return false;
  }
  bmin[0] = bmin[1] = bmin[2] = std::numeric_limits<float>::max();
  bmax[0] = bmax[1] = bmax[2] = -std::numeric_limits<float>::max();

  //std::cout << "vertices.size() = " << attrib.vertices.size() << std::endl;
  //std::cout << "normals.size() = " << attrib.normals.size() << std::endl;

  {
        DrawObject o;
        std::vector<float> vb; // pos(3float), normal(3float), color(3float)
        size_t face_offset = 0;
        for (size_t v = 0; v < attrib.face_num_verts.size(); v++) {
          assert(attrib.face_num_verts[v] % 3 == 0); // assume all triangle face.
          for (size_t f = 0; f < attrib.face_num_verts[v] / 3; f++) {
            tinyobj_opt::index_t idx0 = attrib.indices[face_offset+3*f+0];
            tinyobj_opt::index_t idx1 = attrib.indices[face_offset+3*f+1];
            tinyobj_opt::index_t idx2 = attrib.indices[face_offset+3*f+2];

            float v[3][3];
            for (int k = 0; k < 3; k++) {
              int f0 = idx0.vertex_index;
              int f1 = idx1.vertex_index;
              int f2 = idx2.vertex_index;
              assert(f0 >= 0);
              assert(f1 >= 0);
              assert(f2 >= 0);

              v[0][k] = attrib.vertices[3*f0+k];
              v[1][k] = attrib.vertices[3*f1+k];
              v[2][k] = attrib.vertices[3*f2+k];
              bmin[k] = std::min(v[0][k], bmin[k]);
              bmin[k] = std::min(v[1][k], bmin[k]);
              bmin[k] = std::min(v[2][k], bmin[k]);
              bmax[k] = std::max(v[0][k], bmax[k]);
              bmax[k] = std::max(v[1][k], bmax[k]);
              bmax[k] = std::max(v[2][k], bmax[k]);
            }

            float n[3][3];

            if (attrib.normals.size() > 0) { 
              int nf0 = idx0.normal_index;
              int nf1 = idx1.normal_index;
              int nf2 = idx2.normal_index;

              if (nf0 >= 0 && nf1 >= 0 && nf2 >= 0) {
                assert(3*nf0+2 < attrib.normals.size());
                assert(3*nf1+2 < attrib.normals.size());
                assert(3*nf2+2 < attrib.normals.size());
                for (int k = 0; k < 3; k++) {
                  n[0][k] = attrib.normals[3*nf0+k];
                  n[1][k] = attrib.normals[3*nf1+k];
                  n[2][k] = attrib.normals[3*nf2+k];
                }
              } else {
                // compute geometric normal
                CalcNormal(n[0], v[0], v[1], v[2]);
                n[1][0] = n[0][0]; n[1][1] = n[0][1]; n[1][2] = n[0][2];
                n[2][0] = n[0][0]; n[2][1] = n[0][1]; n[2][2] = n[0][2];
              }
            } else {
              // compute geometric normal
              CalcNormal(n[0], v[0], v[1], v[2]);
              n[1][0] = n[0][0]; n[1][1] = n[0][1]; n[1][2] = n[0][2];
              n[2][0] = n[0][0]; n[2][1] = n[0][1]; n[2][2] = n[0][2];
            }

            for (int k = 0; k < 3; k++) {
              vb.push_back(v[k][0]);
              vb.push_back(v[k][1]);
              vb.push_back(v[k][2]);
              vb.push_back(n[k][0]);
              vb.push_back(n[k][1]);
              vb.push_back(n[k][2]);
              // Use normal as color.
              float c[3] = {n[k][0], n[k][1], n[k][2]};
              float len2 = c[0] * c[0] + c[1] * c[1] + c[2] * c[2];
              if (len2 > 1.0e-6f) {
                float len = sqrtf(len2);
                
                c[0] /= len;
                c[1] /= len;
                c[2] /= len;
              }
              vb.push_back(c[0] * 0.5 + 0.5);
              vb.push_back(c[1] * 0.5 + 0.5);
              vb.push_back(c[2] * 0.5 + 0.5);
            }
          } 
          face_offset += attrib.face_num_verts[v];
        }

        o.vb = 0;
        o.numTriangles = 0;
        if (vb.size() > 0) {
          glGenBuffers(1, &o.vb);
          glBindBuffer(GL_ARRAY_BUFFER, o.vb);
          glBufferData(GL_ARRAY_BUFFER, vb.size() * sizeof(float), &vb.at(0), GL_STATIC_DRAW);
          o.numTriangles = vb.size() / 9 / 3;
        }

        gDrawObjects.push_back(o);
  }
  
  printf("bmin = %f, %f, %f\n", bmin[0], bmin[1], bmin[2]);
  printf("bmax = %f, %f, %f\n", bmax[0], bmax[1], bmax[2]);

  return true;
}

void reshapeFunc(GLFWwindow* window, int w, int h)
{
  (void)window;
  // for retinal display.
  int fb_w, fb_h;
  glfwGetFramebufferSize(window, &fb_w, &fb_h);

  glViewport(0, 0, fb_w, fb_h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(45.0, (float)w / (float)h, 0.01f, 100.0f);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  width = w;
  height = h;
}

void keyboardFunc(GLFWwindow *window, int key, int scancode, int action, int mods) {
  (void)window;
  (void)scancode;
  (void)mods;
    if(action == GLFW_PRESS || action == GLFW_REPEAT){
        // Move camera
        float mv_x = 0, mv_y = 0, mv_z = 0;
        if(key == GLFW_KEY_K) mv_x += 1;
        else if(key == GLFW_KEY_J) mv_x += -1;
        else if(key == GLFW_KEY_L) mv_y += 1;
        else if(key == GLFW_KEY_H) mv_y += -1;
        else if(key == GLFW_KEY_P) mv_z += 1;
        else if(key == GLFW_KEY_N) mv_z += -1;
        //camera.move(mv_x * 0.05, mv_y * 0.05, mv_z * 0.05);
        // Close window
        if(key == GLFW_KEY_Q || key == GLFW_KEY_ESCAPE) glfwSetWindowShouldClose(window, GL_TRUE);

        //init_frame = true;
    }
}

void clickFunc(GLFWwindow* window, int button, int action, int mods){
  (void)window;
  (void)mods;
    if(button == GLFW_MOUSE_BUTTON_LEFT){
        if(action == GLFW_PRESS){
            mouseLeftPressed = true;
            trackball(prev_quat, 0.0, 0.0, 0.0, 0.0);
        } else if(action == GLFW_RELEASE){
            mouseLeftPressed = false;
        }
    }
    if(button == GLFW_MOUSE_BUTTON_RIGHT){
        if(action == GLFW_PRESS){
            mouseRightPressed = true;
        } else if(action == GLFW_RELEASE){
            mouseRightPressed = false;
        }
    }
    if(button == GLFW_MOUSE_BUTTON_MIDDLE){
        if(action == GLFW_PRESS){
            mouseMiddlePressed = true;
        } else if(action == GLFW_RELEASE){
            mouseMiddlePressed = false;
        }
    }
}

void motionFunc(GLFWwindow* window, double mouse_x, double mouse_y){
  (void)window;
  float rotScale = 1.0f;
  float transScale = 2.0f;

    if(mouseLeftPressed){
      trackball(prev_quat,
          rotScale * (2.0f * prevMouseX - width) / (float)width,
          rotScale * (height - 2.0f * prevMouseY) / (float)height,
          rotScale * (2.0f * mouse_x - width) / (float)width,
          rotScale * (height - 2.0f * mouse_y) / (float)height);

      add_quats(prev_quat, curr_quat, curr_quat);
    } else if (mouseMiddlePressed) {
      eye[0] -= transScale * (mouse_x - prevMouseX) / (float)width;
      lookat[0] -= transScale * (mouse_x - prevMouseX) / (float)width;
      eye[1] += transScale * (mouse_y - prevMouseY) / (float)height;
      lookat[1] += transScale * (mouse_y - prevMouseY) / (float)height;
    } else if (mouseRightPressed) {
      eye[2] += transScale * (mouse_y - prevMouseY) / (float)height;
      lookat[2] += transScale * (mouse_y - prevMouseY) / (float)height;
    }

    // Update mouse point
    prevMouseX = mouse_x;
    prevMouseY = mouse_y;
}

void Draw(const std::vector<DrawObject>& drawObjects)
{
  glPolygonMode(GL_FRONT, GL_FILL);
  glPolygonMode(GL_BACK, GL_FILL);

  glEnable(GL_POLYGON_OFFSET_FILL);
  glPolygonOffset(1.0, 1.0);
  glColor3f(1.0f, 1.0f, 1.0f);
  for (size_t i = 0; i < drawObjects.size(); i++) {
    DrawObject o = drawObjects[i];
    if (o.vb < 1) {
      continue;
    }
 
    glBindBuffer(GL_ARRAY_BUFFER, o.vb);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glVertexPointer(3, GL_FLOAT, 36, (const void*)0);
    glNormalPointer(GL_FLOAT, 36, (const void*)(sizeof(float)*3));
    glColorPointer(3, GL_FLOAT, 36, (const void*)(sizeof(float)*6));

    glDrawArrays(GL_TRIANGLES, 0, 3 * o.numTriangles);
    CheckErrors("drawarrays");
  }

  // draw wireframe
  glDisable(GL_POLYGON_OFFSET_FILL);
  glPolygonMode(GL_FRONT, GL_LINE);
  glPolygonMode(GL_BACK, GL_LINE);

  glColor3f(0.0f, 0.0f, 0.4f);
  for (size_t i = 0; i < drawObjects.size(); i++) {
    DrawObject o = drawObjects[i];
    if (o.vb < 1) {
      continue;
    }
 
    glBindBuffer(GL_ARRAY_BUFFER, o.vb);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
    glVertexPointer(3, GL_FLOAT, 36, (const void*)0);
    glNormalPointer(GL_FLOAT, 36, (const void*)(sizeof(float)*3));

    glDrawArrays(GL_TRIANGLES, 0, 3 * o.numTriangles);
    CheckErrors("drawarrays");
  }
}

static void Init() {
  trackball(curr_quat, 0, 0, 0, 0);

  eye[0] = 0.0f;
  eye[1] = 0.0f;
  eye[2] = 3.0f;

  lookat[0] = 0.0f;
  lookat[1] = 0.0f;
  lookat[2] = 0.0f;

  up[0] = 0.0f;
  up[1] = 1.0f;
  up[2] = 0.0f;
}


int main(int argc, char **argv)
{
  if (argc < 2) {
    std::cout << "view input.obj <num_threads> <benchark_only> <verbose>" << std::endl;
    return 0;
  }

  bool benchmark_only = false;
  int num_threads = -1;
  bool verbose = false;

  if (argc > 2) {
    num_threads = atoi(argv[2]);
  }

  if (argc > 3) {
    benchmark_only = (atoi(argv[3]) > 0) ? true : false;
  }

  if (argc > 4) {
    verbose = true;
  }

  if (benchmark_only) {

    tinyobj_opt::attrib_t attrib;
    std::vector<tinyobj_opt::shape_t> shapes;
    std::vector<tinyobj_opt::material_t> materials;

    size_t data_len = 0;
    const char* data = get_file_data(&data_len, argv[1]);
    if (data == nullptr) {
      printf("failed to load file\n");
      exit(-1);
      return false;
    }

    if (data_len < 4) {
      printf("Empty file\n");
      exit(-1);
      return false;
    }
    printf("filesize: %d\n", (int)data_len);
    tinyobj_opt::LoadOption option;
    option.req_num_threads = num_threads;
    option.verbose = true;

    bool ret = parseObj(&attrib, &shapes, &materials, data, data_len, option);

    return ret;
  }

  Init();

  std::cout << "Initialize GLFW..." << std::endl;

  if(!glfwInit()){
    std::cerr << "Failed to initialize GLFW." << std::endl;
    return -1;
  }

  std::cout << "GLFW OK." << std::endl;


  window = glfwCreateWindow(width, height, "Obj viewer", NULL, NULL);
  if(window == NULL){
    std::cerr << "Failed to open GLFW window. " << std::endl;
    glfwTerminate();
    return 1;
  }

  glfwMakeContextCurrent(window);
  glfwSwapInterval(1);

  // Callback
  glfwSetWindowSizeCallback(window, reshapeFunc);
  glfwSetKeyCallback(window, keyboardFunc);
  glfwSetMouseButtonCallback(window, clickFunc);
  glfwSetCursorPosCallback(window, motionFunc);

  glewExperimental = true;
  if (glewInit() != GLEW_OK) {
    std::cerr << "Failed to initialize GLEW." << std::endl;
    return -1;
  }

  reshapeFunc(window, width, height);

  float bmin[3], bmax[3];
  if (false == LoadObjAndConvert(bmin, bmax, argv[1], num_threads, verbose)) {
    printf("failed to load & conv\n");
    return -1;
  }

  float maxExtent = 0.5f * (bmax[0] - bmin[0]);
  if (maxExtent < 0.5f * (bmax[1] - bmin[1])) {
    maxExtent = 0.5f * (bmax[1] - bmin[1]);
  }
  if (maxExtent < 0.5f * (bmax[2] - bmin[2])) {
    maxExtent = 0.5f * (bmax[2] - bmin[2]);
  }

  while(glfwWindowShouldClose(window) == GL_FALSE) {
    glfwPollEvents();
    glClearColor(0.1f, 0.2f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glEnable(GL_DEPTH_TEST);

    // camera & rotate
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    GLfloat mat[4][4];
    gluLookAt(eye[0], eye[1], eye[2], lookat[0], lookat[1], lookat[2], up[0], up[1], up[2]);
    build_rotmatrix(mat, curr_quat);
    glMultMatrixf(&mat[0][0]);

    // Fit to -1, 1
    glScalef(1.0f / maxExtent, 1.0f / maxExtent, 1.0f / maxExtent);

    // Centerize object.
    glTranslatef(-0.5*(bmax[0] + bmin[0]), -0.5*(bmax[1] + bmin[1]), -0.5*(bmax[2] + bmin[2]));
  
    Draw(gDrawObjects);

    glfwSwapBuffers(window);
  }

  glfwTerminate();
}
