/*
---------------------------------------------------------------------------
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  B3DImporter.cpp
 *  @brief Implementation of the b3d importer class
 */


#ifndef ASSIMP_BUILD_NO_B3D_IMPORTER

// internal headers
#include "B3DImporter.h"
#include "TextureTransform.h"
#include "ConvertToLHProcess.h"
#include "StringUtils.h"
#include <memory>
#include <assimp/IOSystem.hpp>
#include <assimp/anim.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/importerdesc.h>

using namespace Assimp;
using namespace std;

static const aiImporterDesc desc = {
    "BlitzBasic 3D Importer",
    "",
    "",
    "http://www.blitzbasic.com/",
    aiImporterFlags_SupportBinaryFlavour,
    0,
    0,
    0,
    0,
    "b3d"
};

// (fixme, Aramis) quick workaround to get rid of all those signed to unsigned warnings
#ifdef _MSC_VER
#	pragma warning (disable: 4018)
#endif

//#define DEBUG_B3D

template<typename T>
void DeleteAllBarePointers(std::vector<T>& x)
{
    for(auto p : x)
    {
        delete p;
    }
}

B3DImporter::~B3DImporter()
{
    DeleteAllBarePointers(_animations);
}

// ------------------------------------------------------------------------------------------------
bool B3DImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const{

    size_t pos=pFile.find_last_of( '.' );
    if( pos==string::npos ) return false;

    string ext=pFile.substr( pos+1 );
    if( ext.size()!=3 ) return false;

    return (ext[0]=='b' || ext[0]=='B') && (ext[1]=='3') && (ext[2]=='d' || ext[2]=='D');
}

// ------------------------------------------------------------------------------------------------
// Loader meta information
const aiImporterDesc* B3DImporter::GetInfo () const
{
    return &desc;
}

#ifdef DEBUG_B3D
    extern "C"{ void _stdcall AllocConsole(); }
#endif
// ------------------------------------------------------------------------------------------------
void B3DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler){

#ifdef DEBUG_B3D
    AllocConsole();
    freopen( "conin$","r",stdin );
    freopen( "conout$","w",stdout );
    freopen( "conout$","w",stderr );
    cout<<"Hello world from the B3DImporter!"<<endl;
#endif

    std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));

    // Check whether we can read from the file
    if( file.get() == NULL)
        throw DeadlyImportError( "Failed to open B3D file " + pFile + ".");

    // check whether the .b3d file is large enough to contain
    // at least one chunk.
    size_t fileSize = file->FileSize();
    if( fileSize<8 ) throw DeadlyImportError( "B3D File is too small.");

    _pos=0;
    _buf.resize( fileSize );
    file->Read( &_buf[0],1,fileSize );
    _stack.clear();

    ReadBB3D( pScene );
}

// ------------------------------------------------------------------------------------------------
AI_WONT_RETURN void B3DImporter::Oops(){
    throw DeadlyImportError( "B3D Importer - INTERNAL ERROR" );
}

// ------------------------------------------------------------------------------------------------
AI_WONT_RETURN void B3DImporter::Fail( string str ){
#ifdef DEBUG_B3D
    cout<<"Error in B3D file data: "<<str<<endl;
#endif
    throw DeadlyImportError( "B3D Importer - error in B3D file data: "+str );
}

// ------------------------------------------------------------------------------------------------
int B3DImporter::ReadByte(){
    if( _pos<_buf.size() ) return _buf[_pos++];
    Fail( "EOF" );
    return 0;
}

// ------------------------------------------------------------------------------------------------
int B3DImporter::ReadInt(){
    if( _pos+4<=_buf.size() ){
        int n;
        memcpy(&n, &_buf[_pos], 4);
        _pos+=4;
        return n;
    }
    Fail( "EOF" );
    return 0;
}

// ------------------------------------------------------------------------------------------------
float B3DImporter::ReadFloat(){
    if( _pos+4<=_buf.size() ){
        float n;
        memcpy(&n, &_buf[_pos], 4);
        _pos+=4;
        return n;
    }
    Fail( "EOF" );
    return 0.0f;
}

