/*
Open Asset Import Library (assimp)
----------------------------------------------------------------------

Copyright (c) 2006-2017, assimp team

All rights reserved.

Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the
following conditions are met:

* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.

* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.

* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

----------------------------------------------------------------------
*/

#include "StringUtils.h"

// Header files, Assimp
#include <assimp/DefaultLogger.hpp>

using namespace Assimp;

namespace glTF2 {

namespace {

    //
    // JSON Value reading helpers
    //

    template<class T>
    struct ReadHelper { static bool Read(Value& val, T& out) {
        return val.IsInt() ? out = static_cast<T>(val.GetInt()), true : false;
    }};

    template<> struct ReadHelper<bool> { static bool Read(Value& val, bool& out) {
        return val.IsBool() ? out = val.GetBool(), true : false;
    }};

    template<> struct ReadHelper<float> { static bool Read(Value& val, float& out) {
        return val.IsNumber() ? out = static_cast<float>(val.GetDouble()), true : false;
    }};

    template<unsigned int N> struct ReadHelper<float[N]> { static bool Read(Value& val, float (&out)[N]) {
        if (!val.IsArray() || val.Size() != N) return false;
        for (unsigned int i = 0; i < N; ++i) {
            if (val[i].IsNumber())
                out[i] = static_cast<float>(val[i].GetDouble());
        }
        return true;
    }};

    template<> struct ReadHelper<const char*> { static bool Read(Value& val, const char*& out) {
        return val.IsString() ? (out = val.GetString(), true) : false;
    }};

    template<> struct ReadHelper<std::string> { static bool Read(Value& val, std::string& out) {
        return val.IsString() ? (out = std::string(val.GetString(), val.GetStringLength()), true) : false;
    }};

    template<class T> struct ReadHelper< Nullable<T> > { static bool Read(Value& val, Nullable<T>& out) {
        return out.isPresent = ReadHelper<T>::Read(val, out.value);
    }};

    template<class T>
    inline static bool ReadValue(Value& val, T& out)
    {
        return ReadHelper<T>::Read(val, out);
    }

    template<class T>
    inline static bool ReadMember(Value& obj, const char* id, T& out)
    {
        Value::MemberIterator it = obj.FindMember(id);
        if (it != obj.MemberEnd()) {
            return ReadHelper<T>::Read(it->value, out);
        }
        return false;
    }

    template<class T>
    inline static T MemberOrDefault(Value& obj, const char* id, T defaultValue)
    {
        T out;
        return ReadMember(obj, id, out) ? out : defaultValue;
    }

    inline Value* FindMember(Value& val, const char* id)
    {
        Value::MemberIterator it = val.FindMember(id);
        return (it != val.MemberEnd()) ? &it->value : 0;
    }

    inline Value* FindString(Value& val, const char* id)
    {
        Value::MemberIterator it = val.FindMember(id);
        return (it != val.MemberEnd() && it->value.IsString()) ? &it->value : 0;
    }

    inline Value* FindNumber(Value& val, const char* id)
    {
        Value::MemberIterator it = val.FindMember(id);
        return (it != val.MemberEnd() && it->value.IsNumber()) ? &it->value : 0;
    }

    inline Value* FindUInt(Value& val, const char* id)
    {
        Value::MemberIterator it = val.FindMember(id);
        return (it != val.MemberEnd() && it->value.IsUint()) ? &it->value : 0;
    }

    inline Value* FindArray(Value& val, const char* id)
    {
        Value::MemberIterator it = val.FindMember(id);
        return (it != val.MemberEnd() && it->value.IsArray()) ? &it->value : 0;
    }

