//
// Tiny glTF loader.
//
//
// The MIT License (MIT)
//
// Copyright (c) 2015 - 2016 Syoyo Fujita and many contributors.
//
// 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.

// Version:
//  - v0.9.5 Support parsing `extras` parameter.
//  - v0.9.4 Support parsing `shader`, `program` and `tecnique` thanks to
//  @lukesanantonio
//  - v0.9.3 Support binary glTF
//  - v0.9.2 Support parsing `texture`
//  - v0.9.1 Support loading glTF asset from memory
//  - v0.9.0 Initial
//
// Tiny glTF loader is using following third party libraries:
//
//  - picojson: C++ JSON library.
//  - base64: base64 decode/encode library.
//  - stb_image: Image loading library.
//
#ifndef TINY_GLTF_LOADER_H_
#define TINY_GLTF_LOADER_H_

#include <cassert>
#include <cstring>
#include <map>
#include <string>
#include <vector>

namespace tinygltf {

#define TINYGLTF_MODE_POINTS (0)
#define TINYGLTF_MODE_LINE (1)
#define TINYGLTF_MODE_LINE_LOOP (2)
#define TINYGLTF_MODE_TRIANGLES (4)
#define TINYGLTF_MODE_TRIANGLE_STRIP (5)
#define TINYGLTF_MODE_TRIANGLE_FAN (6)

#define TINYGLTF_COMPONENT_TYPE_BYTE (5120)
#define TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE (5121)
#define TINYGLTF_COMPONENT_TYPE_SHORT (5122)
#define TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT (5123)
#define TINYGLTF_COMPONENT_TYPE_INT (5124)
#define TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT (5125)
#define TINYGLTF_COMPONENT_TYPE_FLOAT (5126)
#define TINYGLTF_COMPONENT_TYPE_DOUBLE (5127)

#define TINYGLTF_TEXTURE_FILTER_NEAREST (9728)
#define TINYGLTF_TEXTURE_FILTER_LINEAR (9729)
#define TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_NEAREST (9984)
#define TINYGLTF_TEXTURE_FILTER_LINEAR_MIPMAP_NEAREST (9985)
#define TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_LINEAR (9986)
#define TINYGLTF_TEXTURE_FILTER_LINEAR_MIPMAP_LINEAR (9987)

#define TINYGLTF_TEXTURE_WRAP_RPEAT (10497)
#define TINYGLTF_TEXTURE_WRAP_CLAMP_TO_EDGE (33071)
#define TINYGLTF_TEXTURE_WRAP_MIRRORED_REPEAT (33648)

// Redeclarations of the above for technique.parameters.
#define TINYGLTF_PARAMETER_TYPE_BYTE (5120)
#define TINYGLTF_PARAMETER_TYPE_UNSIGNED_BYTE (5121)
#define TINYGLTF_PARAMETER_TYPE_SHORT (5122)
#define TINYGLTF_PARAMETER_TYPE_UNSIGNED_SHORT (5123)
#define TINYGLTF_PARAMETER_TYPE_INT (5124)
#define TINYGLTF_PARAMETER_TYPE_UNSIGNED_INT (5125)
#define TINYGLTF_PARAMETER_TYPE_FLOAT (5126)

#define TINYGLTF_PARAMETER_TYPE_FLOAT_VEC2 (35664)
#define TINYGLTF_PARAMETER_TYPE_FLOAT_VEC3 (35665)
#define TINYGLTF_PARAMETER_TYPE_FLOAT_VEC4 (35666)

#define TINYGLTF_PARAMETER_TYPE_INT_VEC2 (35667)
#define TINYGLTF_PARAMETER_TYPE_INT_VEC3 (35668)
#define TINYGLTF_PARAMETER_TYPE_INT_VEC4 (35669)

#define TINYGLTF_PARAMETER_TYPE_BOOL (35670)
#define TINYGLTF_PARAMETER_TYPE_BOOL_VEC2 (35671)
#define TINYGLTF_PARAMETER_TYPE_BOOL_VEC3 (35672)
#define TINYGLTF_PARAMETER_TYPE_BOOL_VEC4 (35673)

#define TINYGLTF_PARAMETER_TYPE_FLOAT_MAT2 (35674)
#define TINYGLTF_PARAMETER_TYPE_FLOAT_MAT3 (35675)
#define TINYGLTF_PARAMETER_TYPE_FLOAT_MAT4 (35676)

#define TINYGLTF_PARAMETER_TYPE_SAMPLER_2D (35678)

// End parameter types

#define TINYGLTF_TYPE_VEC2 (2)
#define TINYGLTF_TYPE_VEC3 (3)
#define TINYGLTF_TYPE_VEC4 (4)
#define TINYGLTF_TYPE_MAT2 (32 + 2)
#define TINYGLTF_TYPE_MAT3 (32 + 3)
#define TINYGLTF_TYPE_MAT4 (32 + 4)
#define TINYGLTF_TYPE_SCALAR (64 + 1)
#define TINYGLTF_TYPE_VECTOR (64 + 4)
#define TINYGLTF_TYPE_MATRIX (64 + 16)

#define TINYGLTF_IMAGE_FORMAT_JPEG (0)
#define TINYGLTF_IMAGE_FORMAT_PNG (1)
#define TINYGLTF_IMAGE_FORMAT_BMP (2)
#define TINYGLTF_IMAGE_FORMAT_GIF (3)

#define TINYGLTF_TEXTURE_FORMAT_ALPHA (6406)
#define TINYGLTF_TEXTURE_FORMAT_RGB (6407)
#define TINYGLTF_TEXTURE_FORMAT_RGBA (6408)
#define TINYGLTF_TEXTURE_FORMAT_LUMINANCE (6409)
#define TINYGLTF_TEXTURE_FORMAT_LUMINANCE_ALPHA (6410)

#define TINYGLTF_TEXTURE_TARGET_TEXTURE2D (3553)
#define TINYGLTF_TEXTURE_TYPE_UNSIGNED_BYTE (5121)

#define TINYGLTF_TARGET_ARRAY_BUFFER (34962)
#define TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER (34963)

#define TINYGLTF_SHADER_TYPE_VERTEX_SHADER (35633)
#define TINYGLTF_SHADER_TYPE_FRAGMENT_SHADER (35632)

typedef enum {
  NULL_TYPE = 0,
  NUMBER_TYPE = 1,
  INT_TYPE = 2,
  BOOL_TYPE = 3,
  STRING_TYPE = 4,
  ARRAY_TYPE = 5,
  BINARY_TYPE = 6,
  OBJECT_TYPE = 7
} Type;

// Simple class to represent JSON object
class Value {
 public:
  typedef std::vector<Value> Array;
  typedef std::map<std::string, Value> Object;

  Value() : type_(NULL_TYPE) {}

  explicit Value(bool b) : type_(BOOL_TYPE) { boolean_value_ = b; }
  explicit Value(int i) : type_(INT_TYPE) { int_value_ = i; }
  explicit Value(double n) : type_(NUMBER_TYPE) { number_value_ = n; }
  explicit Value(const std::string &s) : type_(STRING_TYPE) {
    string_value_ = s;
  }
  explicit Value(const unsigned char *p, size_t n) : type_(BINARY_TYPE) {
    binary_value_.resize(n);
    memcpy(binary_value_.data(), p, n);
  }
  explicit Value(const Array &a) : type_(ARRAY_TYPE) {
    array_value_ = Array(a);
  }
  explicit Value(const Object &o) : type_(OBJECT_TYPE) {
    object_value_ = Object(o);
  }

  char Type() const { return static_cast<const char>(type_); }

  bool IsBool() const { return (type_ == BOOL_TYPE); }

  bool IsInt() const { return (type_ == INT_TYPE); }

  bool IsNumber() const { return (type_ == NUMBER_TYPE); }

  bool IsString() const { return (type_ == STRING_TYPE); }

  bool IsBinary() const { return (type_ == BINARY_TYPE); }

  bool IsArray() const { return (type_ == ARRAY_TYPE); }

  bool IsObject() const { return (type_ == OBJECT_TYPE); }

  // Accessor
  template <typename T>
  const T &Get() const;
  template <typename T>
  T &Get();

  // Lookup value from an array
  const Value &Get(int idx) const {
    static Value &null_value = *(new Value());
    assert(IsArray());
    assert(idx >= 0);
    return (static_cast<size_t>(idx) < array_value_.size())
               ? array_value_[static_cast<size_t>(idx)]
               : null_value;
  }

  // Lookup value from a key-value pair
  const Value &Get(const std::string &key) const {
    static Value &null_value = *(new Value());
    assert(IsObject());
    Object::const_iterator it = object_value_.find(key);
    return (it != object_value_.end()) ? it->second : null_value;
  }

  size_t ArrayLen() const {
    if (!IsArray()) return 0;
    return array_value_.size();
  }

  // Valid only for object type.
  bool Has(const std::string &key) const {
    if (!IsObject()) return false;
    Object::const_iterator it = object_value_.find(key);
    return (it != object_value_.end()) ? true : false;
  }

  // List keys
  std::vector<std::string> Keys() const {
    std::vector<std::string> keys;
    if (!IsObject()) return keys;  // empty

    for (Object::const_iterator it = object_value_.begin();
         it != object_value_.end(); ++it) {
      keys.push_back(it->first);
    }

    return keys;
  }

 protected:
  int type_;

  int int_value_;
  double number_value_;
  std::string string_value_;
  std::vector<unsigned char> binary_value_;
  Array array_value_;
  Object object_value_;
  bool boolean_value_;
  char pad[3];