// ------------------------------------------------------------------------------------------------
aiVector2D B3DImporter::ReadVec2(){
    float x=ReadFloat();
    float y=ReadFloat();
    return aiVector2D( x,y );
}

// ------------------------------------------------------------------------------------------------
aiVector3D B3DImporter::ReadVec3(){
    float x=ReadFloat();
    float y=ReadFloat();
    float z=ReadFloat();
    return aiVector3D( x,y,z );
}

// ------------------------------------------------------------------------------------------------
aiQuaternion B3DImporter::ReadQuat(){
    // (aramis_acg) Fix to adapt the loader to changed quat orientation
    float w=-ReadFloat();
    float x=ReadFloat();
    float y=ReadFloat();
    float z=ReadFloat();
    return aiQuaternion( w,x,y,z );
}

// ------------------------------------------------------------------------------------------------
string B3DImporter::ReadString(){
    string str;
    while( _pos<_buf.size() ){
        char c=(char)ReadByte();
        if( !c ) return str;
        str+=c;
    }
    Fail( "EOF" );
    return string();
}

// ------------------------------------------------------------------------------------------------
string B3DImporter::ReadChunk(){
    string tag;
    for( int i=0;i<4;++i ){
        tag+=char( ReadByte() );
    }
#ifdef DEBUG_B3D
//	cout<<"ReadChunk:"<<tag<<endl;
#endif
    unsigned sz=(unsigned)ReadInt();
    _stack.push_back( _pos+sz );
    return tag;
}

// ------------------------------------------------------------------------------------------------
void B3DImporter::ExitChunk(){
    _pos=_stack.back();
    _stack.pop_back();
}

// ------------------------------------------------------------------------------------------------
unsigned B3DImporter::ChunkSize(){
    return _stack.back()-_pos;
}
// ------------------------------------------------------------------------------------------------

template<class T>
T *B3DImporter::to_array( const vector<T> &v ){
    if( v.empty() ) {
        return 0;
    }
    T *p=new T[ v.size() ];
    for( size_t i=0;i<v.size();++i ){
        p[i]=v[i];
    }
    return p;
}

// ------------------------------------------------------------------------------------------------
void B3DImporter::ReadTEXS(){
    while( ChunkSize() ){
        string name=ReadString();
        /*int flags=*/ReadInt();
        /*int blend=*/ReadInt();
        /*aiVector2D pos=*/ReadVec2();
        /*aiVector2D scale=*/ReadVec2();
        /*float rot=*/ReadFloat();

        _textures.push_back( name );
    }
}

// ------------------------------------------------------------------------------------------------
void B3DImporter::ReadBRUS(){
    int n_texs=ReadInt();
    if( n_texs<0 || n_texs>8 ){
        Fail( "Bad texture count" );
    }
    while( ChunkSize() ){
        string name=ReadString();
        aiVector3D color=ReadVec3();
        float alpha=ReadFloat();
        float shiny=ReadFloat();
        /*int blend=**/ReadInt();
        int fx=ReadInt();

        aiMaterial *mat=new aiMaterial;
        _materials.push_back( mat );

        // Name
        aiString ainame( name );
        mat->AddProperty( &ainame,AI_MATKEY_NAME );

        // Diffuse color
        mat->AddProperty( &color,1,AI_MATKEY_COLOR_DIFFUSE );

        // Opacity
        mat->AddProperty( &alpha,1,AI_MATKEY_OPACITY );

        // Specular color
        aiColor3D speccolor( shiny,shiny,shiny );
        mat->AddProperty( &speccolor,1,AI_MATKEY_COLOR_SPECULAR );

        // Specular power
        float specpow=shiny*128;
        mat->AddProperty( &specpow,1,AI_MATKEY_SHININESS );

        // Double sided
        if( fx & 0x10 ){
            int i=1;
            mat->AddProperty( &i,1,AI_MATKEY_TWOSIDED );
        }

        //Textures
        for( int i=0;i<n_texs;++i ){
            int texid=ReadInt();
            if( texid<-1 || (texid>=0 && texid>=static_cast<int>(_textures.size())) ){
                Fail( "Bad texture id" );
            }
            if( i==0 && texid>=0 ){
                aiString texname( _textures[texid] );
                mat->AddProperty( &texname,AI_MATKEY_TEXTURE_DIFFUSE(0) );
            }
        }
    }
}

