﻿/*
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.

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

/** @file glTFAsset.h
 * Declares a glTF class to handle gltf/glb files
 *
 * glTF Extensions Support:
 *   KHR_materials_pbrSpecularGlossiness full
 */
#ifndef GLTF2ASSET_H_INC
#define GLTF2ASSET_H_INC

#ifndef ASSIMP_BUILD_NO_GLTF_IMPORTER

#include <map>
#include <string>
#include <list>
#include <vector>
#include <algorithm>
#include <stdexcept>

#define RAPIDJSON_HAS_STDSTRING 1
#include <rapidjson/rapidjson.h>
#include <rapidjson/document.h>
#include <rapidjson/error/en.h>

#ifdef ASSIMP_API
#   include <memory>
#   include <assimp/DefaultIOSystem.h>
#   include "ByteSwapper.h"
#else
#   include <memory>
#   define AI_SWAP4(p)
#   define ai_assert
#endif


#if _MSC_VER > 1500 || (defined __GNUC___)
#       define ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
#   else
#       define gltf_unordered_map map
#endif

#ifdef ASSIMP_GLTF_USE_UNORDERED_MULTIMAP
#   include <unordered_map>
#   if _MSC_VER > 1600
#       define gltf_unordered_map unordered_map
#   else
#       define gltf_unordered_map tr1::unordered_map
#   endif
#endif

#include "StringUtils.h"

namespace glTF2
{
#ifdef ASSIMP_API
    using Assimp::IOStream;
    using Assimp::IOSystem;
    using std::shared_ptr;
#else
    using std::shared_ptr;

    typedef std::runtime_error DeadlyImportError;
    typedef std::runtime_error DeadlyExportError;

    enum aiOrigin { aiOrigin_SET = 0, aiOrigin_CUR = 1, aiOrigin_END = 2 };
    class IOSystem;
    class IOStream
    {
        FILE* f;
    public:
        IOStream(FILE* file) : f(file) {}
        ~IOStream() { fclose(f); f = 0; }

        size_t Read(void* b, size_t sz, size_t n) { return fread(b, sz, n, f); }
        size_t Write(const void* b, size_t sz, size_t n) { return fwrite(b, sz, n, f); }
        int    Seek(size_t off, aiOrigin orig) { return fseek(f, off, int(orig)); }
        size_t Tell() const { return ftell(f); }

        size_t FileSize() {
            long p = Tell(), len = (Seek(0, aiOrigin_END), Tell());
            return size_t((Seek(p, aiOrigin_SET), len));
        }
    };
#endif

    using rapidjson::Value;
    using rapidjson::Document;

    class Asset;
    class AssetWriter;

    struct BufferView; // here due to cross-reference
    struct Texture;
    struct Skin;

    // Vec/matrix types, as raw float arrays
    typedef float (vec3)[3];
    typedef float (vec4)[4];
	typedef float (mat4)[16];

    namespace Util
    {
        void EncodeBase64(const uint8_t* in, size_t inLength, std::string& out);

        size_t DecodeBase64(const char* in, size_t inLength, uint8_t*& out);

        inline size_t DecodeBase64(const char* in, uint8_t*& out)
        {
            return DecodeBase64(in, strlen(in), out);
        }

        struct DataURI
        {
            const char* mediaType;
            const char* charset;
            bool base64;
            const char* data;
            size_t dataLength;
        };

        //! Check if a uri is a data URI
        inline bool ParseDataURI(const char* uri, size_t uriLen, DataURI& out);
    }


    //! Magic number for GLB files
	#define AI_GLB_MAGIC_NUMBER "glTF"

    #define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR "$mat.gltf.pbrMetallicRoughness.baseColorFactor", 0, 0
	#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR "$mat.gltf.pbrMetallicRoughness.metallicFactor", 0, 0
	#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR "$mat.gltf.pbrMetallicRoughness.roughnessFactor", 0, 0
    #define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_TEXTURE aiTextureType_DIFFUSE, 1
	#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE aiTextureType_UNKNOWN, 0
	#define AI_MATKEY_GLTF_ALPHAMODE "$mat.gltf.alphaMode", 0, 0
	#define AI_MATKEY_GLTF_ALPHACUTOFF "$mat.gltf.alphaCutoff", 0, 0
	#define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS "$mat.gltf.pbrSpecularGlossiness", 0, 0
	#define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR "$mat.gltf.pbrMetallicRoughness.glossinessFactor", 0, 0