    inline Value* FindObject(Value& val, const char* id)
    {
        Value::MemberIterator it = val.FindMember(id);
        return (it != val.MemberEnd() && it->value.IsObject()) ? &it->value : 0;
    }
}

//
// LazyDict methods
//

template<class T>
inline LazyDict<T>::LazyDict(Asset& asset, const char* dictId, const char* extId)
    : mDictId(dictId), mExtId(extId), mDict(0), mAsset(asset)
{
    asset.mDicts.push_back(this); // register to the list of dictionaries
}

template<class T>
inline LazyDict<T>::~LazyDict()
{
    for (size_t i = 0; i < mObjs.size(); ++i) {
        delete mObjs[i];
    }
}


template<class T>
inline void LazyDict<T>::AttachToDocument(Document& doc)
{
    Value* container = 0;

    if (mExtId) {
        if (Value* exts = FindObject(doc, "extensions")) {
            container = FindObject(*exts, mExtId);
        }
    }
    else {
        container = &doc;
    }

    if (container) {
        mDict = FindArray(*container, mDictId);
    }
}

template<class T>
inline void LazyDict<T>::DetachFromDocument()
{
    mDict = 0;
}

template<class T>
unsigned int LazyDict<T>::Remove(const char* id)
{
    id = T::TranslateId(mAsset, id);

    typename IdDict::iterator it = mObjsById.find(id);

    if (it == mObjsById.end()) {
        throw DeadlyExportError("GLTF: Object with id \"" + std::string(id) + "\" is not found");
    }

    const unsigned int index = it->second;

    mAsset.mUsedIds[id] = false;
    mObjsById.erase(id);
    mObjsByOIndex.erase(index);
    mObjs.erase(mObjs.begin() + index);

    //update index of object in mObjs;
    for (unsigned int i = index; i < mObjs.size(); ++i) {
        T *obj = mObjs[i];

        obj->index = i;
    }

    for (IdDict::iterator it = mObjsById.begin(); it != mObjsById.end(); ++it) {
        if (it->second <= index) {
            continue;
        }

        mObjsById[it->first] = it->second - 1;
    }

    for (Dict::iterator it = mObjsByOIndex.begin(); it != mObjsByOIndex.end(); ++it) {
        if (it->second <= index) {
            continue;
        }

        mObjsByOIndex[it->first] = it->second - 1;
    }

    return index;
}

template<class T>
Ref<T> LazyDict<T>::Retrieve(unsigned int i)
{

    typename Dict::iterator it = mObjsByOIndex.find(i);
    if (it != mObjsByOIndex.end()) {// already created?
        return Ref<T>(mObjs, it->second);
    }

    // read it from the JSON object
    if (!mDict) {
        throw DeadlyImportError("GLTF: Missing section \"" + std::string(mDictId) + "\"");
    }

    if (!mDict->IsArray()) {
        throw DeadlyImportError("GLTF: Field is not an array \"" + std::string(mDictId) + "\"");
    }

    Value &obj = (*mDict)[i];

    if (!obj.IsObject()) {
        throw DeadlyImportError("GLTF: Object at index \"" + to_string(i) + "\" is not a JSON object");
    }

    T* inst = new T();
    inst->id = std::string(mDictId) + "_" + to_string(i);
    inst->oIndex = i;
    ReadMember(obj, "name", inst->name);
    inst->Read(obj, mAsset);

    return Add(inst);
}

template<class T>
Ref<T> LazyDict<T>::Get(unsigned int i)
{

    return Ref<T>(mObjs, i);

}

template<class T>
Ref<T> LazyDict<T>::Get(const char* id)
{
    id = T::TranslateId(mAsset, id);

    typename IdDict::iterator it = mObjsById.find(id);
    if (it != mObjsById.end()) { // already created?
        return Ref<T>(mObjs, it->second);
    }

    return Ref<T>();
}

template<class T>
Ref<T> LazyDict<T>::Add(T* obj)
{
    unsigned int idx = unsigned(mObjs.size());
    mObjs.push_back(obj);
    mObjsByOIndex[obj->oIndex] = idx;
    mObjsById[obj->id] = idx;
    mAsset.mUsedIds[obj->id] = true;
    return Ref<T>(mObjs, idx);
}

template<class T>
Ref<T> LazyDict<T>::Create(const char* id)
{
    Asset::IdMap::iterator it = mAsset.mUsedIds.find(id);
    if (it != mAsset.mUsedIds.end()) {
        throw DeadlyImportError("GLTF: two objects with the same ID exist");
    }
    T* inst = new T();
    unsigned int idx = unsigned(mObjs.size());
    inst->id = id;
    inst->index = idx;
    inst->oIndex = idx;
    return Add(inst);
}


//
// glTF dictionary objects methods
//


inline Buffer::Buffer()
	: byteLength(0), type(Type_arraybuffer), EncodedRegion_Current(nullptr), mIsSpecial(false)
{ }

inline Buffer::~Buffer()
{
	for(SEncodedRegion* reg : EncodedRegion_List) delete reg;
}

inline const char* Buffer::TranslateId(Asset& /*r*/, const char* id)
{
    return id;
}

inline void Buffer::Read(Value& obj, Asset& r)
{
    size_t statedLength = MemberOrDefault<size_t>(obj, "byteLength", 0);
    byteLength = statedLength;

    Value* it = FindString(obj, "uri");
    if (!it) {
        if (statedLength > 0) {
            throw DeadlyImportError("GLTF: buffer with non-zero length missing the \"uri\" attribute");
        }
        return;
    }

    const char* uri = it->GetString();

    Util::DataURI dataURI;
    if (ParseDataURI(uri, it->GetStringLength(), dataURI)) {
        if (dataURI.base64) {
            uint8_t* data = 0;
            this->byteLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, data);
            this->mData.reset(data, std::default_delete<uint8_t[]>());

            if (statedLength > 0 && this->byteLength != statedLength) {
                throw DeadlyImportError("GLTF: buffer \"" + id + "\", expected " + to_string(statedLength) +
                    " bytes, but found " + to_string(dataURI.dataLength));
            }
        }
        else { // assume raw data
            if (statedLength != dataURI.dataLength) {
                throw DeadlyImportError("GLTF: buffer \"" + id + "\", expected " + to_string(statedLength) +
                                        " bytes, but found " + to_string(dataURI.dataLength));
            }

            this->mData.reset(new uint8_t[dataURI.dataLength], std::default_delete<uint8_t[]>());
            memcpy( this->mData.get(), dataURI.data, dataURI.dataLength );
        }
    }
    else { // Local file
        if (byteLength > 0) {
            std::string dir = !r.mCurrentAssetDir.empty() ? (r.mCurrentAssetDir + "/") : "";

            IOStream* file = r.OpenFile(dir + uri, "rb");
            if (file) {
                bool ok = LoadFromStream(*file, byteLength);
                delete file;

                if (!ok)
                    throw DeadlyImportError("GLTF: error while reading referenced file \"" + std::string(uri) + "\"" );
            }
            else {
                throw DeadlyImportError("GLTF: could not open referenced file \"" + std::string(uri) + "\"");
            }
        }
    }
}

inline bool Buffer::LoadFromStream(IOStream& stream, size_t length, size_t baseOffset)
{
    byteLength = length ? length : stream.FileSize();

    if (baseOffset) {
        stream.Seek(baseOffset, aiOrigin_SET);
    }

    mData.reset(new uint8_t[byteLength], std::default_delete<uint8_t[]>());

    if (stream.Read(mData.get(), byteLength, 1) != 1) {
        return false;
    }
    return true;
}