  int pad0;
};

#define TINYGLTF_VALUE_GET(ctype, var)            \
  template <>                                     \
  inline const ctype &Value::Get<ctype>() const { \
    return var;                                   \
  }                                               \
  template <>                                     \
  inline ctype &Value::Get<ctype>() {             \
    return var;                                   \
  }
TINYGLTF_VALUE_GET(bool, boolean_value_)
TINYGLTF_VALUE_GET(double, number_value_)
TINYGLTF_VALUE_GET(int, int_value_)
TINYGLTF_VALUE_GET(std::string, string_value_)
TINYGLTF_VALUE_GET(std::vector<unsigned char>, binary_value_)
TINYGLTF_VALUE_GET(Value::Array, array_value_)
TINYGLTF_VALUE_GET(Value::Object, object_value_)
#undef TINYGLTF_VALUE_GET

typedef struct {
  std::string string_value;
  std::vector<double> number_array;
} Parameter;

typedef std::map<std::string, Parameter> ParameterMap;

typedef struct {
  std::string sampler;
  std::string target_id;
  std::string target_path;
  Value extras;
} AnimationChannel;

typedef struct {
  std::string input;
  std::string interpolation;
  std::string output;
  Value extras;
} AnimationSampler;

typedef struct {
  std::string name;
  std::vector<AnimationChannel> channels;
  std::map<std::string, AnimationSampler> samplers;
  ParameterMap parameters;
  Value extras;
} Animation;

typedef struct {
  std::string name;
  int minFilter;
  int magFilter;
  int wrapS;
  int wrapT;
  int wrapR;  // TinyGLTF extension
  int pad0;
  Value extras;
} Sampler;

typedef struct {
  std::string name;
  int width;
  int height;
  int component;
  int pad0;
  std::vector<unsigned char> image;

  std::string bufferView;  // KHR_binary_glTF extenstion.
  std::string mimeType;    // KHR_binary_glTF extenstion.

  Value extras;
} Image;

typedef struct {
  int format;
  int internalFormat;
  std::string sampler;  // Required
  std::string source;   // Required
  int target;
  int type;
  std::string name;
  Value extras;
} Texture;

typedef struct {
  std::string name;
  std::string technique;
  ParameterMap values;

  Value extras;
} Material;

typedef struct {
  std::string name;
  std::string buffer;  // Required
  size_t byteOffset;   // Required
  size_t byteLength;   // default: 0
  int target;
  int pad0;
  Value extras;
} BufferView;

typedef struct {
  std::string bufferView;
  std::string name;
  size_t byteOffset;
  size_t byteStride;
  int componentType;  // One of TINYGLTF_COMPONENT_TYPE_***
  int pad0;
  size_t count;
  int type;  // One of TINYGLTF_TYPE_***
  int pad1;
  std::vector<double> minValues;  // Optional
  std::vector<double> maxValues;  // Optional
  Value extras;
} Accessor;

class Camera {
 public:
  Camera() {}
  ~Camera() {}

  std::string name;
  bool isOrthographic;  // false = perspective.

  // Some common properties.
  float aspectRatio;
  float yFov;
  float zFar;
  float zNear;
};

typedef struct {
  std::map<std::string, std::string> attributes;  // A dictionary object of
                                                  // strings, where each string
                                                  // is the ID of the accessor
                                                  // containing an attribute.
  std::string material;  // The ID of the material to apply to this primitive
                         // when rendering.
  std::string indices;   // The ID of the accessor that contains the indices.
  int mode;              // one of TINYGLTF_MODE_***
  int pad0;

  Value extras;  // "extra" property
} Primitive;

typedef struct {
  std::string name;
  std::vector<Primitive> primitives;
  Value extras;
} Mesh;

class Node {
 public:
  Node() {}
  ~Node() {}

  std::string camera;  // camera object referenced by this node.

  std::string name;
  std::vector<std::string> children;
  std::vector<double> rotation;     // length must be 0 or 4
  std::vector<double> scale;        // length must be 0 or 3
  std::vector<double> translation;  // length must be 0 or 3
  std::vector<double> matrix;       // length must be 0 or 16
  std::vector<std::string> meshes;

  Value extras;
};

typedef struct {
  std::string name;
  std::vector<unsigned char> data;
  Value extras;
} Buffer;

typedef struct {
  std::string name;
  int type;
  int pad0;
  std::vector<unsigned char> source;

  Value extras;
} Shader;

typedef struct {
  std::string name;
  std::string vertexShader;
  std::string fragmentShader;
  std::vector<std::string> attributes;

  Value extras;
} Program;

typedef struct {
  int count;
  int pad0;
  std::string node;
  std::string semantic;
  int type;
  int pad1;
  Parameter value;
} TechniqueParameter;

typedef struct {
  std::string name;
  std::string program;
  std::map<std::string, TechniqueParameter> parameters;
  std::map<std::string, std::string> attributes;
  std::map<std::string, std::string> uniforms;

  Value extras;
} Technique;

typedef struct {
  std::string generator;
  std::string version;
  std::string profile_api;
  std::string profile_version;
  bool premultipliedAlpha;
  char pad[7];
  Value extras;
} Asset;

class Scene {
 public:
  Scene() {}
  ~Scene() {}

  std::map<std::string, Accessor> accessors;
  std::map<std::string, Animation> animations;
  std::map<std::string, Buffer> buffers;
  std::map<std::string, BufferView> bufferViews;
  std::map<std::string, Material> materials;
  std::map<std::string, Mesh> meshes;
  std::map<std::string, Node> nodes;
  std::map<std::string, Texture> textures;
  std::map<std::string, Image> images;
  std::map<std::string, Shader> shaders;
  std::map<std::string, Program> programs;
  std::map<std::string, Technique> techniques;
  std::map<std::string, Sampler> samplers;
  std::map<std::string, std::vector<std::string> > scenes;  // list of nodes

  std::string defaultScene;

  Asset asset;

  Value extras;
};

enum SectionCheck {
  NO_REQUIRE = 0x00,
  REQUIRE_SCENE = 0x01,
  REQUIRE_SCENES = 0x02,
  REQUIRE_NODES = 0x04,
  REQUIRE_ACCESSORS = 0x08,
  REQUIRE_BUFFERS = 0x10,
  REQUIRE_BUFFER_VIEWS = 0x20,
  REQUIRE_ALL = 0x3f
};

class TinyGLTFLoader {
 public:
  TinyGLTFLoader() : bin_data_(NULL), bin_size_(0), is_binary_(false) {
    pad[0] = pad[1] = pad[2] = pad[3] = pad[4] = pad[5] = pad[6] = 0;
  }
  ~TinyGLTFLoader() {}

  /// Loads glTF ASCII asset from a file.
  /// Returns false and set error string to `err` if there's an error.
  bool LoadASCIIFromFile(Scene *scene, std::string *err,
                         const std::string &filename,
                         unsigned int check_sections = REQUIRE_ALL);

  /// Loads glTF ASCII asset from string(memory).
  /// `length` = strlen(str);
  /// Returns false and set error string to `err` if there's an error.
  bool LoadASCIIFromString(Scene *scene, std::string *err, const char *str,
                           const unsigned int length,
                           const std::string &base_dir,
                           unsigned int check_sections = REQUIRE_ALL);

  /// Loads glTF binary asset from a file.
  /// Returns false and set error string to `err` if there's an error.
  bool LoadBinaryFromFile(Scene *scene, std::string *err,
                          const std::string &filename,
                          unsigned int check_sections = REQUIRE_ALL);

  /// Loads glTF binary asset from memory.
  /// `length` = strlen(str);
  /// Returns false and set error string to `err` if there's an error.
  bool LoadBinaryFromMemory(Scene *scene, std::string *err,
                            const unsigned char *bytes,
                            const unsigned int length,
                            const std::string &base_dir = "",
                            unsigned int check_sections = REQUIRE_ALL);

 private:
  /// Loads glTF asset from string(memory).
  /// `length` = strlen(str);
  /// Returns false and set error string to `err` if there's an error.
  bool LoadFromString(Scene *scene, std::string *err, const char *str,
                      const unsigned int length, const std::string &base_dir,
                      unsigned int check_sections);

  const unsigned char *bin_data_;
  size_t bin_size_;
  bool is_binary_;
  char pad[7];
};

}  // namespace tinygltf

#ifdef TINYGLTF_LOADER_IMPLEMENTATION
#include <algorithm>
//#include <cassert>
#include <fstream>
#include <sstream>

#ifdef __clang__
// Disable some warnings for external files.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wfloat-equal"
#pragma clang diagnostic ignored "-Wexit-time-destructors"
#pragma clang diagnostic ignored "-Wconversion"
#pragma clang diagnostic ignored "-Wold-style-cast"
#pragma clang diagnostic ignored "-Wdouble-promotion"
#pragma clang diagnostic ignored "-Wglobal-constructors"
#pragma clang diagnostic ignored "-Wreserved-id-macro"
#pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
#pragma clang diagnostic ignored "-Wpadded"
#endif

#define PICOJSON_USE_INT64
#include "picojson/picojson.h"
#include "stb/stb_image.h"
#ifdef __clang__
#pragma clang diagnostic pop
#endif

#ifdef _WIN32
#include <Windows.h>
#else
#include <wordexp.h>
#endif

#if defined(__sparcv9)
// Big endian
#else
#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU
#define TINYGLTF_LITTLE_ENDIAN 1
#endif
#endif