	#define _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE "$tex.file.texCoord"
	#define _AI_MATKEY_GLTF_MAPPINGNAME_BASE "$tex.mappingname"
	#define _AI_MATKEY_GLTF_MAPPINGID_BASE "$tex.mappingid"
	#define _AI_MATKEY_GLTF_MAPPINGFILTER_MAG_BASE "$tex.mappingfiltermag"
	#define _AI_MATKEY_GLTF_MAPPINGFILTER_MIN_BASE "$tex.mappingfiltermin"

	#define AI_MATKEY_GLTF_TEXTURE_TEXCOORD _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE, type, N
	#define AI_MATKEY_GLTF_MAPPINGNAME(type, N) _AI_MATKEY_GLTF_MAPPINGNAME_BASE, type, N
	#define AI_MATKEY_GLTF_MAPPINGID(type, N) _AI_MATKEY_GLTF_MAPPINGID_BASE, type, N
	#define AI_MATKEY_GLTF_MAPPINGFILTER_MAG(type, N) _AI_MATKEY_GLTF_MAPPINGFILTER_MAG_BASE, type, N
	#define AI_MATKEY_GLTF_MAPPINGFILTER_MIN(type, N) _AI_MATKEY_GLTF_MAPPINGFILTER_MIN_BASE, type, N

    #ifdef ASSIMP_API
        #include "./../include/assimp/Compiler/pushpack1.h"
    #endif

    //! For binary .glb files
    //! 12-byte header (+ the JSON + a "body" data section)
    struct GLB_Header
    {
        uint8_t magic[4];     //!< Magic number: "glTF"
        uint32_t version;     //!< Version number (always 2 as of the last update)
        uint32_t length;      //!< Total length of the Binary glTF, including header, scene, and body, in bytes
    } PACK_STRUCT;

    struct GLB_Chunk
    {
        uint32_t chunkLength;
        uint32_t chunkType;
    } PACK_STRUCT;

    #ifdef ASSIMP_API
        #include "./../include/assimp/Compiler/poppack1.h"
    #endif


    //! Values for the GLB_Chunk::chunkType field
    enum ChunkType
    {
        ChunkType_JSON = 0x4E4F534A,
        ChunkType_BIN  = 0x004E4942
    };

    //! Values for the mesh primitive modes
    enum PrimitiveMode
    {
        PrimitiveMode_POINTS = 0,
        PrimitiveMode_LINES = 1,
        PrimitiveMode_LINE_LOOP = 2,
        PrimitiveMode_LINE_STRIP = 3,
        PrimitiveMode_TRIANGLES = 4,
        PrimitiveMode_TRIANGLE_STRIP = 5,
        PrimitiveMode_TRIANGLE_FAN = 6
    };

    //! Values for the Accessor::componentType field
    enum ComponentType
    {
        ComponentType_BYTE = 5120,
        ComponentType_UNSIGNED_BYTE = 5121,
        ComponentType_SHORT = 5122,
        ComponentType_UNSIGNED_SHORT = 5123,
        ComponentType_UNSIGNED_INT = 5125,
        ComponentType_FLOAT = 5126
    };

    inline unsigned int ComponentTypeSize(ComponentType t)
    {
        switch (t) {
            case ComponentType_SHORT:
            case ComponentType_UNSIGNED_SHORT:
                return 2;

            case ComponentType_UNSIGNED_INT:
            case ComponentType_FLOAT:
                return 4;

            case ComponentType_BYTE:
            case ComponentType_UNSIGNED_BYTE:
                return 1;
            default:
                throw DeadlyImportError("GLTF: Unsupported Component Type " + to_string(t));
        }
    }

    //! Values for the BufferView::target field
    enum BufferViewTarget
    {
        BufferViewTarget_ARRAY_BUFFER = 34962,
        BufferViewTarget_ELEMENT_ARRAY_BUFFER = 34963
    };

    //! Values for the Sampler::magFilter field
    enum class SamplerMagFilter: unsigned int
    {
        UNSET = 0,
        SamplerMagFilter_Nearest = 9728,
        SamplerMagFilter_Linear = 9729
    };

    //! Values for the Sampler::minFilter field
    enum class SamplerMinFilter: unsigned int
    {
        UNSET = 0,
        SamplerMinFilter_Nearest = 9728,
        SamplerMinFilter_Linear = 9729,
        SamplerMinFilter_Nearest_Mipmap_Nearest = 9984,
        SamplerMinFilter_Linear_Mipmap_Nearest = 9985,
        SamplerMinFilter_Nearest_Mipmap_Linear = 9986,
        SamplerMinFilter_Linear_Mipmap_Linear = 9987
    };