inline void Buffer::EncodedRegion_Mark(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string& pID)
{
	// Check pointer to data
	if(pDecodedData == nullptr) throw DeadlyImportError("GLTF: for marking encoded region pointer to decoded data must be provided.");

	// Check offset
	if(pOffset > byteLength)
	{
		const uint8_t val_size = 32;

		char val[val_size];

		ai_snprintf(val, val_size, "%llu", (long long)pOffset);
		throw DeadlyImportError(std::string("GLTF: incorrect offset value (") + val + ") for marking encoded region.");
	}

	// Check length
	if((pOffset + pEncodedData_Length) > byteLength)
	{
		const uint8_t val_size = 64;

		char val[val_size];

		ai_snprintf(val, val_size, "%llu, %llu", (long long)pOffset, (long long)pEncodedData_Length);
		throw DeadlyImportError(std::string("GLTF: encoded region with offset/length (") + val + ") is out of range.");
	}

	// Add new region
	EncodedRegion_List.push_back(new SEncodedRegion(pOffset, pEncodedData_Length, pDecodedData, pDecodedData_Length, pID));
	// And set new value for "byteLength"
	byteLength += (pDecodedData_Length - pEncodedData_Length);
}

inline void Buffer::EncodedRegion_SetCurrent(const std::string& pID)
{
	if((EncodedRegion_Current != nullptr) && (EncodedRegion_Current->ID == pID)) return;

	for(SEncodedRegion* reg : EncodedRegion_List)
	{
		if(reg->ID == pID)
		{
			EncodedRegion_Current = reg;

			return;
		}

	}

	throw DeadlyImportError("GLTF: EncodedRegion with ID: \"" + pID + "\" not found.");
}

inline bool Buffer::ReplaceData(const size_t pBufferData_Offset, const size_t pBufferData_Count, const uint8_t* pReplace_Data, const size_t pReplace_Count)
{
const size_t new_data_size = byteLength + pReplace_Count - pBufferData_Count;

uint8_t* new_data;

	if((pBufferData_Count == 0) || (pReplace_Count == 0) || (pReplace_Data == nullptr)) return false;

	new_data = new uint8_t[new_data_size];
	// Copy data which place before replacing part.
	memcpy(new_data, mData.get(), pBufferData_Offset);
	// Copy new data.
	memcpy(&new_data[pBufferData_Offset], pReplace_Data, pReplace_Count);
	// Copy data which place after replacing part.
	memcpy(&new_data[pBufferData_Offset + pReplace_Count], &mData.get()[pBufferData_Offset + pBufferData_Count], pBufferData_Offset);
	// Apply new data
	mData.reset(new_data, std::default_delete<uint8_t[]>());
	byteLength = new_data_size;

	return true;
}

inline size_t Buffer::AppendData(uint8_t* data, size_t length)
{
    size_t offset = this->byteLength;
    Grow(length);
    memcpy(mData.get() + offset, data, length);
    return offset;
}

inline void Buffer::Grow(size_t amount)
{
    if (amount <= 0) return;
    uint8_t* b = new uint8_t[byteLength + amount];
    if (mData) memcpy(b, mData.get(), byteLength);
    mData.reset(b, std::default_delete<uint8_t[]>());
    byteLength += amount;
}

//
// struct BufferView
//

inline void BufferView::Read(Value& obj, Asset& r)
{

    if (Value* bufferVal = FindUInt(obj, "buffer")) {
        buffer = r.buffers.Retrieve(bufferVal->GetUint());
    }

    byteOffset = MemberOrDefault(obj, "byteOffset", 0u);
    byteLength = MemberOrDefault(obj, "byteLength", 0u);
    byteStride = MemberOrDefault(obj, "byteStride", 0u);
}

//
// struct Accessor
//

inline void Accessor::Read(Value& obj, Asset& r)
{

    if (Value* bufferViewVal = FindUInt(obj, "bufferView")) {
        bufferView = r.bufferViews.Retrieve(bufferViewVal->GetUint());
    }

    byteOffset = MemberOrDefault(obj, "byteOffset", 0u);
    componentType = MemberOrDefault(obj, "componentType", ComponentType_BYTE);
    count = MemberOrDefault(obj, "count", 0u);

    const char* typestr;
    type = ReadMember(obj, "type", typestr) ? AttribType::FromString(typestr) : AttribType::SCALAR;
}

inline unsigned int Accessor::GetNumComponents()
{
    return AttribType::GetNumComponents(type);
}

inline unsigned int Accessor::GetBytesPerComponent()
{
    return int(ComponentTypeSize(componentType));
}

inline unsigned int Accessor::GetElementSize()
{
    return GetNumComponents() * GetBytesPerComponent();
}

inline uint8_t* Accessor::GetPointer()
{
    if (!bufferView || !bufferView->buffer) return 0;
    uint8_t* basePtr = bufferView->buffer->GetPointer();
    if (!basePtr) return 0;

    size_t offset = byteOffset + bufferView->byteOffset;

	// Check if region is encoded.
	if(bufferView->buffer->EncodedRegion_Current != nullptr)
	{
		const size_t begin = bufferView->buffer->EncodedRegion_Current->Offset;
		const size_t end = begin + bufferView->buffer->EncodedRegion_Current->DecodedData_Length;

		if((offset >= begin) && (offset < end))
			return &bufferView->buffer->EncodedRegion_Current->DecodedData[offset - begin];
	}

	return basePtr + offset;
}

namespace {
    inline void CopyData(size_t count,
            const uint8_t* src, size_t src_stride,
                  uint8_t* dst, size_t dst_stride)
    {
        if (src_stride == dst_stride) {
            memcpy(dst, src, count * src_stride);
        }
        else {
            size_t sz = std::min(src_stride, dst_stride);
            for (size_t i = 0; i < count; ++i) {
                memcpy(dst, src, sz);
                if (sz < dst_stride) {
                    memset(dst + sz, 0, dst_stride - sz);
                }
                src += src_stride;
                dst += dst_stride;
            }
        }
    }
}

