/*
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  AssbinExporter.cpp
 *  ASSBIN exporter main code
 */
#include "assbin_chunks.h"
#include <assimp/version.h>
#include <assimp/IOStream.hpp>
#include <assimp/IOSystem.hpp>
#include <assimp/Exporter.hpp>
#include "ProcessHelper.h"
#include "Exceptional.h"

#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
#   include <zlib.h>
#else
#   include "../contrib/zlib/zlib.h"
#endif

#include <time.h>


#ifndef ASSIMP_BUILD_NO_EXPORT
#ifndef ASSIMP_BUILD_NO_ASSBIN_EXPORTER

using namespace Assimp;

namespace Assimp    {

template <typename T>
size_t Write(IOStream * stream, const T& v)
{
    return stream->Write( &v, sizeof(T), 1 );
}


// -----------------------------------------------------------------------------------
// Serialize an aiString
template <>
inline size_t Write<aiString>(IOStream * stream, const aiString& s)
{
    const size_t s2 = (uint32_t)s.length;
    stream->Write(&s,4,1);
    stream->Write(s.data,s2,1);
    return s2+4;
}

// -----------------------------------------------------------------------------------
// Serialize an unsigned int as uint32_t
template <>
inline size_t Write<unsigned int>(IOStream * stream, const unsigned int& w)
{
    const uint32_t t = (uint32_t)w;
    if (w > t) {
        // this shouldn't happen, integers in Assimp data structures never exceed 2^32
        throw new DeadlyExportError("loss of data due to 64 -> 32 bit integer conversion");
    }

    stream->Write(&t,4,1);
    return 4;
}

// -----------------------------------------------------------------------------------
// Serialize an unsigned int as uint16_t
template <>
inline size_t Write<uint16_t>(IOStream * stream, const uint16_t& w)
{
    static_assert(sizeof(uint16_t)==2, "sizeof(uint16_t)==2");
    stream->Write(&w,2,1);
    return 2;
}

// -----------------------------------------------------------------------------------
// Serialize a float
template <>
inline size_t Write<float>(IOStream * stream, const float& f)
{
    static_assert(sizeof(float)==4, "sizeof(float)==4");
    stream->Write(&f,4,1);
    return 4;
}

// -----------------------------------------------------------------------------------
// Serialize a double
template <>
inline size_t Write<double>(IOStream * stream, const double& f)
{
    static_assert(sizeof(double)==8, "sizeof(double)==8");
    stream->Write(&f,8,1);
    return 8;
}

// -----------------------------------------------------------------------------------
// Serialize a vec3
template <>
inline size_t Write<aiVector3D>(IOStream * stream, const aiVector3D& v)
{
    size_t t = Write<float>(stream,v.x);
    t += Write<float>(stream,v.y);
    t += Write<float>(stream,v.z);
    return t;
}

// -----------------------------------------------------------------------------------
// Serialize a color value
template <>
inline size_t Write<aiColor3D>(IOStream * stream, const aiColor3D& v)
{
    size_t t = Write<float>(stream,v.r);
    t += Write<float>(stream,v.g);
    t += Write<float>(stream,v.b);
    return t;
}

// -----------------------------------------------------------------------------------
// Serialize a color value
template <>
inline size_t Write<aiColor4D>(IOStream * stream, const aiColor4D& v)
{
    size_t t = Write<float>(stream,v.r);
    t += Write<float>(stream,v.g);
    t += Write<float>(stream,v.b);
    t += Write<float>(stream,v.a);
    return t;
}

// -----------------------------------------------------------------------------------
// Serialize a quaternion
template <>
inline size_t Write<aiQuaternion>(IOStream * stream, const aiQuaternion& v)
{
    size_t t = Write<float>(stream,v.w);
    t += Write<float>(stream,v.x);
    t += Write<float>(stream,v.y);
    t += Write<float>(stream,v.z);
    ai_assert(t == 16);
    return 16;
}


// -----------------------------------------------------------------------------------
// Serialize a vertex weight
template <>
inline size_t Write<aiVertexWeight>(IOStream * stream, const aiVertexWeight& v)
{
    size_t t = Write<unsigned int>(stream,v.mVertexId);
    return t+Write<float>(stream,v.mWeight);
}

// -----------------------------------------------------------------------------------
// Serialize a mat4x4
template <>
inline size_t Write<aiMatrix4x4>(IOStream * stream, const aiMatrix4x4& m)
{
    for (unsigned int i = 0; i < 4;++i) {
        for (unsigned int i2 = 0; i2 < 4;++i2) {
            Write<float>(stream,m[i][i2]);
        }
    }
    return 64;
}

// -----------------------------------------------------------------------------------
// Serialize an aiVectorKey
template <>
inline size_t Write<aiVectorKey>(IOStream * stream, const aiVectorKey& v)
{
    const size_t t = Write<double>(stream,v.mTime);
    return t + Write<aiVector3D>(stream,v.mValue);
}

// -----------------------------------------------------------------------------------
// Serialize an aiQuatKey
template <>
inline size_t Write<aiQuatKey>(IOStream * stream, const aiQuatKey& v)
{
    const size_t t = Write<double>(stream,v.mTime);
    return t + Write<aiQuaternion>(stream,v.mValue);
}

template <typename T>
inline size_t WriteBounds(IOStream * stream, const T* in, unsigned int size)
{
    T minc,maxc;
    ArrayBounds(in,size,minc,maxc);

    const size_t t = Write<T>(stream,minc);
    return t + Write<T>(stream,maxc);
}

// We use this to write out non-byte arrays so that we write using the specializations.
// This way we avoid writing out extra bytes that potentially come from struct alignment.
template <typename T>
inline size_t WriteArray(IOStream * stream, const T* in, unsigned int size)
{
    size_t n = 0;
    for (unsigned int i=0; i<size; i++) n += Write<T>(stream,in[i]);
    return n;
}