    //! Values for the Sampler::wrapS and Sampler::wrapT field
    enum class SamplerWrap: unsigned int
    {
        UNSET = 0,
        Clamp_To_Edge = 33071,
        Mirrored_Repeat = 33648,
        Repeat = 10497
    };

    //! Values for the Texture::format and Texture::internalFormat fields
    enum TextureFormat
    {
        TextureFormat_ALPHA = 6406,
        TextureFormat_RGB = 6407,
        TextureFormat_RGBA = 6408,
        TextureFormat_LUMINANCE = 6409,
        TextureFormat_LUMINANCE_ALPHA = 6410
    };

    //! Values for the Texture::target field
    enum TextureTarget
    {
        TextureTarget_TEXTURE_2D = 3553
    };

    //! Values for the Texture::type field
    enum TextureType
    {
        TextureType_UNSIGNED_BYTE = 5121,
        TextureType_UNSIGNED_SHORT_5_6_5 = 33635,
        TextureType_UNSIGNED_SHORT_4_4_4_4 = 32819,
        TextureType_UNSIGNED_SHORT_5_5_5_1 = 32820
    };


    //! Values for the Accessor::type field (helper class)
    class AttribType
    {
    public:
        enum Value
            { SCALAR, VEC2, VEC3, VEC4, MAT2, MAT3, MAT4 };

    private:
        static const size_t NUM_VALUES = static_cast<size_t>(MAT4)+1;

        struct Info
            { const char* name; unsigned int numComponents; };

        template<int N> struct data
            { static const Info infos[NUM_VALUES]; };

    public:
        inline static Value FromString(const char* str)
        {
            for (size_t i = 0; i < NUM_VALUES; ++i) {
                if (strcmp(data<0>::infos[i].name, str) == 0) {
                    return static_cast<Value>(i);
                }
            }
            return SCALAR;
        }

        inline static const char* ToString(Value type)
        {
            return data<0>::infos[static_cast<size_t>(type)].name;
        }

        inline static unsigned int GetNumComponents(Value type)
        {
            return data<0>::infos[static_cast<size_t>(type)].numComponents;
        }
    };

    // must match the order of the AttribTypeTraits::Value enum!
    template<int N> const AttribType::Info
    AttribType::data<N>::infos[AttribType::NUM_VALUES] = {
        { "SCALAR", 1 }, { "VEC2", 2 }, { "VEC3", 3 }, { "VEC4", 4 }, { "MAT2", 4 }, { "MAT3", 9 }, { "MAT4", 16 }
    };



    //! A reference to one top-level object, which is valid
    //! until the Asset instance is destroyed
    template<class T>
    class Ref
    {
        std::vector<T*>* vector;
        unsigned int index;

    public:
        Ref() : vector(0), index(0) {}
        Ref(std::vector<T*>& vec, unsigned int idx) : vector(&vec), index(idx) {}

        inline unsigned int GetIndex() const
            { return index; }

        operator bool() const
            { return vector != 0; }

        T* operator->()
            { return (*vector)[index]; }

        T& operator*()
            { return *((*vector)[index]); }
    };

    //! Helper struct to represent values that might not be present
    template<class T>
    struct Nullable
    {
        T value;
        bool isPresent;

        Nullable() : isPresent(false) {}
        Nullable(T& val) : value(val), isPresent(true) {}
    };


    //! Base classe for all glTF top-level objects
    struct Object
    {
        int index;        //!< The index of this object within its property container
        int oIndex;       //!< The original index of this object defined in the JSON
        std::string id;   //!< The globally unique ID used to reference this object
        std::string name; //!< The user-defined name of this object

        //! Objects marked as special are not exported (used to emulate the binary body buffer)
        virtual bool IsSpecial() const
            { return false; }

        virtual ~Object() {}

        //! Maps special IDs to another ID, where needed. Subclasses may override it (statically)
        static const char* TranslateId(Asset& /*r*/, const char* id)
            { return id; }
    };

    //
    // Classes for each glTF top-level object type
    //

    //! A typed view into a BufferView. A BufferView contains raw binary data.
    //! An accessor provides a typed view into a BufferView or a subset of a BufferView
    //! similar to how WebGL's vertexAttribPointer() defines an attribute in a buffer.
    struct Accessor : public Object
    {
        Ref<BufferView> bufferView;  //!< The ID of the bufferView. (required)
        unsigned int byteOffset;     //!< The offset relative to the start of the bufferView in bytes. (required)
        ComponentType componentType; //!< The datatype of components in the attribute. (required)
        unsigned int count;          //!< The number of attributes referenced by this accessor. (required)
        AttribType::Value type;      //!< Specifies if the attribute is a scalar, vector, or matrix. (required)
        std::vector<float> max;      //!< Maximum value of each component in this attribute.
        std::vector<float> min;      //!< Minimum value of each component in this attribute.