template<class T>
bool Accessor::ExtractData(T*& outData)
{
    uint8_t* data = GetPointer();
    if (!data) return false;

    const size_t elemSize = GetElementSize();
    const size_t totalSize = elemSize * count;

    const size_t stride = bufferView && bufferView->byteStride ? bufferView->byteStride : elemSize;

    const size_t targetElemSize = sizeof(T);
    ai_assert(elemSize <= targetElemSize);

    ai_assert(count*stride <= bufferView->byteLength);

    outData = new T[count];
    if (stride == elemSize && targetElemSize == elemSize) {
        memcpy(outData, data, totalSize);
    }
    else {
        for (size_t i = 0; i < count; ++i) {
            memcpy(outData + i, data + i*stride, elemSize);
        }
    }

    return true;
}

inline void Accessor::WriteData(size_t count, const void* src_buffer, size_t src_stride)
{
    uint8_t* buffer_ptr = bufferView->buffer->GetPointer();
    size_t offset = byteOffset + bufferView->byteOffset;

    size_t dst_stride = GetNumComponents() * GetBytesPerComponent();

    const uint8_t* src = reinterpret_cast<const uint8_t*>(src_buffer);
    uint8_t*       dst = reinterpret_cast<      uint8_t*>(buffer_ptr + offset);

    ai_assert(dst + count*dst_stride <= buffer_ptr + bufferView->buffer->byteLength);
    CopyData(count, src, src_stride, dst, dst_stride);
}



inline Accessor::Indexer::Indexer(Accessor& acc)
    : accessor(acc)
    , data(acc.GetPointer())
    , elemSize(acc.GetElementSize())
    , stride(acc.bufferView && acc.bufferView->byteStride ? acc.bufferView->byteStride : elemSize)
{

}

//! Accesses the i-th value as defined by the accessor
template<class T>
T Accessor::Indexer::GetValue(int i)
{
    ai_assert(data);
    ai_assert(i*stride < accessor.bufferView->byteLength);
    T value = T();
    memcpy(&value, data + i*stride, elemSize);
    //value >>= 8 * (sizeof(T) - elemSize);
    return value;
}

inline Image::Image()
    : width(0)
    , height(0)
    , mData(0)
    , mDataLength(0)
{

}

inline void Image::Read(Value& obj, Asset& /*r*/)
{
    if (!mDataLength) {
        if (Value* uri = FindString(obj, "uri")) {
            const char* uristr = uri->GetString();

            Util::DataURI dataURI;
            if (ParseDataURI(uristr, uri->GetStringLength(), dataURI)) {
                mimeType = dataURI.mediaType;
                if (dataURI.base64) {
                    mDataLength = Util::DecodeBase64(dataURI.data, dataURI.dataLength, mData);
                }
            }
            else {
                this->uri = uristr;
            }
        }
    }
}

inline uint8_t* Image::StealData()
{
    uint8_t* data = mData;
    mDataLength = 0;
    mData = 0;
    return data;
}

inline void Image::SetData(uint8_t* data, size_t length, Asset& r)
{
    Ref<Buffer> b = r.GetBodyBuffer();
    if (b) { // binary file: append to body
        std::string bvId = r.FindUniqueID(this->id, "imgdata");
        bufferView = r.bufferViews.Create(bvId);

        bufferView->buffer = b;
        bufferView->byteLength = length;
        bufferView->byteOffset = b->AppendData(data, length);
    }
    else { // text file: will be stored as a data uri
        this->mData = data;
        this->mDataLength = length;
    }
}

inline void Sampler::Read(Value& obj, Asset& /*r*/)
{
    SetDefaults();

    ReadMember(obj, "name", name);
    ReadMember(obj, "magFilter", magFilter);
    ReadMember(obj, "minFilter", minFilter);
    ReadMember(obj, "wrapS", wrapS);
    ReadMember(obj, "wrapT", wrapT);
}

inline void Sampler::SetDefaults()
{
    //only wrapping modes have defaults
    wrapS = SamplerWrap::Repeat;
    wrapT = SamplerWrap::Repeat;
    magFilter = SamplerMagFilter::UNSET;
    minFilter = SamplerMinFilter::UNSET;
}

inline void Texture::Read(Value& obj, Asset& r)
{
    if (Value* sourceVal = FindUInt(obj, "source")) {
        source = r.images.Retrieve(sourceVal->GetUint());
    }

    if (Value* samplerVal = FindUInt(obj, "sampler")) {
        sampler = r.samplers.Retrieve(samplerVal->GetUint());
    }
}

namespace {
    inline void SetTextureProperties(Asset& r, Value* prop, TextureInfo& out)
    {
        if (Value* index = FindUInt(*prop, "index")) {
            out.texture = r.textures.Retrieve(index->GetUint());
        }

        if (Value* texcoord = FindUInt(*prop, "texCoord")) {
            out.texCoord = texcoord->GetUint();
        }
    }

    inline void ReadTextureProperty(Asset& r, Value& vals, const char* propName, TextureInfo& out)
    {
        if (Value* prop = FindMember(vals, propName)) {
            SetTextureProperties(r, prop, out);
        }
    }

    inline void ReadTextureProperty(Asset& r, Value& vals, const char* propName, NormalTextureInfo& out)
    {
        if (Value* prop = FindMember(vals, propName)) {
            SetTextureProperties(r, prop, out);

            if (Value* scale = FindNumber(*prop, "scale")) {
                out.scale = static_cast<float>(scale->GetDouble());
            }
        }
    }

    inline void ReadTextureProperty(Asset& r, Value& vals, const char* propName, OcclusionTextureInfo& out)
    {
        if (Value* prop = FindMember(vals, propName)) {
            SetTextureProperties(r, prop, out);

            if (Value* strength = FindNumber(*prop, "strength")) {
                out.strength = static_cast<float>(strength->GetDouble());
            }
        }
    }
}