    // ----------------------------------------------------------------------------------
    /** @class  AssbinChunkWriter
     *  @brief  Chunk writer mechanism for the .assbin file structure
     *
     *  This is a standard in-memory IOStream (most of the code is based on BlobIOStream),
     *  the difference being that this takes another IOStream as a "container" in the
     *  constructor, and when it is destroyed, it appends the magic number, the chunk size,
     *  and the chunk contents to the container stream. This allows relatively easy chunk
     *  chunk construction, even recursively.
     */
    class AssbinChunkWriter : public IOStream
    {
    private:

        uint8_t* buffer;
        uint32_t magic;
        IOStream * container;
        size_t cur_size, cursor, initial;

    private:
        // -------------------------------------------------------------------
        void Grow(size_t need = 0)
        {
            size_t new_size = std::max(initial, std::max( need, cur_size+(cur_size>>1) ));

            const uint8_t* const old = buffer;
            buffer = new uint8_t[new_size];

            if (old) {
                memcpy(buffer,old,cur_size);
                delete[] old;
            }

            cur_size = new_size;
        }

    public:

        AssbinChunkWriter( IOStream * container, uint32_t magic, size_t initial = 4096)
            : buffer(NULL), magic(magic), container(container), cur_size(0), cursor(0), initial(initial)
        {
        }

        virtual ~AssbinChunkWriter()
        {
            if (container) {
                container->Write( &magic, sizeof(uint32_t), 1 );
                container->Write( &cursor, sizeof(uint32_t), 1 );
                container->Write( buffer, 1, cursor );
            }
            if (buffer) delete[] buffer;
        }

        void * GetBufferPointer() { return buffer; }

        // -------------------------------------------------------------------
        virtual size_t Read(void* /*pvBuffer*/, size_t /*pSize*/, size_t /*pCount*/) { return 0; }
        virtual aiReturn Seek(size_t /*pOffset*/, aiOrigin /*pOrigin*/) { return aiReturn_FAILURE; }
        virtual size_t Tell() const { return cursor; }
        virtual void Flush() { }