        unsigned int GetNumComponents();
        unsigned int GetBytesPerComponent();
        unsigned int GetElementSize();

        inline uint8_t* GetPointer();

        template<class T>
        bool ExtractData(T*& outData);

        void WriteData(size_t count, const void* src_buffer, size_t src_stride);

        //! Helper class to iterate the data
        class Indexer
        {
            friend struct Accessor;

            Accessor& accessor;
            uint8_t* data;
            size_t elemSize, stride;

            Indexer(Accessor& acc);

        public:

            //! Accesses the i-th value as defined by the accessor
            template<class T>
            T GetValue(int i);

            //! Accesses the i-th value as defined by the accessor
            inline unsigned int GetUInt(int i)
            {
                return GetValue<unsigned int>(i);
            }

            inline bool IsValid() const
            {
                return data != 0;
            }
        };

        inline Indexer GetIndexer()
        {
            return Indexer(*this);
        }

        Accessor() {}
        void Read(Value& obj, Asset& r);
    };

    //! A buffer points to binary geometry, animation, or skins.
    struct Buffer : public Object
	{
		/********************* Types *********************/
	public:

		enum Type
		{
			Type_arraybuffer,
			Type_text
		};

		/// \struct SEncodedRegion
		/// Descriptor of encoded region in "bufferView".
		struct SEncodedRegion
		{
			const size_t Offset;///< Offset from begin of "bufferView" to encoded region, in bytes.
			const size_t EncodedData_Length;///< Size of encoded region, in bytes.
			uint8_t* const DecodedData;///< Cached encoded data.
			const size_t DecodedData_Length;///< Size of decoded region, in bytes.
			const std::string ID;///< ID of the region.

			/// \fn SEncodedRegion(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string pID)
			/// Constructor.
			/// \param [in] pOffset - offset from begin of "bufferView" to encoded region, in bytes.
			/// \param [in] pEncodedData_Length - size of encoded region, in bytes.
			/// \param [in] pDecodedData - pointer to decoded data array.
			/// \param [in] pDecodedData_Length - size of encoded region, in bytes.
			/// \param [in] pID - ID of the region.
			SEncodedRegion(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string pID)
				: Offset(pOffset), EncodedData_Length(pEncodedData_Length), DecodedData(pDecodedData), DecodedData_Length(pDecodedData_Length), ID(pID)
			{}

			/// \fn ~SEncodedRegion()
			/// Destructor.
			~SEncodedRegion() { delete[] DecodedData; }
		};

		/******************* Variables *******************/

		//std::string uri; //!< The uri of the buffer. Can be a filepath, a data uri, etc. (required)
		size_t byteLength; //!< The length of the buffer in bytes. (default: 0)
		//std::string type; //!< XMLHttpRequest responseType (default: "arraybuffer")

		Type type;

		/// \var EncodedRegion_Current
		/// Pointer to currently active encoded region.
		/// Why not decoding all regions at once and not to set one buffer with decoded data?
		/// Yes, why not? Even "accessor" point to decoded data. I mean that fields "byteOffset", "byteStride" and "count" has values which describes decoded
		/// data array. But only in range of mesh while is active parameters from "compressedData". For another mesh accessors point to decoded data too. But
		/// offset is counted for another regions is encoded.
		/// Example. You have two meshes. For every of it you have 4 bytes of data. That data compressed to 2 bytes. So, you have buffer with encoded data:
		/// M1_E0, M1_E1, M2_E0, M2_E1.
		/// After decoding you'll get:
		/// M1_D0, M1_D1, M1_D2, M1_D3, M2_D0, M2_D1, M2_D2, M2_D3.
		/// "accessors" must to use values that point to decoded data - obviously. So, you'll expect "accessors" like
		/// "accessor_0" : { byteOffset: 0, byteLength: 4}, "accessor_1" : { byteOffset: 4, byteLength: 4}
		/// but in real life you'll get:
		/// "accessor_0" : { byteOffset: 0, byteLength: 4}, "accessor_1" : { byteOffset: 2, byteLength: 4}
		/// Yes, accessor of next mesh has offset and length which mean: current mesh data is decoded, all other data is encoded.
		/// And when before you start to read data of current mesh (with encoded data ofcourse) you must decode region of "bufferView", after read finished
		/// delete encoding mark. And after that you can repeat process: decode data of mesh, read, delete decoded data.
		///
		/// Remark. Encoding all data at once is good in world with computers which do not has RAM limitation. So, you must use step by step encoding in
		/// exporter and importer. And, thanks to such way, there is no need to load whole file into memory.
		SEncodedRegion* EncodedRegion_Current;