inline void Material::Read(Value& material, Asset& r)
{
    SetDefaults();

    if (Value* pbrMetallicRoughness = FindObject(material, "pbrMetallicRoughness")) {
        ReadMember(*pbrMetallicRoughness, "baseColorFactor", this->pbrMetallicRoughness.baseColorFactor);
        ReadTextureProperty(r, *pbrMetallicRoughness, "baseColorTexture", this->pbrMetallicRoughness.baseColorTexture);
        ReadTextureProperty(r, *pbrMetallicRoughness, "metallicRoughnessTexture", this->pbrMetallicRoughness.metallicRoughnessTexture);
        ReadMember(*pbrMetallicRoughness, "metallicFactor", this->pbrMetallicRoughness.metallicFactor);
        ReadMember(*pbrMetallicRoughness, "roughnessFactor", this->pbrMetallicRoughness.roughnessFactor);
    }

    ReadTextureProperty(r, material, "normalTexture", this->normalTexture);
    ReadTextureProperty(r, material, "occlusionTexture", this->occlusionTexture);
    ReadTextureProperty(r, material, "emissiveTexture", this->emissiveTexture);
    ReadMember(material, "emissiveFactor", this->emissiveFactor);

    ReadMember(material, "doubleSided", this->doubleSided);
    ReadMember(material, "alphaMode", this->alphaMode);
    ReadMember(material, "alphaCutoff", this->alphaCutoff);

    if (Value* extensions = FindObject(material, "extensions")) {
        if (r.extensionsUsed.KHR_materials_pbrSpecularGlossiness) {
            if (Value* pbrSpecularGlossiness = FindObject(*extensions, "KHR_materials_pbrSpecularGlossiness")) {
                PbrSpecularGlossiness pbrSG;

                ReadMember(*pbrSpecularGlossiness, "diffuseFactor", pbrSG.diffuseFactor);
                ReadTextureProperty(r, *pbrSpecularGlossiness, "diffuseTexture", pbrSG.diffuseTexture);
                ReadTextureProperty(r, *pbrSpecularGlossiness, "specularGlossinessTexture", pbrSG.specularGlossinessTexture);
                ReadMember(*pbrSpecularGlossiness, "specularFactor", pbrSG.specularFactor);
                ReadMember(*pbrSpecularGlossiness, "glossinessFactor", pbrSG.glossinessFactor);

                this->pbrSpecularGlossiness = Nullable<PbrSpecularGlossiness>(pbrSG);
            }
        }
    }
}

namespace {
    void SetVector(vec4& v, const float(&in)[4])
        { v[0] = in[0]; v[1] = in[1]; v[2] = in[2]; v[3] = in[3]; }

    void SetVector(vec3& v, const float(&in)[3])
        { v[0] = in[0]; v[1] = in[1]; v[2] = in[2]; }
}

inline void Material::SetDefaults()
{
    //pbr materials
    SetVector(pbrMetallicRoughness.baseColorFactor, defaultBaseColor);
    pbrMetallicRoughness.metallicFactor = 1.0;
    pbrMetallicRoughness.roughnessFactor = 1.0;

    SetVector(emissiveFactor, defaultEmissiveFactor);
    alphaMode = "OPAQUE";
    alphaCutoff = 0.5;
    doubleSided = false;
}

inline void PbrSpecularGlossiness::SetDefaults()
{
    //pbrSpecularGlossiness properties
    SetVector(diffuseFactor, defaultDiffuseFactor);
    SetVector(specularFactor, defaultSpecularFactor);
    glossinessFactor = 1.0;
}

namespace {

    template<int N>
    inline int Compare(const char* attr, const char (&str)[N]) {
        return (strncmp(attr, str, N - 1) == 0) ? N - 1 : 0;
    }

    inline bool GetAttribVector(Mesh::Primitive& p, const char* attr, Mesh::AccessorList*& v, int& pos)
    {
        if ((pos = Compare(attr, "POSITION"))) {
            v = &(p.attributes.position);
        }
        else if ((pos = Compare(attr, "NORMAL"))) {
            v = &(p.attributes.normal);
        }
        else if ((pos = Compare(attr, "TANGENT"))) {
            v = &(p.attributes.tangent);
        }
        else if ((pos = Compare(attr, "TEXCOORD"))) {
            v = &(p.attributes.texcoord);
        }
        else if ((pos = Compare(attr, "COLOR"))) {
            v = &(p.attributes.color);
        }
        else if ((pos = Compare(attr, "JOINT"))) {
            v = &(p.attributes.joint);
        }
        else if ((pos = Compare(attr, "JOINTMATRIX"))) {
            v = &(p.attributes.jointmatrix);
        }
        else if ((pos = Compare(attr, "WEIGHT"))) {
            v = &(p.attributes.weight);
        }
        else return false;
        return true;
    }
}

inline void Mesh::Read(Value& pJSON_Object, Asset& pAsset_Root)
{
    if (Value* name = FindMember(pJSON_Object, "name")) {
        this->name = name->GetString();
    }

	/****************** Mesh primitives ******************/
	if (Value* primitives = FindArray(pJSON_Object, "primitives")) {
        this->primitives.resize(primitives->Size());
        for (unsigned int i = 0; i < primitives->Size(); ++i) {
            Value& primitive = (*primitives)[i];

            Primitive& prim = this->primitives[i];
            prim.mode = MemberOrDefault(primitive, "mode", PrimitiveMode_TRIANGLES);

            if (Value* attrs = FindObject(primitive, "attributes")) {
                for (Value::MemberIterator it = attrs->MemberBegin(); it != attrs->MemberEnd(); ++it) {
                    if (!it->value.IsUint()) continue;
                    const char* attr = it->name.GetString();
                    // Valid attribute semantics include POSITION, NORMAL, TANGENT, TEXCOORD, COLOR, JOINT, JOINTMATRIX,
                    // and WEIGHT.Attribute semantics can be of the form[semantic]_[set_index], e.g., TEXCOORD_0, TEXCOORD_1, etc.

                    int undPos = 0;
                    Mesh::AccessorList* vec = 0;
                    if (GetAttribVector(prim, attr, vec, undPos)) {
                        size_t idx = (attr[undPos] == '_') ? atoi(attr + undPos + 1) : 0;
                        if ((*vec).size() <= idx) (*vec).resize(idx + 1);
						(*vec)[idx] = pAsset_Root.accessors.Retrieve(it->value.GetUint());
                    }
                }
            }

            if (Value* indices = FindUInt(primitive, "indices")) {
				prim.indices = pAsset_Root.accessors.Retrieve(indices->GetUint());
            }

            if (Value* material = FindUInt(primitive, "material")) {
				prim.material = pAsset_Root.materials.Retrieve(material->GetUint());
            }
        }
    }
}