        virtual size_t FileSize() const
        {
            return cursor;
        }

        // -------------------------------------------------------------------
        virtual size_t Write(const void* pvBuffer, size_t pSize, size_t pCount)
        {
            pSize *= pCount;
            if (cursor + pSize > cur_size) {
                Grow(cursor + pSize);
            }

            memcpy(buffer+cursor, pvBuffer, pSize);
            cursor += pSize;

            return pCount;
        }

    };

    // ----------------------------------------------------------------------------------
    /** @class  AssbinExport
     *  @brief  Assbin exporter class
     *
     *  This class performs the .assbin exporting, and is responsible for the file layout.
     */
    class AssbinExport
    {
    private:
        bool shortened;
        bool compressed;

    protected:

        // -----------------------------------------------------------------------------------
        void WriteBinaryNode( IOStream * container, const aiNode* node)
        {
            AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODE );

			unsigned int nb_metadata = (node->mMetaData != NULL ? node->mMetaData->mNumProperties : 0);

            Write<aiString>(&chunk,node->mName);
            Write<aiMatrix4x4>(&chunk,node->mTransformation);
            Write<unsigned int>(&chunk,node->mNumChildren);
            Write<unsigned int>(&chunk,node->mNumMeshes);
			Write<unsigned int>(&chunk,nb_metadata);

            for (unsigned int i = 0; i < node->mNumMeshes;++i) {
                Write<unsigned int>(&chunk,node->mMeshes[i]);
            }

            for (unsigned int i = 0; i < node->mNumChildren;++i) {
                WriteBinaryNode( &chunk, node->mChildren[i] );
            }

			for (unsigned int i = 0; i < nb_metadata; ++i) {
				const aiString& key = node->mMetaData->mKeys[i];
				aiMetadataType type = node->mMetaData->mValues[i].mType;
				void* value = node->mMetaData->mValues[i].mData;

				Write<aiString>(&chunk, key);
				Write<uint16_t>(&chunk, type);
				
				switch (type) {
                    case AI_BOOL:
                        Write<bool>(&chunk, *((bool*) value));
                        break;
                    case AI_INT32:
                        Write<int32_t>(&chunk, *((int32_t*) value));
                        break;
                    case AI_UINT64:
                        Write<uint64_t>(&chunk, *((uint64_t*) value));
                        break;
                    case AI_FLOAT:
                        Write<float>(&chunk, *((float*) value));
                        break;
                    case AI_DOUBLE:
                        Write<double>(&chunk, *((double*) value));
                        break;
                    case AI_AISTRING:
                        Write<aiString>(&chunk, *((aiString*) value));
                        break;
                    case AI_AIVECTOR3D:
                        Write<aiVector3D>(&chunk, *((aiVector3D*) value));
                        break;
#ifdef SWIG
                    case FORCE_32BIT:
#endif // SWIG
                    default:
                        break;
				}
			}
        }

        // -----------------------------------------------------------------------------------
        void WriteBinaryTexture(IOStream * container, const aiTexture* tex)
        {
            AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AITEXTURE );

            Write<unsigned int>(&chunk,tex->mWidth);
            Write<unsigned int>(&chunk,tex->mHeight);
            chunk.Write( tex->achFormatHint, sizeof(char), 4 );