	private:

		shared_ptr<uint8_t> mData; //!< Pointer to the data
		bool mIsSpecial; //!< Set to true for special cases (e.g. the body buffer)

		/// \var EncodedRegion_List
		/// List of encoded regions.
		std::list<SEncodedRegion*> EncodedRegion_List;

		/******************* Functions *******************/

	public:

		Buffer();
		~Buffer();

		void Read(Value& obj, Asset& r);

        bool LoadFromStream(IOStream& stream, size_t length = 0, size_t baseOffset = 0);

		/// \fn void EncodedRegion_Mark(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string& pID)
		/// Mark region of "bufferView" as encoded. When data is request from such region then "bufferView" use decoded data.
		/// \param [in] pOffset - offset from begin of "bufferView" to encoded region, in bytes.
		/// \param [in] pEncodedData_Length - size of encoded region, in bytes.
		/// \param [in] pDecodedData - pointer to decoded data array.
		/// \param [in] pDecodedData_Length - size of encoded region, in bytes.
		/// \param [in] pID - ID of the region.
		void EncodedRegion_Mark(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string& pID);

		/// \fn void EncodedRegion_SetCurrent(const std::string& pID)
		/// Select current encoded region by ID. \sa EncodedRegion_Current.
		/// \param [in] pID - ID of the region.
		void EncodedRegion_SetCurrent(const std::string& pID);

		/// \fn bool ReplaceData(const size_t pBufferData_Offset, const size_t pBufferData_Count, const uint8_t* pReplace_Data, const size_t pReplace_Count)
		/// Replace part of buffer data. Pay attention that function work with original array of data (\ref mData) not with encoded regions.
		/// \param [in] pBufferData_Offset - index of first element in buffer from which new data will be placed.
		/// \param [in] pBufferData_Count - count of bytes in buffer which will be replaced.
		/// \param [in] pReplace_Data - pointer to array with new data for buffer.
		/// \param [in] pReplace_Count - count of bytes in new data.
		/// \return true - if successfully replaced, false if input arguments is out of range.
		bool ReplaceData(const size_t pBufferData_Offset, const size_t pBufferData_Count, const uint8_t* pReplace_Data, const size_t pReplace_Count);

        size_t AppendData(uint8_t* data, size_t length);
        void Grow(size_t amount);

        uint8_t* GetPointer()
            { return mData.get(); }

        void MarkAsSpecial()
            { mIsSpecial = true; }

        bool IsSpecial() const
            { return mIsSpecial; }

        std::string GetURI()
            { return std::string(this->id) + ".bin"; }

        static const char* TranslateId(Asset& r, const char* id);
    };

    //! A view into a buffer generally representing a subset of the buffer.
    struct BufferView : public Object
    {
        Ref<Buffer> buffer; //! The ID of the buffer. (required)
        size_t byteOffset; //! The offset into the buffer in bytes. (required)
        size_t byteLength; //! The length of the bufferView in bytes. (default: 0)
        unsigned int byteStride; //!< The stride, in bytes, between attributes referenced by this accessor. (default: 0)

        BufferViewTarget target; //! The target that the WebGL buffer should be bound to.

        void Read(Value& obj, Asset& r);
    };

    struct Camera : public Object
    {
        enum Type
        {
            Perspective,
            Orthographic
        };

        Type type;

        union
        {
            struct {
                float aspectRatio; //!<The floating - point aspect ratio of the field of view. (0 = undefined = use the canvas one)
                float yfov;  //!<The floating - point vertical field of view in radians. (required)
                float zfar;  //!<The floating - point distance to the far clipping plane. (required)
                float znear; //!< The floating - point distance to the near clipping plane. (required)
            } perspective;

            struct {
                float xmag;  //! The floating-point horizontal magnification of the view. (required)
                float ymag;  //! The floating-point vertical magnification of the view. (required)
                float zfar;  //! The floating-point distance to the far clipping plane. (required)
                float znear; //! The floating-point distance to the near clipping plane. (required)
            } ortographic;
        } cameraProperties;

        Camera() {}
        void Read(Value& obj, Asset& r);
    };


    //! Image data used to create a texture.
    struct Image : public Object
    {
        std::string uri; //! The uri of the image, that can be a file path, a data URI, etc.. (required)

        Ref<BufferView> bufferView;

        std::string mimeType;

        int width, height;

    private:
        uint8_t* mData;
        size_t mDataLength;

    public:

        Image();
        void Read(Value& obj, Asset& r);