inline void Camera::Read(Value& obj, Asset& /*r*/)
{
    type = MemberOrDefault(obj, "type", Camera::Perspective);

    const char* subobjId = (type == Camera::Orthographic) ? "orthographic" : "perspective";

    Value* it = FindObject(obj, subobjId);
    if (!it) throw DeadlyImportError("GLTF: Camera missing its parameters");

    if (type == Camera::Perspective) {
        cameraProperties.perspective.aspectRatio = MemberOrDefault(*it, "aspectRatio", 0.f);
        cameraProperties.perspective.yfov        = MemberOrDefault(*it, "yfov", 3.1415f/2.f);
        cameraProperties.perspective.zfar        = MemberOrDefault(*it, "zfar", 100.f);
        cameraProperties.perspective.znear       = MemberOrDefault(*it, "znear", 0.01f);
    }
    else {
        cameraProperties.ortographic.xmag  = MemberOrDefault(obj, "xmag", 1.f);
        cameraProperties.ortographic.ymag  = MemberOrDefault(obj, "ymag", 1.f);
        cameraProperties.ortographic.zfar  = MemberOrDefault(obj, "zfar", 100.f);
        cameraProperties.ortographic.znear = MemberOrDefault(obj, "znear", 0.01f);
    }
}

inline void Node::Read(Value& obj, Asset& r)
{

    if (Value* children = FindArray(obj, "children")) {
        this->children.reserve(children->Size());
        for (unsigned int i = 0; i < children->Size(); ++i) {
            Value& child = (*children)[i];
            if (child.IsUint()) {
                // get/create the child node
                Ref<Node> chn = r.nodes.Retrieve(child.GetUint());
                if (chn) this->children.push_back(chn);
            }
        }
    }

    if (Value* matrix = FindArray(obj, "matrix")) {
        ReadValue(*matrix, this->matrix);
    }
    else {
        ReadMember(obj, "translation", translation);
        ReadMember(obj, "scale", scale);
        ReadMember(obj, "rotation", rotation);
    }

    if (Value* mesh = FindUInt(obj, "mesh")) {
        unsigned numMeshes = 1;

        this->meshes.reserve(numMeshes);

        Ref<Mesh> meshRef = r.meshes.Retrieve((*mesh).GetUint());

        if (meshRef) this->meshes.push_back(meshRef);
    }

    if (Value* camera = FindUInt(obj, "camera")) {
        this->camera = r.cameras.Retrieve(camera->GetUint());
        if (this->camera)
            this->camera->id = this->id;
    }
}

inline void Scene::Read(Value& obj, Asset& r)
{
    if (Value* array = FindArray(obj, "nodes")) {
        for (unsigned int i = 0; i < array->Size(); ++i) {
            if (!(*array)[i].IsUint()) continue;
            Ref<Node> node = r.nodes.Retrieve((*array)[i].GetUint());
            if (node)
                this->nodes.push_back(node);
        }
    }
}

inline void AssetMetadata::Read(Document& doc)
{
    if (Value* obj = FindObject(doc, "asset")) {
        ReadMember(*obj, "copyright", copyright);
        ReadMember(*obj, "generator", generator);

        if (Value* versionString = FindString(*obj, "version")) {
            version = versionString->GetString();
        } else if (Value* versionNumber = FindNumber (*obj, "version")) {
            char buf[4];

            ai_snprintf(buf, 4, "%.1f", versionNumber->GetDouble());

            version = buf;
        }

        if (Value* profile = FindObject(*obj, "profile")) {
            ReadMember(*profile, "api",     this->profile.api);
            ReadMember(*profile, "version", this->profile.version);
        }
    }

    if (version.empty() || version[0] != '2') {
        throw DeadlyImportError("GLTF: Unsupported glTF version: " + version);
    }
}

//
// Asset methods implementation
//