// ------------------------------------------------------------------------------------------------
void B3DImporter::ReadVRTS(){
    _vflags=ReadInt();
    _tcsets=ReadInt();
    _tcsize=ReadInt();
    if( _tcsets<0 || _tcsets>4 || _tcsize<0 || _tcsize>4 ){
        Fail( "Bad texcoord data" );
    }

    int sz=12+(_vflags&1?12:0)+(_vflags&2?16:0)+(_tcsets*_tcsize*4);
    int n_verts=ChunkSize()/sz;

    int v0=static_cast<int>(_vertices.size());
    _vertices.resize( v0+n_verts );

    for( int i=0;i<n_verts;++i ){
        Vertex &v=_vertices[v0+i];

        memset( v.bones,0,sizeof(v.bones) );
        memset( v.weights,0,sizeof(v.weights) );

        v.vertex=ReadVec3();

        if( _vflags & 1 ) v.normal=ReadVec3();

        if( _vflags & 2 ) ReadQuat();	//skip v 4bytes...

        for( int i=0;i<_tcsets;++i ){
            float t[4]={0,0,0,0};
            for( int j=0;j<_tcsize;++j ){
                t[j]=ReadFloat();
            }
            t[1]=1-t[1];
            if( !i ) v.texcoords=aiVector3D( t[0],t[1],t[2] );
        }
    }
}

// ------------------------------------------------------------------------------------------------
void B3DImporter::ReadTRIS( int v0 ){
    int matid=ReadInt();
    if( matid==-1 ){
        matid=0;
    }else if( matid<0 || matid>=(int)_materials.size() ){
#ifdef DEBUG_B3D
        cout<<"material id="<<matid<<endl;
#endif
        Fail( "Bad material id" );
    }

    aiMesh *mesh=new aiMesh;
    _meshes.push_back( mesh );

    mesh->mMaterialIndex=matid;
    mesh->mNumFaces=0;
    mesh->mPrimitiveTypes=aiPrimitiveType_TRIANGLE;

    int n_tris=ChunkSize()/12;
    aiFace *face=mesh->mFaces=new aiFace[n_tris];

    for( int i=0;i<n_tris;++i ){
        int i0=ReadInt()+v0;
        int i1=ReadInt()+v0;
        int i2=ReadInt()+v0;
        if( i0<0 || i0>=(int)_vertices.size() || i1<0 || i1>=(int)_vertices.size() || i2<0 || i2>=(int)_vertices.size() ){
#ifdef DEBUG_B3D
            cout<<"Bad triangle index: i0="<<i0<<", i1="<<i1<<", i2="<<i2<<endl;
#endif
            Fail( "Bad triangle index" );
            continue;
        }
        face->mNumIndices=3;
        face->mIndices=new unsigned[3];
        face->mIndices[0]=i0;
        face->mIndices[1]=i1;
        face->mIndices[2]=i2;
        ++mesh->mNumFaces;
        ++face;
    }
}

// ------------------------------------------------------------------------------------------------
void B3DImporter::ReadMESH(){
    /*int matid=*/ReadInt();

    int v0= static_cast<int>(_vertices.size());

    while( ChunkSize() ){
        string t=ReadChunk();
        if( t=="VRTS" ){
            ReadVRTS();
        }else if( t=="TRIS" ){
            ReadTRIS( v0 );
        }
        ExitChunk();
    }
}

// ------------------------------------------------------------------------------------------------
void B3DImporter::ReadBONE( int id ){
    while( ChunkSize() ){
        int vertex=ReadInt();
        float weight=ReadFloat();
        if( vertex<0 || vertex>=(int)_vertices.size() ){
            Fail( "Bad vertex index" );
        }

        Vertex &v=_vertices[vertex];
        int i;
        for( i=0;i<4;++i ){
            if( !v.weights[i] ){
                v.bones[i]=id;
                v.weights[i]=weight;
                break;
            }
        }
#ifdef DEBUG_B3D
        if( i==4 ){
            cout<<"Too many bone weights"<<endl;
        }
#endif
    }
}