        inline bool HasData() const
            { return mDataLength > 0; }

        inline size_t GetDataLength() const
            { return mDataLength; }

        inline const uint8_t* GetData() const
            { return mData; }

        inline uint8_t* StealData();

        inline void SetData(uint8_t* data, size_t length, Asset& r);
	};

	const vec4 defaultBaseColor = {1, 1, 1, 1};
	const vec3 defaultEmissiveFactor = {0, 0, 0};
	const vec4 defaultDiffuseFactor = {1, 1, 1, 1};
	const vec3 defaultSpecularFactor = {1, 1, 1};

    struct TextureInfo
    {
        Ref<Texture> texture;
        unsigned int index;
        unsigned int texCoord = 0;
    };

    struct NormalTextureInfo : TextureInfo
    {
        float scale = 1;
    };

    struct OcclusionTextureInfo : TextureInfo
    {
        float strength = 1;
    };

    struct PbrMetallicRoughness
    {
        vec4 baseColorFactor;
        TextureInfo baseColorTexture;
        TextureInfo metallicRoughnessTexture;
        float metallicFactor;
        float roughnessFactor;
    };

    struct PbrSpecularGlossiness
    {
        vec4 diffuseFactor;
        vec3 specularFactor;
        float glossinessFactor;
        TextureInfo diffuseTexture;
		TextureInfo specularGlossinessTexture;

		PbrSpecularGlossiness() { SetDefaults(); }
		void SetDefaults();
    };

    //! The material appearance of a primitive.
    struct Material : public Object
    {
        //PBR metallic roughness properties
        PbrMetallicRoughness pbrMetallicRoughness;

        //other basic material properties
        NormalTextureInfo normalTexture;
        OcclusionTextureInfo occlusionTexture;
        TextureInfo emissiveTexture;
        vec3 emissiveFactor;
        std::string alphaMode;
        float alphaCutoff;
        bool doubleSided;

        //extension: KHR_materials_pbrSpecularGlossiness
        Nullable<PbrSpecularGlossiness> pbrSpecularGlossiness;

        Material() { SetDefaults(); }
        void Read(Value& obj, Asset& r);
        void SetDefaults();
    };

    //! A set of primitives to be rendered. A node can contain one or more meshes. A node's transform places the mesh in the scene.
    struct Mesh : public Object
    {
        typedef std::vector< Ref<Accessor> > AccessorList;

        struct Primitive
        {
            PrimitiveMode mode;

            struct Attributes {
                AccessorList position, normal, tangent, texcoord, color, joint, jointmatrix, weight;
            } attributes;

            Ref<Accessor> indices;

            Ref<Material> material;
        };

        std::vector<Primitive> primitives;

        Mesh() {}

		/// \fn void Read(Value& pJSON_Object, Asset& pAsset_Root)
		/// Get mesh data from JSON-object and place them to root asset.
		/// \param [in] pJSON_Object - reference to pJSON-object from which data are read.
		/// \param [out] pAsset_Root - reference to root assed where data will be stored.
		void Read(Value& pJSON_Object, Asset& pAsset_Root);
    };

    struct Node : public Object
    {
        std::vector< Ref<Node> > children;
        std::vector< Ref<Mesh> > meshes;

        Nullable<mat4> matrix;
        Nullable<vec3> translation;
        Nullable<vec4> rotation;
        Nullable<vec3> scale;

        Ref<Camera> camera;

        std::vector< Ref<Node> > skeletons;       //!< The ID of skeleton nodes. Each of which is the root of a node hierarchy.
        Ref<Skin> skin;                           //!< The ID of the skin referenced by this node.
        std::string jointName;                    //!< Name used when this node is a joint in a skin.

        Ref<Node> parent;                         //!< This is not part of the glTF specification. Used as a helper.

        Node() {}
        void Read(Value& obj, Asset& r);
    };

    struct Program : public Object
    {
        Program() {}
        void Read(Value& obj, Asset& r);
    };


    struct Sampler : public Object
    {
        SamplerMagFilter magFilter; //!< The texture magnification filter.
        SamplerMinFilter minFilter; //!< The texture minification filter.
        SamplerWrap wrapS;          //!< The texture wrapping in the S direction.
        SamplerWrap wrapT;          //!< The texture wrapping in the T direction.

        Sampler() { SetDefaults(); }
        void Read(Value& obj, Asset& r);
        void SetDefaults();
    };

    struct Scene : public Object
    {
        std::vector< Ref<Node> > nodes;

        Scene() {}
        void Read(Value& obj, Asset& r);
    };

    struct Shader : public Object
    {
        Shader() {}
        void Read(Value& obj, Asset& r);
    };