inline void Asset::ReadBinaryHeader(IOStream& stream, std::vector<char>& sceneData)
{
    GLB_Header header;
    if (stream.Read(&header, sizeof(header), 1) != 1) {
        throw DeadlyImportError("GLTF: Unable to read the file header");
    }

    if (strncmp((char*)header.magic, AI_GLB_MAGIC_NUMBER, sizeof(header.magic)) != 0) {
        throw DeadlyImportError("GLTF: Invalid binary glTF file");
    }

    AI_SWAP4(header.version);
    asset.version = to_string(header.version);
    if (header.version != 2) {
        throw DeadlyImportError("GLTF: Unsupported binary glTF version");
    }

    GLB_Chunk chunk;
    if (stream.Read(&chunk, sizeof(chunk), 1) != 1) {
        throw DeadlyImportError("GLTF: Unable to read JSON chunk");
    }

    AI_SWAP4(chunk.chunkLength);
    AI_SWAP4(chunk.chunkType);

    if (chunk.chunkType != ChunkType_JSON) {
        throw DeadlyImportError("GLTF: JSON chunk missing");
    }

    // read the scene data

    mSceneLength = chunk.chunkLength;
    sceneData.resize(mSceneLength + 1);
    sceneData[mSceneLength] = '\0';

    if (stream.Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
        throw DeadlyImportError("GLTF: Could not read the file contents");
    }

    uint32_t padding = ((chunk.chunkLength + 3) & ~3) - chunk.chunkLength;
    if (padding > 0) {
        stream.Seek(padding, aiOrigin_CUR);
    }

    AI_SWAP4(header.length);
    mBodyOffset = 12 + 8 + chunk.chunkLength + padding + 8;
    if (header.length >= mBodyOffset) {
        if (stream.Read(&chunk, sizeof(chunk), 1) != 1) {
            throw DeadlyImportError("GLTF: Unable to read BIN chunk");
        }

        AI_SWAP4(chunk.chunkLength);
        AI_SWAP4(chunk.chunkType);

        if (chunk.chunkType != ChunkType_BIN) {
            throw DeadlyImportError("GLTF: BIN chunk missing");
        }

        mBodyLength = chunk.chunkLength;
    }
    else {
        mBodyOffset = mBodyLength = 0;
    }
}

inline void Asset::Load(const std::string& pFile, bool isBinary)
{
    mCurrentAssetDir.clear();
    int pos = std::max(int(pFile.rfind('/')), int(pFile.rfind('\\')));
    if (pos != int(std::string::npos)) mCurrentAssetDir = pFile.substr(0, pos + 1);

    shared_ptr<IOStream> stream(OpenFile(pFile.c_str(), "rb", true));
    if (!stream) {
        throw DeadlyImportError("GLTF: Could not open file for reading");
    }

    // is binary? then read the header
    std::vector<char> sceneData;
    if (isBinary) {
        SetAsBinary(); // also creates the body buffer
        ReadBinaryHeader(*stream, sceneData);
    }
    else {
        mSceneLength = stream->FileSize();
        mBodyLength = 0;


        // read the scene data

        sceneData.resize(mSceneLength + 1);
        sceneData[mSceneLength] = '\0';

        if (stream->Read(&sceneData[0], 1, mSceneLength) != mSceneLength) {
            throw DeadlyImportError("GLTF: Could not read the file contents");
        }
    }


    // parse the JSON document

    Document doc;
    doc.ParseInsitu(&sceneData[0]);

    if (doc.HasParseError()) {
        char buffer[32];
        ai_snprintf(buffer, 32, "%d", static_cast<int>(doc.GetErrorOffset()));
        throw DeadlyImportError(std::string("GLTF: JSON parse error, offset ") + buffer + ": "
            + GetParseError_En(doc.GetParseError()));
    }

    if (!doc.IsObject()) {
        throw DeadlyImportError("GLTF: JSON document root must be a JSON object");
    }

    // Fill the buffer instance for the current file embedded contents
    if (mBodyLength > 0) {
        if (!mBodyBuffer->LoadFromStream(*stream, mBodyLength, mBodyOffset)) {
            throw DeadlyImportError("GLTF: Unable to read gltf file");
        }
    }


    // Load the metadata
    asset.Read(doc);
    ReadExtensionsUsed(doc);

    // Prepare the dictionaries
    for (size_t i = 0; i < mDicts.size(); ++i) {
        mDicts[i]->AttachToDocument(doc);
    }

    // Read the "scene" property, which specifies which scene to load
    // and recursively load everything referenced by it
    if (Value* scene = FindUInt(doc, "scene")) {
        unsigned int sceneIndex = scene->GetUint();

        Ref<Scene> s = scenes.Retrieve(sceneIndex);

        this->scene = s;
    }

    // Clean up
    for (size_t i = 0; i < mDicts.size(); ++i) {
        mDicts[i]->DetachFromDocument();
    }
}

inline void Asset::SetAsBinary()
{
    if (!mBodyBuffer) {
        mBodyBuffer = buffers.Create("binary_glTF");
        mBodyBuffer->MarkAsSpecial();
    }
}