namespace tinygltf {

static void swap4(unsigned int *val) {
#ifdef TINYGLTF_LITTLE_ENDIAN
  (void)val;
#else
  unsigned int tmp = *val;
  unsigned char *dst = reinterpret_cast<unsigned char *>(val);
  unsigned char *src = reinterpret_cast<unsigned char *>(&tmp);

  dst[0] = src[3];
  dst[1] = src[2];
  dst[2] = src[1];
  dst[3] = src[0];
#endif
}

static bool FileExists(const std::string &abs_filename) {
  bool ret;
#ifdef _WIN32
  FILE *fp;
  errno_t err = fopen_s(&fp, abs_filename.c_str(), "rb");
  if (err != 0) {
    return false;
  }
#else
  FILE *fp = fopen(abs_filename.c_str(), "rb");
#endif
  if (fp) {
    ret = true;
    fclose(fp);
  } else {
    ret = false;
  }

  return ret;
}

static std::string ExpandFilePath(const std::string &filepath) {
#ifdef _WIN32
  DWORD len = ExpandEnvironmentStringsA(filepath.c_str(), NULL, 0);
  char *str = new char[len];
  ExpandEnvironmentStringsA(filepath.c_str(), str, len);

  std::string s(str);

  delete[] str;

  return s;
#else

#if defined(TARGET_OS_IPHONE) || defined(TARGET_IPHONE_SIMULATOR)
  // no expansion
  std::string s = filepath;
#else
  std::string s;
  wordexp_t p;

  if (filepath.empty()) {
    return "";
  }

  // char** w;
  int ret = wordexp(filepath.c_str(), &p, 0);
  if (ret) {
    // err
    s = filepath;
    return s;
  }

  // Use first element only.
  if (p.we_wordv) {
    s = std::string(p.we_wordv[0]);
    wordfree(&p);
  } else {
    s = filepath;
  }

#endif

  return s;
#endif
}

static std::string JoinPath(const std::string &path0,
                            const std::string &path1) {
  if (path0.empty()) {
    return path1;
  } else {
    // check '/'
    char lastChar = *path0.rbegin();
    if (lastChar != '/') {
      return path0 + std::string("/") + path1;
    } else {
      return path0 + path1;
    }
  }
}

static std::string FindFile(const std::vector<std::string> &paths,
                            const std::string &filepath) {
  for (size_t i = 0; i < paths.size(); i++) {
    std::string absPath = ExpandFilePath(JoinPath(paths[i], filepath));
    if (FileExists(absPath)) {
      return absPath;
    }
  }

  return std::string();
}

// std::string GetFilePathExtension(const std::string& FileName)
//{
//    if(FileName.find_last_of(".") != std::string::npos)
//        return FileName.substr(FileName.find_last_of(".")+1);
//    return "";
//}

static std::string GetBaseDir(const std::string &filepath) {
  if (filepath.find_last_of("/\\") != std::string::npos)
    return filepath.substr(0, filepath.find_last_of("/\\"));
  return "";
}

// std::string base64_encode(unsigned char const* , unsigned int len);
std::string base64_decode(std::string const &s);

/*
   base64.cpp and base64.h

   Copyright (C) 2004-2008 René Nyffenegger

   This source code is provided 'as-is', without any express or implied
   warranty. In no event will the author be held liable for any damages
   arising from the use of this software.

   Permission is granted to anyone to use this software for any purpose,
   including commercial applications, and to alter it and redistribute it
   freely, subject to the following restrictions:

   1. The origin of this source code must not be misrepresented; you must not
      claim that you wrote the original source code. If you use this source code
      in a product, an acknowledgment in the product documentation would be
      appreciated but is not required.

   2. Altered source versions must be plainly marked as such, and must not be
      misrepresented as being the original source code.

   3. This notice may not be removed or altered from any source distribution.

   René Nyffenegger rene.nyffenegger@adp-gmbh.ch

*/

#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wexit-time-destructors"
#pragma clang diagnostic ignored "-Wglobal-constructors"
#pragma clang diagnostic ignored "-Wsign-conversion"
#pragma clang diagnostic ignored "-Wconversion"
#endif
static const std::string base64_chars =
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "abcdefghijklmnopqrstuvwxyz"
    "0123456789+/";

static inline bool is_base64(unsigned char c) {
  return (isalnum(c) || (c == '+') || (c == '/'));
}

std::string base64_decode(std::string const &encoded_string) {
  int in_len = static_cast<int>(encoded_string.size());
  int i = 0;
  int j = 0;
  int in_ = 0;
  unsigned char char_array_4[4], char_array_3[3];
  std::string ret;

  while (in_len-- && (encoded_string[in_] != '=') &&
         is_base64(encoded_string[in_])) {
    char_array_4[i++] = encoded_string[in_];
    in_++;
    if (i == 4) {
      for (i = 0; i < 4; i++)
        char_array_4[i] =
            static_cast<unsigned char>(base64_chars.find(char_array_4[i]));

      char_array_3[0] =
          (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
      char_array_3[1] =
          ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
      char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

      for (i = 0; (i < 3); i++) ret += char_array_3[i];
      i = 0;
    }
  }

  if (i) {
    for (j = i; j < 4; j++) char_array_4[j] = 0;

    for (j = 0; j < 4; j++)
      char_array_4[j] =
          static_cast<unsigned char>(base64_chars.find(char_array_4[j]));

    char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
    char_array_3[1] =
        ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
    char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

    for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
  }

  return ret;
}
#ifdef __clang__
#pragma clang diagnostic pop
#endif

static bool LoadExternalFile(std::vector<unsigned char> *out, std::string *err,
                             const std::string &filename,
                             const std::string &basedir, size_t reqBytes,
                             bool checkSize) {
  out->clear();

  std::vector<std::string> paths;
  paths.push_back(basedir);
  paths.push_back(".");

  std::string filepath = FindFile(paths, filename);
  if (filepath.empty()) {
    if (err) {
      (*err) += "File not found : " + filename + "\n";
    }
    return false;
  }

  std::ifstream f(filepath.c_str(), std::ifstream::binary);
  if (!f) {
    if (err) {
      (*err) += "File open error : " + filepath + "\n";
    }
    return false;
  }

  f.seekg(0, f.end);
  size_t sz = static_cast<size_t>(f.tellg());
  std::vector<unsigned char> buf(sz);

  f.seekg(0, f.beg);
  f.read(reinterpret_cast<char *>(&buf.at(0)),
         static_cast<std::streamsize>(sz));
  f.close();

  if (checkSize) {
    if (reqBytes == sz) {
      out->swap(buf);
      return true;
    } else {
      std::stringstream ss;
      ss << "File size mismatch : " << filepath << ", requestedBytes "
         << reqBytes << ", but got " << sz << std::endl;
      if (err) {
        (*err) += ss.str();
      }
      return false;
    }
  }

  out->swap(buf);
  return true;
}

static bool LoadImageData(Image *image, std::string *err, int req_width,
                          int req_height, const unsigned char *bytes,
                          int size) {
  int w, h, comp;
  unsigned char *data = stbi_load_from_memory(bytes, size, &w, &h, &comp, 0);
  if (!data) {
    if (err) {
      (*err) += "Unknown image format.\n";
    }
    return false;
  }

  if (w < 1 || h < 1) {
    free(data);
    if (err) {
      (*err) += "Unknown image format.\n";
    }
    return false;
  }

  if (req_width > 0) {
    if (req_width != w) {
      free(data);
      if (err) {
        (*err) += "Image width mismatch.\n";
      }
      return false;
    }
  }

  if (req_height > 0) {
    if (req_height != h) {
      free(data);
      if (err) {
        (*err) += "Image height mismatch.\n";
      }
      return false;
    }
  }

  image->width = w;
  image->height = h;
  image->component = comp;
  image->image.resize(static_cast<size_t>(w * h * comp));
  std::copy(data, data + w * h * comp, image->image.begin());

  free(data);

  return true;
}

static bool IsDataURI(const std::string &in) {
  std::string header = "data:application/octet-stream;base64,";
  if (in.find(header) == 0) {
    return true;
  }

  header = "data:image/png;base64,";
  if (in.find(header) == 0) {
    return true;
  }

  header = "data:image/jpeg;base64,";
  if (in.find(header) == 0) {
    return true;
  }

  header = "data:text/plain;base64,";
  if (in.find(header) == 0) {
    return true;
  }

  return false;
}

static bool DecodeDataURI(std::vector<unsigned char> *out,
                          const std::string &in, size_t reqBytes,
                          bool checkSize) {
  std::string header = "data:application/octet-stream;base64,";
  std::string data;
  if (in.find(header) == 0) {
    data = base64_decode(in.substr(header.size()));  // cut mime string.
  }

  if (data.empty()) {
    header = "data:image/jpeg;base64,";
    if (in.find(header) == 0) {
      data = base64_decode(in.substr(header.size()));  // cut mime string.
    }
  }

  if (data.empty()) {
    header = "data:image/png;base64,";
    if (in.find(header) == 0) {
      data = base64_decode(in.substr(header.size()));  // cut mime string.
    }
  }

  if (data.empty()) {
    header = "data:text/plain;base64,";
    if (in.find(header) == 0) {
      data = base64_decode(in.substr(header.size()));
    }
  }

  if (data.empty()) {
    return false;
  }

  if (checkSize) {
    if (data.size() != reqBytes) {
      return false;
    }
    out->resize(reqBytes);
  } else {
    out->resize(data.size());
  }
  std::copy(data.begin(), data.end(), out->begin());
  return true;
}

static void ParseObjectProperty(Value *ret, const picojson::object &o) {
  tinygltf::Value::Object vo;
  picojson::object::const_iterator it(o.begin());
  picojson::object::const_iterator itEnd(o.end());

  for (; it != itEnd; it++) {
    picojson::value v = it->second;

    if (v.is<bool>()) {
      vo[it->first] = tinygltf::Value(v.get<bool>());
    } else if (v.is<double>()) {
      vo[it->first] = tinygltf::Value(v.get<double>());
    } else if (v.is<int64_t>()) {
      vo[it->first] =
          tinygltf::Value(static_cast<int>(v.get<int64_t>()));  // truncate
    } else if (v.is<std::string>()) {
      vo[it->first] = tinygltf::Value(v.get<std::string>());
    } else if (v.is<picojson::object>()) {
      tinygltf::Value child_value;
      ParseObjectProperty(&child_value, v.get<picojson::object>());
    }
    // TODO(syoyo) binary, array
  }

  (*ret) = tinygltf::Value(vo);
}

static bool ParseExtrasProperty(Value *ret, const picojson::object &o) {
  picojson::object::const_iterator it = o.find("extras");
  if (it == o.end()) {
    return false;
  }

  // FIXME(syoyo) Currently we only support `object` type for extras property.
  if (!it->second.is<picojson::object>()) {
    return false;
  }

  ParseObjectProperty(ret, it->second.get<picojson::object>());

  return true;
}

static bool ParseBooleanProperty(bool *ret, std::string *err,
                                 const picojson::object &o,
                                 const std::string &property, bool required) {
  picojson::object::const_iterator it = o.find(property);
  if (it == o.end()) {
    if (required) {
      if (err) {
        (*err) += "'" + property + "' property is missing.\n";
      }
    }
    return false;
  }

  if (!it->second.is<bool>()) {
    if (required) {
      if (err) {
        (*err) += "'" + property + "' property is not a bool type.\n";
      }
    }
    return false;
  }

  if (ret) {
    (*ret) = it->second.get<bool>();
  }

  return true;
}

static bool ParseNumberProperty(double *ret, std::string *err,
                                const picojson::object &o,
                                const std::string &property, bool required) {
  picojson::object::const_iterator it = o.find(property);
  if (it == o.end()) {
    if (required) {
      if (err) {
        (*err) += "'" + property + "' property is missing.\n";
      }
    }
    return false;
  }

  if (!it->second.is<double>()) {
    if (required) {
      if (err) {
        (*err) += "'" + property + "' property is not a number type.\n";
      }
    }
    return false;
  }

  if (ret) {
    (*ret) = it->second.get<double>();
  }

  return true;
}

static bool ParseNumberArrayProperty(std::vector<double> *ret, std::string *err,
                                     const picojson::object &o,
                                     const std::string &property,
                                     bool required) {
  picojson::object::const_iterator it = o.find(property);
  if (it == o.end()) {
    if (required) {
      if (err) {
        (*err) += "'" + property + "' property is missing.\n";
      }
    }
    return false;
  }

  if (!it->second.is<picojson::array>()) {
    if (required) {
      if (err) {
        (*err) += "'" + property + "' property is not an array.\n";
      }
    }
    return false;
  }

  ret->clear();
  const picojson::array &arr = it->second.get<picojson::array>();
  for (size_t i = 0; i < arr.size(); i++) {
    if (!arr[i].is<double>()) {
      if (required) {
        if (err) {
          (*err) += "'" + property + "' property is not a number.\n";
        }
      }
      return false;
    }
    ret->push_back(arr[i].get<double>());
  }

  return true;
}

static bool ParseStringProperty(
    std::string *ret, std::string *err, const picojson::object &o,
    const std::string &property, bool required,
    const std::string &parent_node = std::string()) {
  picojson::object::const_iterator it = o.find(property);
  if (it == o.end()) {
    if (required) {
      if (err) {
        (*err) += "'" + property + "' property is missing";
        if (parent_node.empty()) {
          (*err) += ".\n";
        } else {
          (*err) += " in `" + parent_node + "'.\n";
        }
      }
    }
    return false;
  }

  if (!it->second.is<std::string>()) {
    if (required) {
      if (err) {
        (*err) += "'" + property + "' property is not a string type.\n";
      }
    }
    return false;
  }

  if (ret) {
    (*ret) = it->second.get<std::string>();
  }

  return true;
}

static bool ParseStringArrayProperty(std::vector<std::string> *ret,
                                     std::string *err,
                                     const picojson::object &o,
                                     const std::string &property,
                                     bool required) {
  picojson::object::const_iterator it = o.find(property);
  if (it == o.end()) {
    if (required) {
      if (err) {
        (*err) += "'" + property + "' property is missing.\n";
      }
    }
    return false;
  }

  if (!it->second.is<picojson::array>()) {
    if (required) {
      if (err) {
        (*err) += "'" + property + "' property is not an array.\n";
      }
    }
    return false;
  }

  ret->clear();
  const picojson::array &arr = it->second.get<picojson::array>();
  for (size_t i = 0; i < arr.size(); i++) {
    if (!arr[i].is<std::string>()) {
      if (required) {
        if (err) {
          (*err) += "'" + property + "' property is not a string.\n";
        }
      }
      return false;
    }
    ret->push_back(arr[i].get<std::string>());
  }

  return true;
}

static bool ParseStringMapProperty(std::map<std::string, std::string> *ret,
                                   std::string *err, const picojson::object &o,
                                   const std::string &property, bool required) {
  picojson::object::const_iterator it = o.find(property);
  if (it == o.end()) {
    if (required) {
      if (err) {
        (*err) += "'" + property + "' property is missing.\n";
      }
    }
    return false;
  }

  // Make sure we are dealing with an object / dictionary.
  if (!it->second.is<picojson::object>()) {
    if (required) {
      if (err) {
        (*err) += "'" + property + "' property is not an object.\n";
      }
    }
    return false;
  }

  ret->clear();
  const picojson::object &dict = it->second.get<picojson::object>();

  picojson::object::const_iterator dictIt(dict.begin());
  picojson::object::const_iterator dictItEnd(dict.end());

  for (; dictIt != dictItEnd; ++dictIt) {
    // Check that the value is a string.
    if (!dictIt->second.is<std::string>()) {
      if (required) {
        if (err) {
          (*err) += "'" + property + "' value is not a string.\n";
        }
      }
      return false;
    }

    // Insert into the list.
    (*ret)[dictIt->first] = dictIt->second.get<std::string>();
  }
  return true;
}

static bool ParseKHRBinaryExtension(const picojson::object &o, std::string *err,
                                    std::string *buffer_view,
                                    std::string *mime_type, int *image_width,
                                    int *image_height) {
  picojson::object j = o;

  if (j.find("extensions") == j.end()) {
    if (err) {
      (*err) += "`extensions' property is missing.\n";
    }
    return false;
  }

  if (!(j["extensions"].is<picojson::object>())) {
    if (err) {
      (*err) += "Invalid `extensions' property.\n";
    }
    return false;
  }

  picojson::object ext = j["extensions"].get<picojson::object>();

  if (ext.find("KHR_binary_glTF") == ext.end()) {
    if (err) {
      (*err) +=
          "`KHR_binary_glTF' property is missing in extension property.\n";
    }
    return false;
  }

  if (!(ext["KHR_binary_glTF"].is<picojson::object>())) {
    if (err) {
      (*err) += "Invalid `KHR_binary_glTF' property.\n";
    }
    return false;
  }

  picojson::object k = ext["KHR_binary_glTF"].get<picojson::object>();

  if (!ParseStringProperty(buffer_view, err, k, "bufferView", true)) {
    return false;
  }

  if (mime_type) {
    ParseStringProperty(mime_type, err, k, "mimeType", false);
  }

  if (image_width) {
    double width = 0.0;
    if (ParseNumberProperty(&width, err, k, "width", false)) {
      (*image_width) = static_cast<int>(width);
    }
  }

  if (image_height) {
    double height = 0.0;
    if (ParseNumberProperty(&height, err, k, "height", false)) {
      (*image_height) = static_cast<int>(height);
    }
  }

  return true;
}

static bool ParseAsset(Asset *asset, std::string *err,
                       const picojson::object &o) {
  ParseStringProperty(&asset->generator, err, o, "generator", false);
  ParseBooleanProperty(&asset->premultipliedAlpha, err, o, "premultipliedAlpha",
                       false);

  ParseStringProperty(&asset->version, err, o, "version", false);

  picojson::object::const_iterator profile = o.find("profile");
  if (profile != o.end()) {
    const picojson::value &v = profile->second;
    if (v.contains("api") & v.get("api").is<std::string>()) {
      asset->profile_api = v.get("api").get<std::string>();
    }
    if (v.contains("version") & v.get("version").is<std::string>()) {
      asset->profile_version = v.get("version").get<std::string>();
    }
  }

  return true;
}

static bool ParseImage(Image *image, std::string *err,
                       const picojson::object &o, const std::string &basedir,
                       bool is_binary, const unsigned char *bin_data,
                       size_t bin_size) {
  std::string uri;
  if (!ParseStringProperty(&uri, err, o, "uri", true)) {
    return false;
  }

  ParseStringProperty(&image->name, err, o, "name", false);

  std::vector<unsigned char> img;

  if (is_binary) {
    // Still binary glTF accepts external dataURI. First try external resources.
    bool loaded = false;
    if (IsDataURI(uri)) {
      loaded = DecodeDataURI(&img, uri, 0, false);
    } else {
      // Assume external .bin file.
      loaded = LoadExternalFile(&img, err, uri, basedir, 0, false);
    }

    if (!loaded) {
      // load data from (embedded) binary data

      if ((bin_size == 0) || (bin_data == NULL)) {
        if (err) {
          (*err) += "Invalid binary data.\n";
        }
        return false;
      }

      // There should be "extensions" property.
      // "extensions":{"KHR_binary_glTF":{"bufferView": "id", ...

      std::string buffer_view;
      std::string mime_type;
      int image_width;
      int image_height;
      bool ret = ParseKHRBinaryExtension(o, err, &buffer_view, &mime_type,
                                         &image_width, &image_height);
      if (!ret) {
        return false;
      }

      if (uri.compare("data:,") == 0) {
        // ok
      } else {
        if (err) {
          (*err) += "Invalid URI for binary data.\n";
        }
        return false;
      }

      // Just only save some information here. Loading actual image data from
      // bufferView is done in other place.
      image->bufferView = buffer_view;
      image->mimeType = mime_type;
      image->width = image_width;
      image->height = image_height;

      return true;
    }
  } else {
    if (IsDataURI(uri)) {
      if (!DecodeDataURI(&img, uri, 0, false)) {
        if (err) {
          (*err) += "Failed to decode 'uri' for image parameter.\n";
        }
        return false;
      }
    } else {
      // Assume external file
      if (!LoadExternalFile(&img, err, uri, basedir, 0, false)) {
        if (err) {
          (*err) += "Failed to load external 'uri'. for image parameter\n";
        }
        return false;
      }
      if (img.empty()) {
        if (err) {
          (*err) += "Image is empty.\n";
        }
        return false;
      }
    }
  }

  return LoadImageData(image, err, 0, 0, &img.at(0),
                       static_cast<int>(img.size()));
}

static bool ParseTexture(Texture *texture, std::string *err,
                         const picojson::object &o,
                         const std::string &basedir) {
  (void)basedir;

  if (!ParseStringProperty(&texture->sampler, err, o, "sampler", true)) {
    return false;
  }

  if (!ParseStringProperty(&texture->source, err, o, "source", true)) {
    return false;
  }

  ParseStringProperty(&texture->name, err, o, "name", false);

  double format = TINYGLTF_TEXTURE_FORMAT_RGBA;
  ParseNumberProperty(&format, err, o, "format", false);

  double internalFormat = TINYGLTF_TEXTURE_FORMAT_RGBA;
  ParseNumberProperty(&internalFormat, err, o, "internalFormat", false);

  double target = TINYGLTF_TEXTURE_TARGET_TEXTURE2D;
  ParseNumberProperty(&target, err, o, "target", false);

  double type = TINYGLTF_TEXTURE_TYPE_UNSIGNED_BYTE;
  ParseNumberProperty(&type, err, o, "type", false);

  texture->format = static_cast<int>(format);
  texture->internalFormat = static_cast<int>(internalFormat);
  texture->target = static_cast<int>(target);
  texture->type = static_cast<int>(type);

  return true;
}

static bool ParseBuffer(Buffer *buffer, std::string *err,
                        const picojson::object &o, const std::string &basedir,
                        bool is_binary = false,
                        const unsigned char *bin_data = NULL,
                        size_t bin_size = 0) {
  double byteLength;
  if (!ParseNumberProperty(&byteLength, err, o, "byteLength", true)) {
    return false;
  }

  std::string uri;
  if (!ParseStringProperty(&uri, err, o, "uri", true)) {
    return false;
  }

  picojson::object::const_iterator type = o.find("type");
  if (type != o.end()) {
    if (type->second.is<std::string>()) {
      const std::string &ty = (type->second).get<std::string>();
      if (ty.compare("arraybuffer") == 0) {
        // buffer.type = "arraybuffer";
      }
    }
  }

  size_t bytes = static_cast<size_t>(byteLength);
  if (is_binary) {
    // Still binary glTF accepts external dataURI. First try external resources.
    bool loaded = false;
    if (IsDataURI(uri)) {
      loaded = DecodeDataURI(&buffer->data, uri, bytes, true);
    } else {
      // Assume external .bin file.
      loaded = LoadExternalFile(&buffer->data, err, uri, basedir, bytes, true);
    }

    if (!loaded) {
      // load data from (embedded) binary data

      if ((bin_size == 0) || (bin_data == NULL)) {
        if (err) {
          (*err) += "Invalid binary data.\n";
        }
        return false;
      }

      if (byteLength > bin_size) {
        if (err) {
          std::stringstream ss;
          ss << "Invalid `byteLength'. Must be equal or less than binary size: "
                "`byteLength' = "
             << byteLength << ", binary size = " << bin_size << std::endl;
          (*err) += ss.str();
        }
        return false;
      }

      if (uri.compare("data:,") == 0) {
        // @todo { check uri }
        buffer->data.resize(static_cast<size_t>(byteLength));
        memcpy(&(buffer->data.at(0)), bin_data,
               static_cast<size_t>(byteLength));

      } else {
        if (err) {
          (*err) += "Invalid URI for binary data.\n";
        }
        return false;
      }
    }

  } else {
    if (IsDataURI(uri)) {
      if (!DecodeDataURI(&buffer->data, uri, bytes, true)) {
        if (err) {
          (*err) += "Failed to decode 'uri'.\n";
        }
        return false;
      }
    } else {
      // Assume external .bin file.
      if (!LoadExternalFile(&buffer->data, err, uri, basedir, bytes, true)) {
        return false;
      }
    }
  }

  ParseStringProperty(&buffer->name, err, o, "name", false);

  return true;
}

static bool ParseBufferView(BufferView *bufferView, std::string *err,
                            const picojson::object &o) {
  std::string buffer;
  if (!ParseStringProperty(&buffer, err, o, "buffer", true)) {
    return false;
  }

  double byteOffset;
  if (!ParseNumberProperty(&byteOffset, err, o, "byteOffset", true)) {
    return false;
  }

  double byteLength = 0.0;
  ParseNumberProperty(&byteLength, err, o, "byteLength", false);

  double target = 0.0;
  ParseNumberProperty(&target, err, o, "target", false);
  int targetValue = static_cast<int>(target);
  if ((targetValue == TINYGLTF_TARGET_ARRAY_BUFFER) ||
      (targetValue == TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER)) {
    // OK
  } else {
    targetValue = 0;
  }
  bufferView->target = targetValue;

  ParseStringProperty(&bufferView->name, err, o, "name", false);

  bufferView->buffer = buffer;
  bufferView->byteOffset = static_cast<size_t>(byteOffset);
  bufferView->byteLength = static_cast<size_t>(byteLength);

  return true;
}

static bool ParseAccessor(Accessor *accessor, std::string *err,
                          const picojson::object &o) {
  std::string bufferView;
  if (!ParseStringProperty(&bufferView, err, o, "bufferView", true)) {
    return false;
  }

  double byteOffset;
  if (!ParseNumberProperty(&byteOffset, err, o, "byteOffset", true)) {
    return false;
  }

  double componentType;
  if (!ParseNumberProperty(&componentType, err, o, "componentType", true)) {
    return false;
  }

  double count = 0.0;
  if (!ParseNumberProperty(&count, err, o, "count", true)) {
    return false;
  }

  std::string type;
  if (!ParseStringProperty(&type, err, o, "type", true)) {
    return false;
  }

  if (type.compare("SCALAR") == 0) {
    accessor->type = TINYGLTF_TYPE_SCALAR;
  } else if (type.compare("VEC2") == 0) {
    accessor->type = TINYGLTF_TYPE_VEC2;
  } else if (type.compare("VEC3") == 0) {
    accessor->type = TINYGLTF_TYPE_VEC3;
  } else if (type.compare("VEC4") == 0) {
    accessor->type = TINYGLTF_TYPE_VEC4;
  } else if (type.compare("MAT2") == 0) {
    accessor->type = TINYGLTF_TYPE_MAT2;
  } else if (type.compare("MAT3") == 0) {
    accessor->type = TINYGLTF_TYPE_MAT3;
  } else if (type.compare("MAT4") == 0) {
    accessor->type = TINYGLTF_TYPE_MAT4;
  } else {
    std::stringstream ss;
    ss << "Unsupported `type` for accessor object. Got \"" << type << "\"\n";
    if (err) {
      (*err) += ss.str();
    }
    return false;
  }

  double byteStride = 0.0;
  ParseNumberProperty(&byteStride, err, o, "byteStride", false);

  ParseStringProperty(&accessor->name, err, o, "name", false);

  accessor->minValues.clear();
  accessor->maxValues.clear();
  ParseNumberArrayProperty(&accessor->minValues, err, o, "min", false);
  ParseNumberArrayProperty(&accessor->maxValues, err, o, "max", false);

  accessor->count = static_cast<size_t>(count);
  accessor->bufferView = bufferView;
  accessor->byteOffset = static_cast<size_t>(byteOffset);
  accessor->byteStride = static_cast<size_t>(byteStride);

  {
    int comp = static_cast<int>(componentType);
    if (comp >= TINYGLTF_COMPONENT_TYPE_BYTE &&
        comp <= TINYGLTF_COMPONENT_TYPE_DOUBLE) {
      // OK
      accessor->componentType = comp;
    } else {
      std::stringstream ss;
      ss << "Invalid `componentType` in accessor. Got " << comp << "\n";
      if (err) {
        (*err) += ss.str();
      }
      return false;
    }
  }

  ParseExtrasProperty(&(accessor->extras), o);

  return true;
}

static bool ParsePrimitive(Primitive *primitive, std::string *err,
                           const picojson::object &o) {
  if (!ParseStringProperty(&primitive->material, err, o, "material", true,
                           "mesh.primitive")) {
    return false;
  }

  double mode = static_cast<double>(TINYGLTF_MODE_TRIANGLES);
  ParseNumberProperty(&mode, err, o, "mode", false);

  int primMode = static_cast<int>(mode);
  primitive->mode = primMode;

  primitive->indices = "";
  ParseStringProperty(&primitive->indices, err, o, "indices", false);

  ParseStringMapProperty(&primitive->attributes, err, o, "attributes", false);

  ParseExtrasProperty(&(primitive->extras), o);

  return true;
}

static bool ParseMesh(Mesh *mesh, std::string *err, const picojson::object &o) {
  ParseStringProperty(&mesh->name, err, o, "name", false);

  mesh->primitives.clear();
  picojson::object::const_iterator primObject = o.find("primitives");
  if ((primObject != o.end()) && (primObject->second).is<picojson::array>()) {
    const picojson::array &primArray =
        (primObject->second).get<picojson::array>();
    for (size_t i = 0; i < primArray.size(); i++) {
      Primitive primitive;
      if (ParsePrimitive(&primitive, err,
                         primArray[i].get<picojson::object>())) {
        // Only add the primitive if the parsing succeeds.
        mesh->primitives.push_back(primitive);
      }
    }
  }

  ParseExtrasProperty(&(mesh->extras), o);

  return true;
}

static bool ParseNode(Node *node, std::string *err, const picojson::object &o) {
  ParseStringProperty(&node->name, err, o, "name", false);

  ParseNumberArrayProperty(&node->rotation, err, o, "rotation", false);
  ParseNumberArrayProperty(&node->scale, err, o, "scale", false);
  ParseNumberArrayProperty(&node->translation, err, o, "translation", false);
  ParseNumberArrayProperty(&node->matrix, err, o, "matrix", false);
  ParseStringArrayProperty(&node->meshes, err, o, "meshes", false);

  node->children.clear();
  picojson::object::const_iterator childrenObject = o.find("children");
  if ((childrenObject != o.end()) &&
      (childrenObject->second).is<picojson::array>()) {
    const picojson::array &childrenArray =
        (childrenObject->second).get<picojson::array>();
    for (size_t i = 0; i < childrenArray.size(); i++) {
      if (!childrenArray[i].is<std::string>()) {
        if (err) {
          (*err) += "Invalid `children` array.\n";
        }
        return false;
      }
      const std::string &childrenNode = childrenArray[i].get<std::string>();
      node->children.push_back(childrenNode);
    }
  }

  ParseExtrasProperty(&(node->extras), o);

  return true;
}

static bool ParseParameterProperty(Parameter *param, std::string *err,
                                   const picojson::object &o,
                                   const std::string &prop, bool required) {
  double num_val;

  // A parameter value can either be a string or an array of either a boolean or
  // a number. Booleans of any kind aren't supported here. Granted, it
  // complicates the Parameter structure and breaks it semantically in the sense
  // that the client probably works off the assumption that if the string is
  // empty the vector is used, etc. Would a tagged union work?
  if (ParseStringProperty(&param->string_value, err, o, prop, false)) {
    // Found string property.
    return true;
  } else if (ParseNumberArrayProperty(&param->number_array, err, o, prop,
                                      false)) {
    // Found a number array.
    return true;
  } else if (ParseNumberProperty(&num_val, err, o, prop, false)) {
    param->number_array.push_back(num_val);
    return true;
  } else {
    if (required) {
      if (err) {
        (*err) += "parameter must be a string or number / number array.\n";
      }
    }
    return false;
  }
}

static bool ParseMaterial(Material *material, std::string *err,
                          const picojson::object &o) {
  ParseStringProperty(&material->name, err, o, "name", false);
  ParseStringProperty(&material->technique, err, o, "technique", false);

  material->values.clear();
  picojson::object::const_iterator valuesIt = o.find("values");

  if ((valuesIt != o.end()) && (valuesIt->second).is<picojson::object>()) {
    const picojson::object &values_object =
        (valuesIt->second).get<picojson::object>();

    picojson::object::const_iterator it(values_object.begin());
    picojson::object::const_iterator itEnd(values_object.end());

    for (; it != itEnd; it++) {
      Parameter param;
      if (ParseParameterProperty(&param, err, values_object, it->first,
                                 false)) {
        material->values[it->first] = param;
      }
    }
  }

  ParseExtrasProperty(&(material->extras), o);

  return true;
}

static bool ParseShader(Shader *shader, std::string *err,
                        const picojson::object &o, const std::string &basedir,
                        bool is_binary = false,
                        const unsigned char *bin_data = NULL,
                        size_t bin_size = 0) {
  std::string uri;
  if (!ParseStringProperty(&uri, err, o, "uri", true)) {
    return false;
  }

  if (is_binary) {
    // Still binary glTF accepts external dataURI. First try external resources.
    bool loaded = false;
    if (IsDataURI(uri)) {
      loaded = DecodeDataURI(&shader->source, uri, 0, false);
    } else {
      // Assume external .bin file.
      loaded = LoadExternalFile(&shader->source, err, uri, basedir, 0, false);
    }

    if (!loaded) {
      // load data from (embedded) binary data

      if ((bin_size == 0) || (bin_data == NULL)) {
        if (err) {
          (*err) += "Invalid binary data.\n";
        }
        return false;
      }

      // There should be "extensions" property.
      // "extensions":{"KHR_binary_glTF":{"bufferView": "id", ...

      std::string buffer_view;
      std::string mime_type;
      int image_width;
      int image_height;
      bool ret = ParseKHRBinaryExtension(o, err, &buffer_view, &mime_type,
                                         &image_width, &image_height);
      if (!ret) {
        return false;
      }

      if (uri.compare("data:,") == 0) {
        // ok
      } else {
        if (err) {
          (*err) += "Invalid URI for binary data.\n";
        }
        return false;
      }
    }
  } else {
    // Load shader source from data uri
    // TODO(syoyo): Support ascii or utf-8 data uris.
    if (IsDataURI(uri)) {
      if (!DecodeDataURI(&shader->source, uri, 0, false)) {
        if (err) {
          (*err) += "Failed to decode 'uri' for shader parameter.\n";
        }
        return false;
      }
    } else {
      // Assume external file
      if (!LoadExternalFile(&shader->source, err, uri, basedir, 0, false)) {
        if (err) {
          (*err) += "Failed to load external 'uri' for shader parameter.\n";
        }
        return false;
      }
      if (shader->source.empty()) {
        if (err) {
          (*err) += "shader is empty.\n";  // This may be OK?
        }
        return false;
      }
    }
  }

  double type;
  if (!ParseNumberProperty(&type, err, o, "type", true)) {
    return false;
  }

  shader->type = static_cast<int>(type);

  ParseExtrasProperty(&(shader->extras), o);

  return true;
}

static bool ParseProgram(Program *program, std::string *err,
                         const picojson::object &o) {
  ParseStringProperty(&program->name, err, o, "name", false);

  if (!ParseStringProperty(&program->vertexShader, err, o, "vertexShader",
                           true)) {
    return false;
  }
  if (!ParseStringProperty(&program->fragmentShader, err, o, "fragmentShader",
                           true)) {
    return false;
  }

  // I suppose the list of attributes isn't needed, but a technique doesn't
  // really make sense without it.
  ParseStringArrayProperty(&program->attributes, err, o, "attributes", false);

  ParseExtrasProperty(&(program->extras), o);

  return true;
}

static bool ParseTechniqueParameter(TechniqueParameter *param, std::string *err,
                                    const picojson::object &o) {
  double count = 1;
  ParseNumberProperty(&count, err, o, "count", false);

  double type;
  if (!ParseNumberProperty(&type, err, o, "type", true)) {
    return false;
  }

  ParseStringProperty(&param->node, err, o, "node", false);
  ParseStringProperty(&param->semantic, err, o, "semantic", false);

  ParseParameterProperty(&param->value, err, o, "value", false);

  param->count = static_cast<int>(count);
  param->type = static_cast<int>(type);

  return true;
}

static bool ParseTechnique(Technique *technique, std::string *err,
                           const picojson::object &o) {
  ParseStringProperty(&technique->name, err, o, "name", false);

  if (!ParseStringProperty(&technique->program, err, o, "program", true)) {
    return false;
  }

  ParseStringMapProperty(&technique->attributes, err, o, "attributes", false);
  ParseStringMapProperty(&technique->uniforms, err, o, "uniforms", false);

  technique->parameters.clear();
  picojson::object::const_iterator paramsIt = o.find("parameters");

  // Verify parameters is an object
  if ((paramsIt != o.end()) && (paramsIt->second).is<picojson::object>()) {
    // For each parameter in params_object.
    const picojson::object &params_object =
        (paramsIt->second).get<picojson::object>();

    picojson::object::const_iterator it(params_object.begin());
    picojson::object::const_iterator itEnd(params_object.end());

    for (; it != itEnd; it++) {
      TechniqueParameter param;

      // Skip non-objects
      if (!it->second.is<picojson::object>()) continue;

      // Parse the technique parameter
      const picojson::object &param_obj = it->second.get<picojson::object>();
      if (ParseTechniqueParameter(&param, err, param_obj)) {
        // Add if successful
        technique->parameters[it->first] = param;
      }
    }
  }

  ParseExtrasProperty(&(technique->extras), o);

  return true;
}

static bool ParseAnimationChannel(AnimationChannel *channel, std::string *err,
                                  const picojson::object &o) {
  if (!ParseStringProperty(&channel->sampler, err, o, "sampler", true)) {
    if (err) {
      (*err) += "`sampler` field is missing in animation channels\n";
    }
    return false;
  }

  picojson::object::const_iterator targetIt = o.find("target");
  if ((targetIt != o.end()) && (targetIt->second).is<picojson::object>()) {
    const picojson::object &target_object =
        (targetIt->second).get<picojson::object>();

    if (!ParseStringProperty(&channel->target_id, err, target_object, "id",
                             true)) {
      if (err) {
        (*err) += "`id` field is missing in animation.channels.target\n";
      }
      return false;
    }

    if (!ParseStringProperty(&channel->target_path, err, target_object, "path",
                             true)) {
      if (err) {
        (*err) += "`path` field is missing in animation.channels.target\n";
      }
      return false;
    }
  }

  ParseExtrasProperty(&(channel->extras), o);

  return true;
}

static bool ParseAnimation(Animation *animation, std::string *err,
                           const picojson::object &o) {
  {
    picojson::object::const_iterator channelsIt = o.find("channels");
    if ((channelsIt != o.end()) && (channelsIt->second).is<picojson::array>()) {
      const picojson::array &channelArray =
          (channelsIt->second).get<picojson::array>();
      for (size_t i = 0; i < channelArray.size(); i++) {
        AnimationChannel channel;
        if (ParseAnimationChannel(&channel, err,
                                  channelArray[i].get<picojson::object>())) {
          // Only add the channel if the parsing succeeds.
          animation->channels.push_back(channel);
        }
      }
    }
  }

  {
    picojson::object::const_iterator samplerIt = o.find("samplers");
    if ((samplerIt != o.end()) && (samplerIt->second).is<picojson::object>()) {
      const picojson::object &sampler_object =
          (samplerIt->second).get<picojson::object>();

      picojson::object::const_iterator it = sampler_object.begin();
      picojson::object::const_iterator itEnd = sampler_object.end();

      for (; it != itEnd; it++) {
        // Skip non-objects
        if (!it->second.is<picojson::object>()) continue;

        const picojson::object &s = it->second.get<picojson::object>();

        AnimationSampler sampler;
        if (!ParseStringProperty(&sampler.input, err, s, "input", true)) {
          if (err) {
            (*err) += "`input` field is missing in animation.sampler\n";
          }
          return false;
        }
        if (!ParseStringProperty(&sampler.interpolation, err, s,
                                 "interpolation", true)) {
          if (err) {
            (*err) += "`interpolation` field is missing in animation.sampler\n";
          }
          return false;
        }
        if (!ParseStringProperty(&sampler.output, err, s, "output", true)) {
          if (err) {
            (*err) += "`output` field is missing in animation.sampler\n";
          }
          return false;
        }

        animation->samplers[it->first] = sampler;
      }
    }
  }

  picojson::object::const_iterator parametersIt = o.find("parameters");
  if ((parametersIt != o.end()) &&
      (parametersIt->second).is<picojson::object>()) {
    const picojson::object &parameters_object =
        (parametersIt->second).get<picojson::object>();

    picojson::object::const_iterator it(parameters_object.begin());
    picojson::object::const_iterator itEnd(parameters_object.end());

    for (; it != itEnd; it++) {
      Parameter param;
      if (ParseParameterProperty(&param, err, parameters_object, it->first,
                                 false)) {
        animation->parameters[it->first] = param;
      }
    }
  }
  ParseStringProperty(&animation->name, err, o, "name", false);

  ParseExtrasProperty(&(animation->extras), o);

  return true;
}

static bool ParseSampler(Sampler *sampler, std::string *err,
                         const picojson::object &o) {
  ParseStringProperty(&sampler->name, err, o, "name", false);

  double minFilter =
      static_cast<double>(TINYGLTF_TEXTURE_FILTER_NEAREST_MIPMAP_LINEAR);
  double magFilter = static_cast<double>(TINYGLTF_TEXTURE_FILTER_LINEAR);
  double wrapS = static_cast<double>(TINYGLTF_TEXTURE_WRAP_RPEAT);
  double wrapT = static_cast<double>(TINYGLTF_TEXTURE_WRAP_RPEAT);
  ParseNumberProperty(&minFilter, err, o, "minFilter", false);
  ParseNumberProperty(&magFilter, err, o, "magFilter", false);
  ParseNumberProperty(&wrapS, err, o, "wrapS", false);
  ParseNumberProperty(&wrapT, err, o, "wrapT", false);

  sampler->minFilter = static_cast<int>(minFilter);
  sampler->magFilter = static_cast<int>(magFilter);
  sampler->wrapS = static_cast<int>(wrapS);
  sampler->wrapT = static_cast<int>(wrapT);

  ParseExtrasProperty(&(sampler->extras), o);

  return true;
}

bool TinyGLTFLoader::LoadFromString(Scene *scene, std::string *err,
                                    const char *str, unsigned int length,
                                    const std::string &base_dir,
                                    unsigned int check_sections) {
  picojson::value v;
  std::string perr = picojson::parse(v, str, str + length);

  if (!perr.empty()) {
    if (err) {
      (*err) = perr;
    }
    return false;
  }

  if (v.contains("scene") && v.get("scene").is<std::string>()) {
    // OK
  } else if (check_sections & REQUIRE_SCENE) {
    if (err) {
      (*err) += "\"scene\" object not found in .gltf\n";
    }
    return false;
  }

  if (v.contains("scenes") && v.get("scenes").is<picojson::object>()) {
    // OK
  } else if (check_sections & REQUIRE_SCENES) {
    if (err) {
      (*err) += "\"scenes\" object not found in .gltf\n";
    }
    return false;
  }

  if (v.contains("nodes") && v.get("nodes").is<picojson::object>()) {
    // OK
  } else if (check_sections & REQUIRE_NODES) {
    if (err) {
      (*err) += "\"nodes\" object not found in .gltf\n";
    }
    return false;
  }

  if (v.contains("accessors") && v.get("accessors").is<picojson::object>()) {
    // OK
  } else if (check_sections & REQUIRE_ACCESSORS) {
    if (err) {
      (*err) += "\"accessors\" object not found in .gltf\n";
    }
    return false;
  }

  if (v.contains("buffers") && v.get("buffers").is<picojson::object>()) {
    // OK
  } else if (check_sections & REQUIRE_BUFFERS) {
    if (err) {
      (*err) += "\"buffers\" object not found in .gltf\n";
    }
    return false;
  }

  if (v.contains("bufferViews") &&
      v.get("bufferViews").is<picojson::object>()) {
    // OK
  } else if (check_sections & REQUIRE_BUFFER_VIEWS) {
    if (err) {
      (*err) += "\"bufferViews\" object not found in .gltf\n";
    }
    return false;
  }

  scene->buffers.clear();
  scene->bufferViews.clear();
  scene->accessors.clear();
  scene->meshes.clear();
  scene->nodes.clear();
  scene->defaultScene = "";

  // 0. Parse Asset
  if (v.contains("asset") && v.get("asset").is<picojson::object>()) {
    const picojson::object &root = v.get("asset").get<picojson::object>();

    ParseAsset(&scene->asset, err, root);
  }

  // 1. Parse Buffer
  if (v.contains("buffers") && v.get("buffers").is<picojson::object>()) {
    const picojson::object &root = v.get("buffers").get<picojson::object>();

    picojson::object::const_iterator it(root.begin());
    picojson::object::const_iterator itEnd(root.end());
    for (; it != itEnd; it++) {
      Buffer buffer;
      if (!ParseBuffer(&buffer, err, (it->second).get<picojson::object>(),
                       base_dir, is_binary_, bin_data_, bin_size_)) {
        return false;
      }

      scene->buffers[it->first] = buffer;
    }
  }

  // 2. Parse BufferView
  if (v.contains("bufferViews") &&
      v.get("bufferViews").is<picojson::object>()) {
    const picojson::object &root = v.get("bufferViews").get<picojson::object>();

    picojson::object::const_iterator it(root.begin());
    picojson::object::const_iterator itEnd(root.end());
    for (; it != itEnd; it++) {
      BufferView bufferView;
      if (!ParseBufferView(&bufferView, err,
                           (it->second).get<picojson::object>())) {
        return false;
      }

      scene->bufferViews[it->first] = bufferView;
    }
  }

  // 3. Parse Accessor
  if (v.contains("accessors") && v.get("accessors").is<picojson::object>()) {
    const picojson::object &root = v.get("accessors").get<picojson::object>();

    picojson::object::const_iterator it(root.begin());
    picojson::object::const_iterator itEnd(root.end());
    for (; it != itEnd; it++) {
      Accessor accessor;
      if (!ParseAccessor(&accessor, err,
                         (it->second).get<picojson::object>())) {
        return false;
      }

      scene->accessors[it->first] = accessor;
    }
  }

  // 4. Parse Mesh
  if (v.contains("meshes") && v.get("meshes").is<picojson::object>()) {
    const picojson::object &root = v.get("meshes").get<picojson::object>();

    picojson::object::const_iterator it(root.begin());
    picojson::object::const_iterator itEnd(root.end());
    for (; it != itEnd; it++) {
      Mesh mesh;
      if (!ParseMesh(&mesh, err, (it->second).get<picojson::object>())) {
        return false;
      }

      scene->meshes[it->first] = mesh;
    }
  }

  // 5. Parse Node
  if (v.contains("nodes") && v.get("nodes").is<picojson::object>()) {
    const picojson::object &root = v.get("nodes").get<picojson::object>();

    picojson::object::const_iterator it(root.begin());
    picojson::object::const_iterator itEnd(root.end());
    for (; it != itEnd; it++) {
      Node node;
      if (!ParseNode(&node, err, (it->second).get<picojson::object>())) {
        return false;
      }

      scene->nodes[it->first] = node;
    }
  }

  // 6. Parse scenes.
  if (v.contains("scenes") && v.get("scenes").is<picojson::object>()) {
    const picojson::object &root = v.get("scenes").get<picojson::object>();

    picojson::object::const_iterator it(root.begin());
    picojson::object::const_iterator itEnd(root.end());
    for (; it != itEnd; it++) {
      if (!((it->second).is<picojson::object>())) {
        if (err) {
          (*err) += "`scenes' does not contain an object.";
        }
        return false;
      }
      const picojson::object &o = (it->second).get<picojson::object>();
      std::vector<std::string> nodes;
      if (!ParseStringArrayProperty(&nodes, err, o, "nodes", false)) {
        return false;
      }

      scene->scenes[it->first] = nodes;
    }
  }

  // 7. Parse default scenes.
  if (v.contains("scene") && v.get("scene").is<std::string>()) {
    const std::string defaultScene = v.get("scene").get<std::string>();

    scene->defaultScene = defaultScene;
  }

  // 8. Parse Material
  if (v.contains("materials") && v.get("materials").is<picojson::object>()) {
    const picojson::object &root = v.get("materials").get<picojson::object>();

    picojson::object::const_iterator it(root.begin());
    picojson::object::const_iterator itEnd(root.end());
    for (; it != itEnd; it++) {
      Material material;
      if (!ParseMaterial(&material, err,
                         (it->second).get<picojson::object>())) {
        return false;
      }

      scene->materials[it->first] = material;
    }
  }

  // 9. Parse Image
  if (v.contains("images") && v.get("images").is<picojson::object>()) {
    const picojson::object &root = v.get("images").get<picojson::object>();

    picojson::object::const_iterator it(root.begin());
    picojson::object::const_iterator itEnd(root.end());
    for (; it != itEnd; it++) {
      Image image;
      if (!ParseImage(&image, err, (it->second).get<picojson::object>(),
                      base_dir, is_binary_, bin_data_, bin_size_)) {
        return false;
      }

      if (!image.bufferView.empty()) {
        // Load image from the buffer view.
        if (scene->bufferViews.find(image.bufferView) ==
            scene->bufferViews.end()) {
          if (err) {
            std::stringstream ss;
            ss << "bufferView \"" << image.bufferView
               << "\" not found in the scene." << std::endl;
            (*err) += ss.str();
          }
          return false;
        }

        const BufferView &bufferView = scene->bufferViews[image.bufferView];
        const Buffer &buffer = scene->buffers[bufferView.buffer];

        bool ret = LoadImageData(&image, err, image.width, image.height,
                                 &buffer.data[bufferView.byteOffset],
                                 static_cast<int>(bufferView.byteLength));
        if (!ret) {
          return false;
        }
      }

      scene->images[it->first] = image;
    }
  }

  // 10. Parse Texture
  if (v.contains("textures") && v.get("textures").is<picojson::object>()) {
    const picojson::object &root = v.get("textures").get<picojson::object>();

    picojson::object::const_iterator it(root.begin());
    picojson::object::const_iterator itEnd(root.end());
    for (; it != itEnd; it++) {
      Texture texture;
      if (!ParseTexture(&texture, err, (it->second).get<picojson::object>(),
                        base_dir)) {
        return false;
      }

      scene->textures[it->first] = texture;
    }
  }

  // 11. Parse Shader
  if (v.contains("shaders") && v.get("shaders").is<picojson::object>()) {
    const picojson::object &root = v.get("shaders").get<picojson::object>();

    picojson::object::const_iterator it(root.begin());
    picojson::object::const_iterator itEnd(root.end());
    for (; it != itEnd; ++it) {
      Shader shader;
      if (!ParseShader(&shader, err, (it->second).get<picojson::object>(),
                       base_dir, is_binary_, bin_data_, bin_size_)) {
        return false;
      }

      scene->shaders[it->first] = shader;
    }
  }

  // 12. Parse Program
  if (v.contains("programs") && v.get("programs").is<picojson::object>()) {
    const picojson::object &root = v.get("programs").get<picojson::object>();

    picojson::object::const_iterator it(root.begin());
    picojson::object::const_iterator itEnd(root.end());
    for (; it != itEnd; ++it) {
      Program program;
      if (!ParseProgram(&program, err, (it->second).get<picojson::object>())) {
        return false;
      }

      scene->programs[it->first] = program;
    }
  }

  // 13. Parse Technique
  if (v.contains("techniques") && v.get("techniques").is<picojson::object>()) {
    const picojson::object &root = v.get("techniques").get<picojson::object>();

    picojson::object::const_iterator it(root.begin());
    picojson::object::const_iterator itEnd(root.end());
    for (; it != itEnd; ++it) {
      Technique technique;
      if (!ParseTechnique(&technique, err,
                          (it->second).get<picojson::object>())) {
        return false;
      }

      scene->techniques[it->first] = technique;
    }
  }

  // 14. Parse Animation
  if (v.contains("animations") && v.get("animations").is<picojson::object>()) {
    const picojson::object &root = v.get("animations").get<picojson::object>();

    picojson::object::const_iterator it(root.begin());
    picojson::object::const_iterator itEnd(root.end());
    for (; it != itEnd; ++it) {
      Animation animation;
      if (!ParseAnimation(&animation, err,
                          (it->second).get<picojson::object>())) {
        return false;
      }

      scene->animations[it->first] = animation;
    }
  }

  // 15. Parse Sampler
  if (v.contains("samplers") && v.get("samplers").is<picojson::object>()) {
    const picojson::object &root = v.get("samplers").get<picojson::object>();

    picojson::object::const_iterator it(root.begin());
    picojson::object::const_iterator itEnd(root.end());
    for (; it != itEnd; ++it) {
      Sampler sampler;
      if (!ParseSampler(&sampler, err, (it->second).get<picojson::object>())) {
        return false;
      }

      scene->samplers[it->first] = sampler;
    }
  }
  return true;
}

bool TinyGLTFLoader::LoadASCIIFromString(Scene *scene, std::string *err,
                                         const char *str, unsigned int length,
                                         const std::string &base_dir,
                                         unsigned int check_sections) {
  is_binary_ = false;
  bin_data_ = NULL;
  bin_size_ = 0;

  return LoadFromString(scene, err, str, length, base_dir, check_sections);
}

bool TinyGLTFLoader::LoadASCIIFromFile(Scene *scene, std::string *err,
                                       const std::string &filename,
                                       unsigned int check_sections) {
  std::stringstream ss;

  std::ifstream f(filename.c_str());
  if (!f) {
    ss << "Failed to open file: " << filename << std::endl;
    if (err) {
      (*err) = ss.str();
    }
    return false;
  }

  f.seekg(0, f.end);
  size_t sz = static_cast<size_t>(f.tellg());
  std::vector<char> buf(sz);

  if (sz == 0) {
    if (err) {
      (*err) = "Empty file.";
    }
    return false;
  }

  f.seekg(0, f.beg);
  f.read(&buf.at(0), static_cast<std::streamsize>(sz));
  f.close();

  std::string basedir = GetBaseDir(filename);

  bool ret = LoadASCIIFromString(scene, err, &buf.at(0),
                                 static_cast<unsigned int>(buf.size()), basedir,
                                 check_sections);

  return ret;
}

bool TinyGLTFLoader::LoadBinaryFromMemory(Scene *scene, std::string *err,
                                          const unsigned char *bytes,
                                          unsigned int size,
                                          const std::string &base_dir,
                                          unsigned int check_sections) {
  if (size < 20) {
    if (err) {
      (*err) = "Too short data size for glTF Binary.";
    }
    return false;
  }

  if (bytes[0] == 'g' && bytes[1] == 'l' && bytes[2] == 'T' &&
      bytes[3] == 'F') {
    // ok
  } else {
    if (err) {
      (*err) = "Invalid magic.";
    }
    return false;
  }

  unsigned int version;       // 4 bytes
  unsigned int length;        // 4 bytes
  unsigned int scene_length;  // 4 bytes
  unsigned int scene_format;  // 4 bytes;

  // @todo { Endian swap for big endian machine. }
  memcpy(&version, bytes + 4, 4);
  swap4(&version);
  memcpy(&length, bytes + 8, 4);
  swap4(&length);
  memcpy(&scene_length, bytes + 12, 4);
  swap4(&scene_length);
  memcpy(&scene_format, bytes + 16, 4);
  swap4(&scene_format);

  if ((20 + scene_length >= size) || (scene_length < 1) ||
      (scene_format != 0)) {  // 0 = JSON format.
    if (err) {
      (*err) = "Invalid glTF binary.";
    }
    return false;
  }

  // Extract JSON string.
  std::string jsonString(reinterpret_cast<const char *>(&bytes[20]),
                         scene_length);

  is_binary_ = true;
  bin_data_ = bytes + 20 + scene_length;
  bin_size_ =
      length - (20 + scene_length);  // extract header + JSON scene data.

  bool ret =
      LoadFromString(scene, err, reinterpret_cast<const char *>(&bytes[20]),
                     scene_length, base_dir, check_sections);
  if (!ret) {
    return ret;
  }

  return true;
}

bool TinyGLTFLoader::LoadBinaryFromFile(Scene *scene, std::string *err,
                                        const std::string &filename,
                                        unsigned int check_sections) {
  std::stringstream ss;

  std::ifstream f(filename.c_str(), std::ios::binary);
  if (!f) {
    ss << "Failed to open file: " << filename << std::endl;
    if (err) {
      (*err) = ss.str();
    }
    return false;
  }

  f.seekg(0, f.end);
  size_t sz = static_cast<size_t>(f.tellg());
  std::vector<char> buf(sz);

  f.seekg(0, f.beg);
  f.read(&buf.at(0), static_cast<std::streamsize>(sz));
  f.close();

  std::string basedir = GetBaseDir(filename);

  bool ret = LoadBinaryFromMemory(
      scene, err, reinterpret_cast<unsigned char *>(&buf.at(0)),
      static_cast<unsigned int>(buf.size()), basedir, check_sections);

  return ret;
}

}  // namespace tinygltf

#endif  // TINYGLTF_LOADER_IMPLEMENTATION

#endif  // TINY_GLTF_LOADER_H_