    struct Skin : public Object
    {
        Nullable<mat4> bindShapeMatrix;       //!< Floating-point 4x4 transformation matrix stored in column-major order.
        Ref<Accessor> inverseBindMatrices;    //!< The ID of the accessor containing the floating-point 4x4 inverse-bind matrices.
        std::vector<Ref<Node>> jointNames;    //!< Joint names of the joints (nodes with a jointName property) in this skin.
        std::string name;                     //!< The user-defined name of this object.

        Skin() {}
        void Read(Value& obj, Asset& r);
    };

    //! A texture and its sampler.
    struct Texture : public Object
    {
        Ref<Sampler> sampler; //!< The ID of the sampler used by this texture. (required)
        Ref<Image> source;    //!< The ID of the image used by this texture. (required)

        //TextureFormat format; //!< The texture's format. (default: TextureFormat_RGBA)
        //TextureFormat internalFormat; //!< The texture's internal format. (default: TextureFormat_RGBA)

        //TextureTarget target; //!< The target that the WebGL texture should be bound to. (default: TextureTarget_TEXTURE_2D)
        //TextureType type; //!< Texel datatype. (default: TextureType_UNSIGNED_BYTE)

        Texture() {}
        void Read(Value& obj, Asset& r);
    };

    struct Animation : public Object
    {
        struct AnimSampler {
            std::string id;               //!< The ID of this sampler.
            std::string input;            //!< The ID of a parameter in this animation to use as key-frame input.
            std::string interpolation;    //!< Type of interpolation algorithm to use between key-frames.
            std::string output;           //!< The ID of a parameter in this animation to use as key-frame output.
        };

        struct AnimChannel {
            int sampler;                 //!< The index of a sampler in the containing animation's samplers property.

            struct AnimTarget {
                Ref<Node> node;          //!< The node to animate.
                std::string path;        //!< The name of property of the node to animate ("translation", "rotation", or "scale").
            } target;
        };

        struct AnimParameters {
            Ref<Accessor> TIME;           //!< Accessor reference to a buffer storing a array of floating point scalar values.
            Ref<Accessor> rotation;       //!< Accessor reference to a buffer storing a array of four-component floating-point vectors.
            Ref<Accessor> scale;          //!< Accessor reference to a buffer storing a array of three-component floating-point vectors.
            Ref<Accessor> translation;    //!< Accessor reference to a buffer storing a array of three-component floating-point vectors.
        };

        // AnimChannel Channels[3];            //!< Connect the output values of the key-frame animation to a specific node in the hierarchy.
        // AnimParameters Parameters;          //!< The samplers that interpolate between the key-frames.
        // AnimSampler Samplers[3];            //!< The parameterized inputs representing the key-frame data.

        std::vector<AnimChannel> Channels;            //!< Connect the output values of the key-frame animation to a specific node in the hierarchy.
        AnimParameters Parameters;                    //!< The samplers that interpolate between the key-frames.
        std::vector<AnimSampler> Samplers;         //!< The parameterized inputs representing the key-frame data.

        Animation() {}
        void Read(Value& obj, Asset& r);

        //! Get accessor given an animation parameter name.
        Ref<Accessor> GetAccessor(std::string name) {
            if (name == "TIME") {
                return Parameters.TIME;
            } else if (name == "rotation") {
                return Parameters.rotation;
            } else if (name == "scale") {
                return Parameters.scale;
            } else if (name == "translation") {
                return Parameters.translation;
            }
            return Ref<Accessor>();
        }
    };


    //! Base class for LazyDict that acts as an interface
    class LazyDictBase
    {
    public:
        virtual ~LazyDictBase() {}

        virtual void AttachToDocument(Document& doc) = 0;
        virtual void DetachFromDocument() = 0;

        virtual void WriteObjects(AssetWriter& writer) = 0;
    };


    template<class T>
    class LazyDict;

    //! (Implemented in glTFAssetWriter.h)
    template<class T>
    void WriteLazyDict(LazyDict<T>& d, AssetWriter& w);


    //! Manages lazy loading of the glTF top-level objects, and keeps a reference to them by ID
    //! It is the owner the loaded objects, so when it is destroyed it also deletes them
    template<class T>
    class LazyDict : public LazyDictBase
    {
        friend class Asset;
        friend class AssetWriter;

        typedef typename std::gltf_unordered_map< unsigned int, unsigned int > Dict;
        typedef typename std::gltf_unordered_map< std::string, unsigned int > IdDict;