// ------------------------------------------------------------------------------------------------
void B3DImporter::ReadKEYS( aiNodeAnim *nodeAnim ){
    vector<aiVectorKey> trans,scale;
    vector<aiQuatKey> rot;
    int flags=ReadInt();
    while( ChunkSize() ){
        int frame=ReadInt();
        if( flags & 1 ){
            trans.push_back( aiVectorKey( frame,ReadVec3() ) );
        }
        if( flags & 2 ){
            scale.push_back( aiVectorKey( frame,ReadVec3() ) );
        }
        if( flags & 4 ){
            rot.push_back( aiQuatKey( frame,ReadQuat() ) );
        }
    }

    if( flags & 1 ){
        nodeAnim->mNumPositionKeys=static_cast<unsigned int>(trans.size());
        nodeAnim->mPositionKeys=to_array( trans );
    }

    if( flags & 2 ){
        nodeAnim->mNumScalingKeys=static_cast<unsigned int>(scale.size());
        nodeAnim->mScalingKeys=to_array( scale );
    }

    if( flags & 4 ){
        nodeAnim->mNumRotationKeys=static_cast<unsigned int>(rot.size());
        nodeAnim->mRotationKeys=to_array( rot );
    }
}

// ------------------------------------------------------------------------------------------------
void B3DImporter::ReadANIM(){
    /*int flags=*/ReadInt();
    int frames=ReadInt();
    float fps=ReadFloat();

    aiAnimation *anim=new aiAnimation;
    _animations.push_back( anim );

    anim->mDuration=frames;
    anim->mTicksPerSecond=fps;
}

// ------------------------------------------------------------------------------------------------
aiNode *B3DImporter::ReadNODE( aiNode *parent ){

    string name=ReadString();
    aiVector3D t=ReadVec3();
    aiVector3D s=ReadVec3();
    aiQuaternion r=ReadQuat();

    aiMatrix4x4 trans,scale,rot;

    aiMatrix4x4::Translation( t,trans );
    aiMatrix4x4::Scaling( s,scale );
    rot=aiMatrix4x4( r.GetMatrix() );

    aiMatrix4x4 tform=trans * rot * scale;

    int nodeid=static_cast<int>(_nodes.size());

    aiNode *node=new aiNode( name );
    _nodes.push_back( node );

    node->mParent=parent;
    node->mTransformation=tform;

    aiNodeAnim *nodeAnim=0;
    vector<unsigned> meshes;
    vector<aiNode*> children;

    while( ChunkSize() ){
        string t=ReadChunk();
        if( t=="MESH" ){
            unsigned int n= static_cast<unsigned int>(_meshes.size());
            ReadMESH();
            for( unsigned int i=n;i<static_cast<unsigned int>(_meshes.size());++i ){
                meshes.push_back( i );
            }
        }else if( t=="BONE" ){
            ReadBONE( nodeid );
        }else if( t=="ANIM" ){
            ReadANIM();
        }else if( t=="KEYS" ){
            if( !nodeAnim ){
                nodeAnim=new aiNodeAnim;
                _nodeAnims.push_back( nodeAnim );
                nodeAnim->mNodeName=node->mName;
            }
            ReadKEYS( nodeAnim );
        }else if( t=="NODE" ){
            aiNode *child=ReadNODE( node );
            children.push_back( child );
        }
        ExitChunk();
    }

    node->mNumMeshes= static_cast<unsigned int>(meshes.size());
    node->mMeshes=to_array( meshes );

    node->mNumChildren=static_cast<unsigned int>(children.size());
    node->mChildren=to_array( children );

    return node;
}