            if(!shortened) {
                if (!tex->mHeight) {
                    chunk.Write(tex->pcData,1,tex->mWidth);
                }
                else {
                    chunk.Write(tex->pcData,1,tex->mWidth*tex->mHeight*4);
                }
            }

        }

        // -----------------------------------------------------------------------------------
        void WriteBinaryBone(IOStream * container, const aiBone* b)
        {
            AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIBONE );

            Write<aiString>(&chunk,b->mName);
            Write<unsigned int>(&chunk,b->mNumWeights);
            Write<aiMatrix4x4>(&chunk,b->mOffsetMatrix);

            // for the moment we write dumb min/max values for the bones, too.
            // maybe I'll add a better, hash-like solution later
            if (shortened) {
                WriteBounds(&chunk,b->mWeights,b->mNumWeights);
            } // else write as usual
            else WriteArray<aiVertexWeight>(&chunk,b->mWeights,b->mNumWeights);
        }

        // -----------------------------------------------------------------------------------
        void WriteBinaryMesh(IOStream * container, const aiMesh* mesh)
        {
            AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMESH );

            Write<unsigned int>(&chunk,mesh->mPrimitiveTypes);
            Write<unsigned int>(&chunk,mesh->mNumVertices);
            Write<unsigned int>(&chunk,mesh->mNumFaces);
            Write<unsigned int>(&chunk,mesh->mNumBones);
            Write<unsigned int>(&chunk,mesh->mMaterialIndex);

            // first of all, write bits for all existent vertex components
            unsigned int c = 0;
            if (mesh->mVertices) {
                c |= ASSBIN_MESH_HAS_POSITIONS;
            }
            if (mesh->mNormals) {
                c |= ASSBIN_MESH_HAS_NORMALS;
            }
            if (mesh->mTangents && mesh->mBitangents) {
                c |= ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS;
            }
            for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) {
                if (!mesh->mTextureCoords[n]) {
                    break;
                }
                c |= ASSBIN_MESH_HAS_TEXCOORD(n);
            }
            for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) {
                if (!mesh->mColors[n]) {
                    break;
                }
                c |= ASSBIN_MESH_HAS_COLOR(n);
            }
            Write<unsigned int>(&chunk,c);

            aiVector3D minVec, maxVec;
            if (mesh->mVertices) {
                if (shortened) {
                    WriteBounds(&chunk,mesh->mVertices,mesh->mNumVertices);
                } // else write as usual
                else WriteArray<aiVector3D>(&chunk,mesh->mVertices,mesh->mNumVertices);
            }
            if (mesh->mNormals) {
                if (shortened) {
                    WriteBounds(&chunk,mesh->mNormals,mesh->mNumVertices);
                } // else write as usual
                else WriteArray<aiVector3D>(&chunk,mesh->mNormals,mesh->mNumVertices);
            }
            if (mesh->mTangents && mesh->mBitangents) {
                if (shortened) {
                    WriteBounds(&chunk,mesh->mTangents,mesh->mNumVertices);
                    WriteBounds(&chunk,mesh->mBitangents,mesh->mNumVertices);
                } // else write as usual
                else {
                    WriteArray<aiVector3D>(&chunk,mesh->mTangents,mesh->mNumVertices);
                    WriteArray<aiVector3D>(&chunk,mesh->mBitangents,mesh->mNumVertices);
                }
            }
            for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) {
                if (!mesh->mColors[n])
                    break;

                if (shortened) {
                    WriteBounds(&chunk,mesh->mColors[n],mesh->mNumVertices);
                } // else write as usual
                else WriteArray<aiColor4D>(&chunk,mesh->mColors[n],mesh->mNumVertices);
            }
            for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) {
                if (!mesh->mTextureCoords[n])
                    break;

                // write number of UV components
                Write<unsigned int>(&chunk,mesh->mNumUVComponents[n]);

                if (shortened) {
                    WriteBounds(&chunk,mesh->mTextureCoords[n],mesh->mNumVertices);
                } // else write as usual
                else WriteArray<aiVector3D>(&chunk,mesh->mTextureCoords[n],mesh->mNumVertices);
            }

            // write faces. There are no floating-point calculations involved
            // in these, so we can write a simple hash over the face data
            // to the dump file. We generate a single 32 Bit hash for 512 faces
            // using Assimp's standard hashing function.
            if (shortened) {
                unsigned int processed = 0;
                for (unsigned int job;(job = std::min(mesh->mNumFaces-processed,512u));processed += job) {

                    uint32_t hash = 0;
                    for (unsigned int a = 0; a < job;++a) {

                        const aiFace& f = mesh->mFaces[processed+a];
                        uint32_t tmp = f.mNumIndices;
                        hash = SuperFastHash(reinterpret_cast<const char*>(&tmp),sizeof tmp,hash);
                        for (unsigned int i = 0; i < f.mNumIndices; ++i) {
                            static_assert(AI_MAX_VERTICES <= 0xffffffff, "AI_MAX_VERTICES <= 0xffffffff");
                            tmp = static_cast<uint32_t>( f.mIndices[i] );
                            hash = SuperFastHash(reinterpret_cast<const char*>(&tmp),sizeof tmp,hash);
                        }
                    }
                    Write<unsigned int>(&chunk,hash);
                }
            }
            else // else write as usual
            {
                // if there are less than 2^16 vertices, we can simply use 16 bit integers ...
                for (unsigned int i = 0; i < mesh->mNumFaces;++i) {
                    const aiFace& f = mesh->mFaces[i];

                    static_assert(AI_MAX_FACE_INDICES <= 0xffff, "AI_MAX_FACE_INDICES <= 0xffff");
                    Write<uint16_t>(&chunk,f.mNumIndices);

                    for (unsigned int a = 0; a < f.mNumIndices;++a) {
                        if (mesh->mNumVertices < (1u<<16)) {
                            Write<uint16_t>(&chunk,f.mIndices[a]);
                        }
                        else Write<unsigned int>(&chunk,f.mIndices[a]);
                    }
                }
            }

            // write bones
            if (mesh->mNumBones) {
                for (unsigned int a = 0; a < mesh->mNumBones;++a) {
                    const aiBone* b = mesh->mBones[a];
                    WriteBinaryBone(&chunk,b);
                }
            }
        }

        // -----------------------------------------------------------------------------------
        void WriteBinaryMaterialProperty(IOStream * container, const aiMaterialProperty* prop)
        {
            AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIALPROPERTY );

            Write<aiString>(&chunk,prop->mKey);
            Write<unsigned int>(&chunk,prop->mSemantic);
            Write<unsigned int>(&chunk,prop->mIndex);

            Write<unsigned int>(&chunk,prop->mDataLength);
            Write<unsigned int>(&chunk,(unsigned int)prop->mType);
            chunk.Write(prop->mData,1,prop->mDataLength);
        }

        // -----------------------------------------------------------------------------------
        void WriteBinaryMaterial(IOStream * container, const aiMaterial* mat)
        {
            AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIMATERIAL);

            Write<unsigned int>(&chunk,mat->mNumProperties);
            for (unsigned int i = 0; i < mat->mNumProperties;++i) {
                WriteBinaryMaterialProperty( &chunk, mat->mProperties[i]);
            }
        }

        // -----------------------------------------------------------------------------------
        void WriteBinaryNodeAnim(IOStream * container, const aiNodeAnim* nd)
        {
            AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AINODEANIM );

            Write<aiString>(&chunk,nd->mNodeName);
            Write<unsigned int>(&chunk,nd->mNumPositionKeys);
            Write<unsigned int>(&chunk,nd->mNumRotationKeys);
            Write<unsigned int>(&chunk,nd->mNumScalingKeys);
            Write<unsigned int>(&chunk,nd->mPreState);
            Write<unsigned int>(&chunk,nd->mPostState);

            if (nd->mPositionKeys) {
                if (shortened) {
                    WriteBounds(&chunk,nd->mPositionKeys,nd->mNumPositionKeys);

                } // else write as usual
                else WriteArray<aiVectorKey>(&chunk,nd->mPositionKeys,nd->mNumPositionKeys);
            }
            if (nd->mRotationKeys) {
                if (shortened) {
                    WriteBounds(&chunk,nd->mRotationKeys,nd->mNumRotationKeys);

                } // else write as usual
                else WriteArray<aiQuatKey>(&chunk,nd->mRotationKeys,nd->mNumRotationKeys);
            }
            if (nd->mScalingKeys) {
                if (shortened) {
                    WriteBounds(&chunk,nd->mScalingKeys,nd->mNumScalingKeys);

                } // else write as usual
                else WriteArray<aiVectorKey>(&chunk,nd->mScalingKeys,nd->mNumScalingKeys);
            }
        }


        // -----------------------------------------------------------------------------------
        void WriteBinaryAnim( IOStream * container, const aiAnimation* anim )
        {
            AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AIANIMATION );

            Write<aiString>(&chunk,anim->mName);
            Write<double>(&chunk,anim->mDuration);
            Write<double>(&chunk,anim->mTicksPerSecond);
            Write<unsigned int>(&chunk,anim->mNumChannels);

            for (unsigned int a = 0; a < anim->mNumChannels;++a) {
                const aiNodeAnim* nd = anim->mChannels[a];
                WriteBinaryNodeAnim(&chunk,nd);
            }
        }

        // -----------------------------------------------------------------------------------
        void WriteBinaryLight( IOStream * container, const aiLight* l )
        {
            AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AILIGHT );

            Write<aiString>(&chunk,l->mName);
            Write<unsigned int>(&chunk,l->mType);

            if (l->mType != aiLightSource_DIRECTIONAL) {
                Write<float>(&chunk,l->mAttenuationConstant);
                Write<float>(&chunk,l->mAttenuationLinear);
                Write<float>(&chunk,l->mAttenuationQuadratic);
            }

            Write<aiColor3D>(&chunk,l->mColorDiffuse);
            Write<aiColor3D>(&chunk,l->mColorSpecular);
            Write<aiColor3D>(&chunk,l->mColorAmbient);

            if (l->mType == aiLightSource_SPOT) {
                Write<float>(&chunk,l->mAngleInnerCone);
                Write<float>(&chunk,l->mAngleOuterCone);
            }

        }

        // -----------------------------------------------------------------------------------
        void WriteBinaryCamera( IOStream * container, const aiCamera* cam )
        {
            AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AICAMERA );

            Write<aiString>(&chunk,cam->mName);
            Write<aiVector3D>(&chunk,cam->mPosition);
            Write<aiVector3D>(&chunk,cam->mLookAt);
            Write<aiVector3D>(&chunk,cam->mUp);
            Write<float>(&chunk,cam->mHorizontalFOV);
            Write<float>(&chunk,cam->mClipPlaneNear);
            Write<float>(&chunk,cam->mClipPlaneFar);
            Write<float>(&chunk,cam->mAspect);
        }

        // -----------------------------------------------------------------------------------
        void WriteBinaryScene( IOStream * container, const aiScene* scene)
        {
            AssbinChunkWriter chunk( container, ASSBIN_CHUNK_AISCENE );

            // basic scene information
            Write<unsigned int>(&chunk,scene->mFlags);
            Write<unsigned int>(&chunk,scene->mNumMeshes);
            Write<unsigned int>(&chunk,scene->mNumMaterials);
            Write<unsigned int>(&chunk,scene->mNumAnimations);
            Write<unsigned int>(&chunk,scene->mNumTextures);
            Write<unsigned int>(&chunk,scene->mNumLights);
            Write<unsigned int>(&chunk,scene->mNumCameras);

            // write node graph
            WriteBinaryNode( &chunk, scene->mRootNode );

            // write all meshes
            for (unsigned int i = 0; i < scene->mNumMeshes;++i) {
                const aiMesh* mesh = scene->mMeshes[i];
                WriteBinaryMesh( &chunk,mesh);
            }

            // write materials
            for (unsigned int i = 0; i< scene->mNumMaterials; ++i) {
                const aiMaterial* mat = scene->mMaterials[i];
                WriteBinaryMaterial(&chunk,mat);
            }

            // write all animations
            for (unsigned int i = 0; i < scene->mNumAnimations;++i) {
                const aiAnimation* anim = scene->mAnimations[i];
                WriteBinaryAnim(&chunk,anim);
            }


            // write all textures
            for (unsigned int i = 0; i < scene->mNumTextures;++i) {
                const aiTexture* mesh = scene->mTextures[i];
                WriteBinaryTexture(&chunk,mesh);
            }

            // write lights
            for (unsigned int i = 0; i < scene->mNumLights;++i) {
                const aiLight* l = scene->mLights[i];
                WriteBinaryLight(&chunk,l);
            }

            // write cameras
            for (unsigned int i = 0; i < scene->mNumCameras;++i) {
                const aiCamera* cam = scene->mCameras[i];
                WriteBinaryCamera(&chunk,cam);
            }

        }

    public:
        AssbinExport()
            : shortened(false), compressed(false) // temporary settings until properties are introduced for exporters
        {
        }

        // -----------------------------------------------------------------------------------
        // Write a binary model dump
        void WriteBinaryDump(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
        {
            IOStream * out = pIOSystem->Open( pFile, "wb" );
            if (!out) return;

            time_t tt = time(NULL);
            tm* p     = gmtime(&tt);

            // header
            char s[64];
            memset( s, 0, 64 );
#if _MSC_VER >= 1400
            sprintf_s(s,"ASSIMP.binary-dump.%s",asctime(p));
#else
            ai_snprintf(s,64,"ASSIMP.binary-dump.%s",asctime(p));
#endif
            out->Write( s, 44, 1 );
            // == 44 bytes

            Write<unsigned int>( out, ASSBIN_VERSION_MAJOR );
            Write<unsigned int>( out, ASSBIN_VERSION_MINOR );
            Write<unsigned int>( out, aiGetVersionRevision() );
            Write<unsigned int>( out, aiGetCompileFlags() );
            Write<uint16_t>( out, shortened );
            Write<uint16_t>( out, compressed );
            // ==  20 bytes

            char buff[256];
            strncpy(buff,pFile,256);
            out->Write(buff,sizeof(char),256);

            char cmd[] = "\0";
            strncpy(buff,cmd,128);
            out->Write(buff,sizeof(char),128);

            // leave 64 bytes free for future extensions
            memset(buff,0xcd,64);
            out->Write(buff,sizeof(char),64);
            // == 435 bytes

            // ==== total header size: 512 bytes
            ai_assert( out->Tell() == ASSBIN_HEADER_LENGTH );

            // Up to here the data is uncompressed. For compressed files, the rest
            // is compressed using standard DEFLATE from zlib.
            if (compressed)
            {
                AssbinChunkWriter uncompressedStream( NULL, 0 );
                WriteBinaryScene( &uncompressedStream, pScene );

                uLongf uncompressedSize = static_cast<uLongf>(uncompressedStream.Tell());
                uLongf compressedSize = (uLongf)(uncompressedStream.Tell() * 1.001 + 12.);
                uint8_t* compressedBuffer = new uint8_t[ compressedSize ];

                compress2( compressedBuffer, &compressedSize, (const Bytef*)uncompressedStream.GetBufferPointer(), uncompressedSize, 9 );

                out->Write( &uncompressedSize, sizeof(uint32_t), 1 );
                out->Write( compressedBuffer, sizeof(char), compressedSize );

                delete[] compressedBuffer;
            }
            else
            {
                WriteBinaryScene( out, pScene );
            }

            pIOSystem->Close( out );
        }
    };

void ExportSceneAssbin(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
{
    AssbinExport exporter;
    exporter.WriteBinaryDump( pFile, pIOSystem, pScene );
}
} // end of namespace Assimp

#endif // ASSIMP_BUILD_NO_ASSBIN_EXPORTER
#endif // ASSIMP_BUILD_NO_EXPORT