        std::vector<T*>     mObjs;         //! The read objects
        Dict                mObjsByOIndex; //! The read objects accessible by original index
        IdDict              mObjsById;     //! The read objects accessible by id
        const char*         mDictId;       //! ID of the dictionary object
        const char*         mExtId;        //! ID of the extension defining the dictionary
        Value*              mDict;         //! JSON dictionary object
        Asset&              mAsset;        //! The asset instance

        void AttachToDocument(Document& doc);
        void DetachFromDocument();

        void WriteObjects(AssetWriter& writer)
            { WriteLazyDict<T>(*this, writer); }

        Ref<T> Add(T* obj);

    public:
        LazyDict(Asset& asset, const char* dictId, const char* extId = 0);
        ~LazyDict();

        Ref<T> Retrieve(unsigned int i);

        Ref<T> Get(unsigned int i);
        Ref<T> Get(const char* id);

        Ref<T> Create(const char* id);
        Ref<T> Create(const std::string& id)
            { return Create(id.c_str()); }

        unsigned int Remove(const char* id);

        inline unsigned int Size() const
            { return unsigned(mObjs.size()); }

        inline T& operator[](size_t i)
            { return *mObjs[i]; }

    };


    struct AssetMetadata
    {
        std::string copyright; //!< A copyright message suitable for display to credit the content creator.
        std::string generator; //!< Tool that generated this glTF model.Useful for debugging.

        struct {
            std::string api;     //!< Specifies the target rendering API (default: "WebGL")
            std::string version; //!< Specifies the target rendering API (default: "1.0.3")
        } profile; //!< Specifies the target rendering API and version, e.g., WebGL 1.0.3. (default: {})

        std::string version; //!< The glTF format version

        void Read(Document& doc);

        AssetMetadata() : version("") {}
    };

    //
    // glTF Asset class
    //

    //! Root object for a glTF asset
    class Asset
    {
        typedef std::gltf_unordered_map<std::string, int> IdMap;

        template<class T>
        friend class LazyDict;

        friend struct Buffer; // To access OpenFile

        friend class AssetWriter;

    private:
        IOSystem* mIOSystem;

        std::string mCurrentAssetDir;

        size_t mSceneLength;
        size_t mBodyOffset, mBodyLength;

        std::vector<LazyDictBase*> mDicts;

        IdMap mUsedIds;

        Ref<Buffer> mBodyBuffer;

        Asset(Asset&);
        Asset& operator=(const Asset&);

    public:

        //! Keeps info about the enabled extensions
        struct Extensions
        {
            bool KHR_materials_pbrSpecularGlossiness;

        } extensionsUsed;

        AssetMetadata asset;


        // Dictionaries for each type of object

        LazyDict<Accessor>    accessors;
        LazyDict<Animation>   animations;
        LazyDict<Buffer>      buffers;
        LazyDict<BufferView>  bufferViews;
        LazyDict<Camera>      cameras;
        LazyDict<Image>       images;
        LazyDict<Material>    materials;
        LazyDict<Mesh>        meshes;
        LazyDict<Node>        nodes;
        LazyDict<Sampler>     samplers;
        LazyDict<Scene>       scenes;
        LazyDict<Skin>        skins;
        LazyDict<Texture>     textures;

        Ref<Scene> scene;

    public:
        Asset(IOSystem* io = 0)
            : mIOSystem(io)
            , asset()
            , accessors     (*this, "accessors")
            , animations    (*this, "animations")
            , buffers       (*this, "buffers")
            , bufferViews   (*this, "bufferViews")
            , cameras       (*this, "cameras")
            , images        (*this, "images")
            , materials     (*this, "materials")
            , meshes        (*this, "meshes")
            , nodes         (*this, "nodes")
            , samplers      (*this, "samplers")
            , scenes        (*this, "scenes")
            , skins         (*this, "skins")
            , textures      (*this, "textures")
        {
            memset(&extensionsUsed, 0, sizeof(extensionsUsed));
        }

        //! Main function
        void Load(const std::string& file, bool isBinary = false);

        //! Enables binary encoding on the asset
        void SetAsBinary();

        //! Search for an available name, starting from the given strings
        std::string FindUniqueID(const std::string& str, const char* suffix);

        Ref<Buffer> GetBodyBuffer()
            { return mBodyBuffer; }

    private:
        void ReadBinaryHeader(IOStream& stream, std::vector<char>& sceneData);

        void ReadExtensionsUsed(Document& doc);

        IOStream* OpenFile(std::string path, const char* mode, bool absolute = false);
    };

}

// Include the implementation of the methods
#include "glTF2Asset.inl"

#endif // ASSIMP_BUILD_NO_GLTF_IMPORTER

#endif // GLTF2ASSET_H_INC