// ------------------------------------------------------------------------------------------------
void B3DImporter::ReadBB3D( aiScene *scene ){

    _textures.clear();

    _materials.clear();

    _vertices.clear();

    _meshes.clear();

    DeleteAllBarePointers(_nodes);
    _nodes.clear();

    _nodeAnims.clear();

    DeleteAllBarePointers(_animations);
    _animations.clear();

    string t=ReadChunk();
    if( t=="BB3D" ){
        int version=ReadInt();

        if (!DefaultLogger::isNullLogger()) {
            char dmp[128];
            ai_snprintf(dmp, 128, "B3D file format version: %i",version);
            DefaultLogger::get()->info(dmp);
        }

        while( ChunkSize() ){
            string t=ReadChunk();
            if( t=="TEXS" ){
                ReadTEXS();
            }else if( t=="BRUS" ){
                ReadBRUS();
            }else if( t=="NODE" ){
                ReadNODE( 0 );
            }
            ExitChunk();
        }
    }
    ExitChunk();

    if( !_nodes.size() ) Fail( "No nodes" );

    if( !_meshes.size() ) Fail( "No meshes" );

    //Fix nodes/meshes/bones
    for(size_t i=0;i<_nodes.size();++i ){
        aiNode *node=_nodes[i];

        for( size_t j=0;j<node->mNumMeshes;++j ){
            aiMesh *mesh=_meshes[node->mMeshes[j]];

            int n_tris=mesh->mNumFaces;
            int n_verts=mesh->mNumVertices=n_tris * 3;

            aiVector3D *mv=mesh->mVertices=new aiVector3D[ n_verts ],*mn=0,*mc=0;
            if( _vflags & 1 ) mn=mesh->mNormals=new aiVector3D[ n_verts ];
            if( _tcsets ) mc=mesh->mTextureCoords[0]=new aiVector3D[ n_verts ];

            aiFace *face=mesh->mFaces;

            vector< vector<aiVertexWeight> > vweights( _nodes.size() );

            for( int i=0;i<n_verts;i+=3 ){
                for( int j=0;j<3;++j ){
                    Vertex &v=_vertices[face->mIndices[j]];

                    *mv++=v.vertex;
                    if( mn ) *mn++=v.normal;
                    if( mc ) *mc++=v.texcoords;

                    face->mIndices[j]=i+j;

                    for( int k=0;k<4;++k ){
                        if( !v.weights[k] ) break;

                        int bone=v.bones[k];
                        float weight=v.weights[k];

                        vweights[bone].push_back( aiVertexWeight(i+j,weight) );
                    }
                }
                ++face;
            }

            vector<aiBone*> bones;
            for(size_t i=0;i<vweights.size();++i ){
                vector<aiVertexWeight> &weights=vweights[i];
                if( !weights.size() ) continue;

                aiBone *bone=new aiBone;
                bones.push_back( bone );

                aiNode *bnode=_nodes[i];

                bone->mName=bnode->mName;
                bone->mNumWeights= static_cast<unsigned int>(weights.size());
                bone->mWeights=to_array( weights );

                aiMatrix4x4 mat=bnode->mTransformation;
                while( bnode->mParent ){
                    bnode=bnode->mParent;
                    mat=bnode->mTransformation * mat;
                }
                bone->mOffsetMatrix=mat.Inverse();
            }
            mesh->mNumBones= static_cast<unsigned int>(bones.size());
            mesh->mBones=to_array( bones );
        }
    }

    //nodes
    scene->mRootNode=_nodes[0];

    //material
    if( !_materials.size() ){
        _materials.push_back( new aiMaterial );
    }
    scene->mNumMaterials= static_cast<unsigned int>(_materials.size());
    scene->mMaterials=to_array( _materials );

    //meshes
    scene->mNumMeshes= static_cast<unsigned int>(_meshes.size());
    scene->mMeshes=to_array( _meshes );

    //animations
    if( _animations.size()==1 && _nodeAnims.size() ){

        aiAnimation *anim=_animations.back();
        anim->mNumChannels=static_cast<unsigned int>(_nodeAnims.size());
        anim->mChannels=to_array( _nodeAnims );

        scene->mNumAnimations=static_cast<unsigned int>(_animations.size());
        scene->mAnimations=to_array( _animations );
    }

    // convert to RH
    MakeLeftHandedProcess makeleft;
    makeleft.Execute( scene );

    FlipWindingOrderProcess flip;
    flip.Execute( scene );
}

#endif // !! ASSIMP_BUILD_NO_B3D_IMPORTER