inline void Asset::ReadExtensionsUsed(Document& doc)
{
    Value* extsUsed = FindArray(doc, "extensionsUsed");
    if (!extsUsed) return;

    std::gltf_unordered_map<std::string, bool> exts;

    for (unsigned int i = 0; i < extsUsed->Size(); ++i) {
        if ((*extsUsed)[i].IsString()) {
            exts[(*extsUsed)[i].GetString()] = true;
        }
    }

    #define CHECK_EXT(EXT) \
        if (exts.find(#EXT) != exts.end()) extensionsUsed.EXT = true;

    CHECK_EXT(KHR_materials_pbrSpecularGlossiness);

    #undef CHECK_EXT
}

inline IOStream* Asset::OpenFile(std::string path, const char* mode, bool /*absolute*/)
{
    #ifdef ASSIMP_API
        return mIOSystem->Open(path, mode);
    #else
        if (path.size() < 2) return 0;
        if (!absolute && path[1] != ':' && path[0] != '/') { // relative?
            path = mCurrentAssetDir + path;
        }
        FILE* f = fopen(path.c_str(), mode);
        return f ? new IOStream(f) : 0;
    #endif
}

inline std::string Asset::FindUniqueID(const std::string& str, const char* suffix)
{
    std::string id = str;

    if (!id.empty()) {
        if (mUsedIds.find(id) == mUsedIds.end())
            return id;

        id += "_";
    }

    id += suffix;

    Asset::IdMap::iterator it = mUsedIds.find(id);
    if (it == mUsedIds.end())
        return id;

    std::vector<char> buffer;
    buffer.resize(id.size() + 16);
    int offset = ai_snprintf(buffer.data(), buffer.size(), "%s_", id.c_str());
    for (int i = 0; it != mUsedIds.end(); ++i) {
        ai_snprintf(buffer.data() + offset, buffer.size() - offset, "%d", i);
        id = buffer.data();
        it = mUsedIds.find(id);
    }

    return id;
}

namespace Util {

    inline
    bool ParseDataURI(const char* const_uri, size_t uriLen, DataURI& out) {
        if ( NULL == const_uri ) {
            return false;
        }

        if (const_uri[0] != 0x10) { // we already parsed this uri?
            if (strncmp(const_uri, "data:", 5) != 0) // not a data uri?
                return false;
        }

        // set defaults
        out.mediaType = "text/plain";
        out.charset = "US-ASCII";
        out.base64 = false;

        char* uri = const_cast<char*>(const_uri);
        if (uri[0] != 0x10) {
            uri[0] = 0x10;
            uri[1] = uri[2] = uri[3] = uri[4] = 0;

            size_t i = 5, j;
            if (uri[i] != ';' && uri[i] != ',') { // has media type?
                uri[1] = char(i);
                for (; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
                    // nothing to do!
                }
            }
            while (uri[i] == ';' && i < uriLen) {
                uri[i++] = '\0';
                for (j = i; uri[i] != ';' && uri[i] != ',' && i < uriLen; ++i) {
                    // nothing to do!
                }

                if ( strncmp( uri + j, "charset=", 8 ) == 0 ) {
                    uri[2] = char(j + 8);
                } else if ( strncmp( uri + j, "base64", 6 ) == 0 ) {
                    uri[3] = char(j);
                }
            }
            if (i < uriLen) {
                uri[i++] = '\0';
                uri[4] = char(i);
            } else {
                uri[1] = uri[2] = uri[3] = 0;
                uri[4] = 5;
            }
        }

        if ( uri[ 1 ] != 0 ) {
            out.mediaType = uri + uri[ 1 ];
        }
        if ( uri[ 2 ] != 0 ) {
            out.charset = uri + uri[ 2 ];
        }
        if ( uri[ 3 ] != 0 ) {
            out.base64 = true;
        }
        out.data = uri + uri[4];
        out.dataLength = (uri + uriLen) - out.data;

        return true;
    }

    template<bool B>
    struct DATA
    {
        static const uint8_t tableDecodeBase64[128];
    };

    template<bool B>
    const uint8_t DATA<B>::tableDecodeBase64[128] = {
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
         0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, 62,  0,  0,  0, 63,
        52, 53, 54, 55, 56, 57, 58, 59, 60, 61,  0,  0,  0, 64,  0,  0,
         0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,  0,  0,  0,  0,  0,
         0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,  0,  0,  0,  0,  0
    };

    inline char EncodeCharBase64(uint8_t b)
    {
        return "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="[size_t(b)];
    }

    inline uint8_t DecodeCharBase64(char c)
    {
        return DATA<true>::tableDecodeBase64[size_t(c)]; // TODO faster with lookup table or ifs?
        /*if (c >= 'A' && c <= 'Z') return c - 'A';
        if (c >= 'a' && c <= 'z') return c - 'a' + 26;
        if (c >= '0' && c <= '9') return c - '0' + 52;
        if (c == '+') return 62;
        if (c == '/') return 63;
        return 64; // '-' */
    }

    inline size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out)
    {
        ai_assert(inLength % 4 == 0);

        if (inLength < 4) {
            out = 0;
            return 0;
        }

        int nEquals = int(in[inLength - 1] == '=') +
                      int(in[inLength - 2] == '=');

        size_t outLength = (inLength * 3) / 4 - nEquals;
        out = new uint8_t[outLength];
        memset(out, 0, outLength);

        size_t i, j = 0;

        for (i = 0; i + 4 < inLength; i += 4) {
            uint8_t b0 = DecodeCharBase64(in[i]);
            uint8_t b1 = DecodeCharBase64(in[i + 1]);
            uint8_t b2 = DecodeCharBase64(in[i + 2]);
            uint8_t b3 = DecodeCharBase64(in[i + 3]);

            out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
            out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
            out[j++] = (uint8_t)((b2 << 6) | b3);
        }

        {
            uint8_t b0 = DecodeCharBase64(in[i]);
            uint8_t b1 = DecodeCharBase64(in[i + 1]);
            uint8_t b2 = DecodeCharBase64(in[i + 2]);
            uint8_t b3 = DecodeCharBase64(in[i + 3]);

            out[j++] = (uint8_t)((b0 << 2) | (b1 >> 4));
            if (b2 < 64) out[j++] = (uint8_t)((b1 << 4) | (b2 >> 2));
            if (b3 < 64) out[j++] = (uint8_t)((b2 << 6) | b3);
        }

        return outLength;
    }



    inline void EncodeBase64(
        const uint8_t* in, size_t inLength,
        std::string& out)
    {
        size_t outLength = ((inLength + 2) / 3) * 4;

        size_t j = out.size();
        out.resize(j + outLength);

        for (size_t i = 0; i <  inLength; i += 3) {
            uint8_t b = (in[i] & 0xFC) >> 2;
            out[j++] = EncodeCharBase64(b);

            b = (in[i] & 0x03) << 4;
            if (i + 1 < inLength) {
                b |= (in[i + 1] & 0xF0) >> 4;
                out[j++] = EncodeCharBase64(b);

                b = (in[i + 1] & 0x0F) << 2;
                if (i + 2 < inLength) {
                    b |= (in[i + 2] & 0xC0) >> 6;
                    out[j++] = EncodeCharBase64(b);

                    b = in[i + 2] & 0x3F;
                    out[j++] = EncodeCharBase64(b);
                }
                else {
                    out[j++] = EncodeCharBase64(b);
                    out[j++] = '=';
                }
            }
            else {
                out[j++] = EncodeCharBase64(b);
                out[j++] = '=';
                out[j++] = '=';
            }
        }
    }

}

} // ns glTF
