/*
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  COBLoader.cpp
 *  @brief Implementation of the TrueSpace COB/SCN importer class.
 */


#ifndef ASSIMP_BUILD_NO_COB_IMPORTER
#include "COBLoader.h"
#include "COBScene.h"

#include "StreamReader.h"
#include "ParsingUtils.h"
#include "fast_atof.h"

#include "LineSplitter.h"
#include "TinyFormatter.h"
#include <memory>
#include <assimp/IOSystem.hpp>
#include <assimp/DefaultLogger.hpp>
#include <assimp/scene.h>
#include <assimp/importerdesc.h>

using namespace Assimp;
using namespace Assimp::COB;
using namespace Assimp::Formatter;


static const float units[] = {
    1000.f,
    100.f,
    1.f,
    0.001f,
    1.f/0.0254f,
    1.f/0.3048f,
    1.f/0.9144f,
    1.f/1609.344f
};

static const aiImporterDesc desc = {
    "TrueSpace Object Importer",
    "",
    "",
    "little-endian files only",
    aiImporterFlags_SupportTextFlavour | aiImporterFlags_SupportBinaryFlavour,
    0,
    0,
    0,
    0,
    "cob scn"
};


// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
COBImporter::COBImporter()
{}

// ------------------------------------------------------------------------------------------------
// Destructor, private as well
COBImporter::~COBImporter()
{}

// ------------------------------------------------------------------------------------------------
// Returns whether the class can handle the format of the given file.
bool COBImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{
    const std::string& extension = GetExtension(pFile);
    if (extension == "cob" || extension == "scn") {
        return true;
    }

    else if ((!extension.length() || checkSig) && pIOHandler)   {
        const char* tokens[] = {"Caligary"};
        return SearchFileHeaderForToken(pIOHandler,pFile,tokens,1);
    }
    return false;
}

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

// ------------------------------------------------------------------------------------------------
// Setup configuration properties for the loader
void COBImporter::SetupProperties(const Importer* /*pImp*/)
{
    // nothing to be done for the moment
}

// ------------------------------------------------------------------------------------------------
/*static*/ AI_WONT_RETURN void COBImporter::ThrowException(const std::string& msg)
{
    throw DeadlyImportError("COB: "+msg);
}

// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void COBImporter::InternReadFile( const std::string& pFile,
    aiScene* pScene, IOSystem* pIOHandler)
{
    COB::Scene scene;
    std::unique_ptr<StreamReaderLE> stream(new StreamReaderLE( pIOHandler->Open(pFile,"rb")) );

    // check header
    char head[32];
    stream->CopyAndAdvance(head,32);
    if (strncmp(head,"Caligari ",9)) {
        ThrowException("Could not found magic id: `Caligari`");
    }

    DefaultLogger::get()->info("File format tag: "+std::string(head+9,6));
    if (head[16]!='L') {
        ThrowException("File is big-endian, which is not supported");
    }

    // load data into intermediate structures
    if (head[15]=='A') {
        ReadAsciiFile(scene, stream.get());
    }
    else {
        ReadBinaryFile(scene, stream.get());
    }
    if(scene.nodes.empty()) {
        ThrowException("No nodes loaded");
    }

    // sort faces by material indices
    for(std::shared_ptr< Node >& n : scene.nodes) {
        if (n->type == Node::TYPE_MESH) {
            Mesh& mesh = (Mesh&)(*n.get());
            for(Face& f : mesh.faces) {
                mesh.temp_map[f.material].push_back(&f);
            }
        }
    }

    // count meshes
    for(std::shared_ptr< Node >& n : scene.nodes) {
        if (n->type == Node::TYPE_MESH) {
            Mesh& mesh = (Mesh&)(*n.get());
            if (mesh.vertex_positions.size() && mesh.texture_coords.size()) {
                pScene->mNumMeshes += static_cast<unsigned int>(mesh.temp_map.size());
            }
        }
    }
    pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]();
    pScene->mMaterials = new aiMaterial*[pScene->mNumMeshes]();
    pScene->mNumMeshes = 0;

    // count lights and cameras
    for(std::shared_ptr< Node >& n : scene.nodes) {
        if (n->type == Node::TYPE_LIGHT) {
            ++pScene->mNumLights;
        }
        else if (n->type == Node::TYPE_CAMERA) {
            ++pScene->mNumCameras;
        }
    }

    if (pScene->mNumLights) {
        pScene->mLights  = new aiLight*[pScene->mNumLights]();
    }
    if (pScene->mNumCameras) {
        pScene->mCameras = new aiCamera*[pScene->mNumCameras]();
    }
    pScene->mNumLights = pScene->mNumCameras = 0;

    // resolve parents by their IDs and build the output graph
    std::unique_ptr<Node> root(new Group());
    for(size_t n = 0; n < scene.nodes.size(); ++n) {
        const Node& nn = *scene.nodes[n].get();
        if(nn.parent_id==0) {
            root->temp_children.push_back(&nn);
        }

        for(size_t m = n; m < scene.nodes.size(); ++m) {
            const Node& mm = *scene.nodes[m].get();
            if (mm.parent_id == nn.id) {
                nn.temp_children.push_back(&mm);
            }
        }
    }

    pScene->mRootNode = BuildNodes(*root.get(),scene,pScene);
}

// ------------------------------------------------------------------------------------------------
void ConvertTexture(std::shared_ptr< Texture > tex, aiMaterial* out, aiTextureType type)
{
    const aiString path( tex->path );
    out->AddProperty(&path,AI_MATKEY_TEXTURE(type,0));
    out->AddProperty(&tex->transform,1,AI_MATKEY_UVTRANSFORM(type,0));
}

// ------------------------------------------------------------------------------------------------
aiNode* COBImporter::BuildNodes(const Node& root,const Scene& scin,aiScene* fill)
{
    aiNode* nd = new aiNode();
    nd->mName.Set(root.name);
    nd->mTransformation = root.transform;

    // Note to everybody believing Voodoo is appropriate here:
    // I know polymorphism, run as fast as you can ;-)
    if (Node::TYPE_MESH == root.type) {
        const Mesh& ndmesh = (const Mesh&)(root);
        if (ndmesh.vertex_positions.size() && ndmesh.texture_coords.size()) {

            typedef std::pair<unsigned int,Mesh::FaceRefList> Entry;
            for(const Entry& reflist : ndmesh.temp_map) {
                {   // create mesh
                    size_t n = 0;
                    for(Face* f : reflist.second) {
                        n += f->indices.size();
                    }
                    if (!n) {
                        continue;
                    }
                    aiMesh* outmesh = fill->mMeshes[fill->mNumMeshes++] = new aiMesh();
                    ++nd->mNumMeshes;

                    outmesh->mVertices = new aiVector3D[n];
                    outmesh->mTextureCoords[0] = new aiVector3D[n];

                    outmesh->mFaces = new aiFace[reflist.second.size()]();
                    for(Face* f : reflist.second) {
                        if (f->indices.empty()) {
                            continue;
                        }

                        aiFace& fout = outmesh->mFaces[outmesh->mNumFaces++];
                        fout.mIndices = new unsigned int[f->indices.size()];

                        for(VertexIndex& v : f->indices) {
                            if (v.pos_idx >= ndmesh.vertex_positions.size()) {
                                ThrowException("Position index out of range");
                            }
                            if (v.uv_idx >= ndmesh.texture_coords.size()) {
                                ThrowException("UV index out of range");
                            }
                            outmesh->mVertices[outmesh->mNumVertices] = ndmesh.vertex_positions[ v.pos_idx ];
                            outmesh->mTextureCoords[0][outmesh->mNumVertices] = aiVector3D(
                                ndmesh.texture_coords[ v.uv_idx ].x,
                                ndmesh.texture_coords[ v.uv_idx ].y,
                                0.f
                            );

                            fout.mIndices[fout.mNumIndices++] = outmesh->mNumVertices++;
                        }
                    }
                    outmesh->mMaterialIndex = fill->mNumMaterials;
                }{  // create material
                    const Material* min = NULL;
                    for(const Material& m : scin.materials) {
                        if (m.parent_id == ndmesh.id && m.matnum == reflist.first) {
                            min = &m;
                            break;
                        }
                    }
                    std::unique_ptr<const Material> defmat;
                    if(!min) {
                        DefaultLogger::get()->debug(format()<<"Could not resolve material index "
                            <<reflist.first<<" - creating default material for this slot");

                        defmat.reset(min=new Material());
                    }

                    aiMaterial* mat = new aiMaterial();
                    fill->mMaterials[fill->mNumMaterials++] = mat;

                    const aiString s(format("#mat_")<<fill->mNumMeshes<<"_"<<min->matnum);
                    mat->AddProperty(&s,AI_MATKEY_NAME);

                    if(int tmp = ndmesh.draw_flags & Mesh::WIRED ? 1 : 0) {
                        mat->AddProperty(&tmp,1,AI_MATKEY_ENABLE_WIREFRAME);
                    }

                    {   int shader;
                        switch(min->shader)
                        {
                        case Material::FLAT:
                            shader = aiShadingMode_Gouraud;
                            break;

                        case Material::PHONG:
                            shader = aiShadingMode_Phong;
                            break;

                        case Material::METAL:
                            shader = aiShadingMode_CookTorrance;
                            break;

                        default:
                            ai_assert(false); // shouldn't be here
                        }
                        mat->AddProperty(&shader,1,AI_MATKEY_SHADING_MODEL);
                        if(shader != aiShadingMode_Gouraud) {
                            mat->AddProperty(&min->exp,1,AI_MATKEY_SHININESS);
                        }
                    }

                    mat->AddProperty(&min->ior,1,AI_MATKEY_REFRACTI);
                    mat->AddProperty(&min->rgb,1,AI_MATKEY_COLOR_DIFFUSE);

                    aiColor3D c = aiColor3D(min->rgb)*min->ks;
                    mat->AddProperty(&c,1,AI_MATKEY_COLOR_SPECULAR);

                    c = aiColor3D(min->rgb)*min->ka;
                    mat->AddProperty(&c,1,AI_MATKEY_COLOR_AMBIENT);

                    // convert textures if some exist.
                    if(min->tex_color) {
                        ConvertTexture(min->tex_color,mat,aiTextureType_DIFFUSE);
                    }
                    if(min->tex_env) {
                        ConvertTexture(min->tex_env  ,mat,aiTextureType_UNKNOWN);
                    }
                    if(min->tex_bump) {
                        ConvertTexture(min->tex_bump ,mat,aiTextureType_HEIGHT);
                    }
                }
            }
        }
    }
    else if (Node::TYPE_LIGHT == root.type) {
        const Light& ndlight = (const Light&)(root);
        aiLight* outlight = fill->mLights[fill->mNumLights++] = new aiLight();

        outlight->mName.Set(ndlight.name);
        outlight->mColorDiffuse = outlight->mColorAmbient = outlight->mColorSpecular = ndlight.color;

        outlight->mAngleOuterCone = AI_DEG_TO_RAD(ndlight.angle);
        outlight->mAngleInnerCone = AI_DEG_TO_RAD(ndlight.inner_angle);

        // XXX
        outlight->mType = ndlight.ltype==Light::SPOT ? aiLightSource_SPOT : aiLightSource_DIRECTIONAL;
    }
    else if (Node::TYPE_CAMERA == root.type) {
        const Camera& ndcam = (const Camera&)(root);
        aiCamera* outcam = fill->mCameras[fill->mNumCameras++] = new aiCamera();

        outcam->mName.Set(ndcam.name);
    }

    // add meshes
    if (nd->mNumMeshes) { // mMeshes must be NULL if count is 0
        nd->mMeshes = new unsigned int[nd->mNumMeshes];
        for(unsigned int i = 0; i < nd->mNumMeshes;++i) {
            nd->mMeshes[i] = fill->mNumMeshes-i-1;
        }
    }

    // add children recursively
    nd->mChildren = new aiNode*[root.temp_children.size()]();
    for(const Node* n : root.temp_children) {
        (nd->mChildren[nd->mNumChildren++] = BuildNodes(*n,scin,fill))->mParent = nd;
    }

    return nd;
}

// ------------------------------------------------------------------------------------------------
// Read an ASCII file into the given scene data structure
void COBImporter::ReadAsciiFile(Scene& out, StreamReaderLE* stream)
{
    ChunkInfo ci;
    for(LineSplitter splitter(*stream);splitter;++splitter) {

        // add all chunks to be recognized here. /else ../ omitted intentionally.
        if (splitter.match_start("PolH ")) {
            ReadChunkInfo_Ascii(ci,splitter);
            ReadPolH_Ascii(out,splitter,ci);
        }
        if (splitter.match_start("BitM ")) {
            ReadChunkInfo_Ascii(ci,splitter);
            ReadBitM_Ascii(out,splitter,ci);
        }
        if (splitter.match_start("Mat1 ")) {
            ReadChunkInfo_Ascii(ci,splitter);
            ReadMat1_Ascii(out,splitter,ci);
        }
        if (splitter.match_start("Grou ")) {
            ReadChunkInfo_Ascii(ci,splitter);
            ReadGrou_Ascii(out,splitter,ci);
        }
        if (splitter.match_start("Lght ")) {
            ReadChunkInfo_Ascii(ci,splitter);
            ReadLght_Ascii(out,splitter,ci);
        }
        if (splitter.match_start("Came ")) {
            ReadChunkInfo_Ascii(ci,splitter);
            ReadCame_Ascii(out,splitter,ci);
        }
        if (splitter.match_start("Bone ")) {
            ReadChunkInfo_Ascii(ci,splitter);
            ReadBone_Ascii(out,splitter,ci);
        }
        if (splitter.match_start("Chan ")) {
            ReadChunkInfo_Ascii(ci,splitter);
            ReadChan_Ascii(out,splitter,ci);
        }
        if (splitter.match_start("Unit ")) {
            ReadChunkInfo_Ascii(ci,splitter);
            ReadUnit_Ascii(out,splitter,ci);
        }
        if (splitter.match_start("END ")) {
            // we don't need this, but I guess there is a reason this
            // chunk has been implemented into COB for.
            return;
        }
    }
}

// ------------------------------------------------------------------------------------------------
void COBImporter::ReadChunkInfo_Ascii(ChunkInfo& out, const LineSplitter& splitter)
{
    const char* all_tokens[8];
    splitter.get_tokens(all_tokens);

    out.version = (all_tokens[1][1]-'0')*100+(all_tokens[1][3]-'0')*10+(all_tokens[1][4]-'0');
    out.id  = strtoul10(all_tokens[3]);
    out.parent_id = strtoul10(all_tokens[5]);
    out.size = strtol10(all_tokens[7]);
}

// ------------------------------------------------------------------------------------------------
void COBImporter::UnsupportedChunk_Ascii(LineSplitter& splitter, const ChunkInfo& nfo, const char* name)
{
    const std::string error = format("Encountered unsupported chunk: ") <<  name <<
        " [version: "<<nfo.version<<", size: "<<nfo.size<<"]";

    // we can recover if the chunk size was specified.
    if(nfo.size != static_cast<unsigned int>(-1)) {
        DefaultLogger::get()->error(error);

        // (HACK) - our current position in the stream is the beginning of the
        // head line of the next chunk. That's fine, but the caller is going
        // to call ++ on `splitter`, which we need to swallow to avoid
        // missing the next line.
        splitter.get_stream().IncPtr(nfo.size);
        splitter.swallow_next_increment();
    }
    else ThrowException(error);
}

// ------------------------------------------------------------------------------------------------
void COBImporter::LogWarn_Ascii(const LineSplitter& splitter, const format& message)    {
    LogWarn_Ascii(message << " [at line "<< splitter.get_index()<<"]");
}

// ------------------------------------------------------------------------------------------------
void COBImporter::LogError_Ascii(const LineSplitter& splitter, const format& message)   {
    LogError_Ascii(message << " [at line "<< splitter.get_index()<<"]");
}

// ------------------------------------------------------------------------------------------------
void COBImporter::LogInfo_Ascii(const LineSplitter& splitter, const format& message)    {
    LogInfo_Ascii(message << " [at line "<< splitter.get_index()<<"]");
}

// ------------------------------------------------------------------------------------------------
void COBImporter::LogDebug_Ascii(const LineSplitter& splitter, const format& message)   {
    LogDebug_Ascii(message << " [at line "<< splitter.get_index()<<"]");
}

// ------------------------------------------------------------------------------------------------
void COBImporter::LogWarn_Ascii(const Formatter::format& message)   {
    DefaultLogger::get()->warn(std::string("COB: ")+=message);
}

// ------------------------------------------------------------------------------------------------
void COBImporter::LogError_Ascii(const Formatter::format& message)  {
    DefaultLogger::get()->error(std::string("COB: ")+=message);
}

// ------------------------------------------------------------------------------------------------
void COBImporter::LogInfo_Ascii(const Formatter::format& message)   {
    DefaultLogger::get()->info(std::string("COB: ")+=message);
}

// ------------------------------------------------------------------------------------------------
void COBImporter::LogDebug_Ascii(const Formatter::format& message)  {
    DefaultLogger::get()->debug(std::string("COB: ")+=message);
}

// ------------------------------------------------------------------------------------------------
void COBImporter::ReadBasicNodeInfo_Ascii(Node& msh, LineSplitter& splitter, const ChunkInfo& /*nfo*/)
{
    for(;splitter;++splitter) {
        if (splitter.match_start("Name")) {
            msh.name = std::string(splitter[1]);

            // make nice names by merging the dupe count
            std::replace(msh.name.begin(),msh.name.end(),
                ',','_');
        }
        else if (splitter.match_start("Transform")) {
            for(unsigned int y = 0; y < 4 && ++splitter; ++y) {
                const char* s = splitter->c_str();
                for(unsigned int x = 0; x < 4; ++x) {
                    SkipSpaces(&s);
                    msh.transform[y][x] = fast_atof(&s);
                }
            }
            // we need the transform chunk, so we won't return until we have it.
            return;
        }
    }
}

// ------------------------------------------------------------------------------------------------
template <typename T>
void COBImporter::ReadFloat3Tuple_Ascii(T& fill, const char** in)
{
    const char* rgb = *in;
    for(unsigned int i = 0; i < 3; ++i) {
        SkipSpaces(&rgb);
        if (*rgb == ',')++rgb;
        SkipSpaces(&rgb);

        fill[i] = fast_atof(&rgb);
    }
    *in = rgb;
}

// ------------------------------------------------------------------------------------------------
void COBImporter::ReadMat1_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
{
    if(nfo.version > 8) {
        return UnsupportedChunk_Ascii(splitter,nfo,"Mat1");
    }

    ++splitter;
    if (!splitter.match_start("mat# ")) {
        LogWarn_Ascii(splitter,format()<<
            "Expected `mat#` line in `Mat1` chunk "<<nfo.id);
        return;
    }

    out.materials.push_back(Material());
    Material& mat = out.materials.back();
    mat = nfo;

    mat.matnum = strtoul10(splitter[1]);
    ++splitter;

    if (!splitter.match_start("shader: ")) {
        LogWarn_Ascii(splitter,format()<<
            "Expected `mat#` line in `Mat1` chunk "<<nfo.id);
        return;
    }
    std::string shader = std::string(splitter[1]);
    shader = shader.substr(0,shader.find_first_of(" \t"));

    if (shader == "metal") {
        mat.shader = Material::METAL;
    }
    else if (shader == "phong") {
        mat.shader = Material::PHONG;
    }
    else if (shader != "flat") {
        LogWarn_Ascii(splitter,format()<<
            "Unknown value for `shader` in `Mat1` chunk "<<nfo.id);
    }

    ++splitter;
    if (!splitter.match_start("rgb ")) {
        LogWarn_Ascii(splitter,format()<<
            "Expected `rgb` line in `Mat1` chunk "<<nfo.id);
    }

    const char* rgb = splitter[1];
    ReadFloat3Tuple_Ascii(mat.rgb,&rgb);

    ++splitter;
    if (!splitter.match_start("alpha ")) {
        LogWarn_Ascii(splitter,format()<<
            "Expected `alpha` line in `Mat1` chunk "<<nfo.id);
    }

    const char* tokens[10];
    splitter.get_tokens(tokens);

    mat.alpha   = fast_atof( tokens[1] );
    mat.ka      = fast_atof( tokens[3] );
    mat.ks      = fast_atof( tokens[5] );
    mat.exp     = fast_atof( tokens[7] );
    mat.ior     = fast_atof( tokens[9] );
}

// ------------------------------------------------------------------------------------------------
void COBImporter::ReadUnit_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
{
    if(nfo.version > 1) {
        return UnsupportedChunk_Ascii(splitter,nfo,"Unit");
    }
    ++splitter;
    if (!splitter.match_start("Units ")) {
        LogWarn_Ascii(splitter,format()<<
            "Expected `Units` line in `Unit` chunk "<<nfo.id);
        return;
    }

    // parent chunks preceede their childs, so we should have the
    // corresponding chunk already.
    for(std::shared_ptr< Node >& nd : out.nodes) {
        if (nd->id == nfo.parent_id) {
            const unsigned int t=strtoul10(splitter[1]);

            nd->unit_scale = t>=sizeof(units)/sizeof(units[0])?(
                LogWarn_Ascii(splitter,format()<<t<<" is not a valid value for `Units` attribute in `Unit chunk` "<<nfo.id)
                ,1.f):units[t];
            return;
        }
    }
    LogWarn_Ascii(splitter,format()<<"`Unit` chunk "<<nfo.id<<" is a child of "
        <<nfo.parent_id<<" which does not exist");
}

// ------------------------------------------------------------------------------------------------
void COBImporter::ReadChan_Ascii(Scene& /*out*/, LineSplitter& splitter, const ChunkInfo& nfo)
{
    if(nfo.version > 8) {
        return UnsupportedChunk_Ascii(splitter,nfo,"Chan");
    }
}

// ------------------------------------------------------------------------------------------------
void COBImporter::ReadLght_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
{
    if(nfo.version > 8) {
        return UnsupportedChunk_Ascii(splitter,nfo,"Lght");
    }

    out.nodes.push_back(std::shared_ptr<Light>(new Light()));
    Light& msh = (Light&)(*out.nodes.back().get());
    msh = nfo;

    ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);

    if (splitter.match_start("Infinite ")) {
        msh.ltype = Light::INFINITE;
    }
    else if (splitter.match_start("Local ")) {
        msh.ltype = Light::LOCAL;
    }
    else if (splitter.match_start("Spot ")) {
        msh.ltype = Light::SPOT;
    }
    else {
        LogWarn_Ascii(splitter,format()<<
            "Unknown kind of light source in `Lght` chunk "<<nfo.id<<" : "<<*splitter);
        msh.ltype = Light::SPOT;
    }

    ++splitter;
    if (!splitter.match_start("color ")) {
        LogWarn_Ascii(splitter,format()<<
            "Expected `color` line in `Lght` chunk "<<nfo.id);
    }

    const char* rgb = splitter[1];
    ReadFloat3Tuple_Ascii(msh.color ,&rgb);

    SkipSpaces(&rgb);
    if (strncmp(rgb,"cone angle",10)) {
        LogWarn_Ascii(splitter,format()<<
            "Expected `cone angle` entity in `color` line in `Lght` chunk "<<nfo.id);
    }
    SkipSpaces(rgb+10,&rgb);
    msh.angle = fast_atof(&rgb);

    SkipSpaces(&rgb);
    if (strncmp(rgb,"inner angle",11)) {
        LogWarn_Ascii(splitter,format()<<
            "Expected `inner angle` entity in `color` line in `Lght` chunk "<<nfo.id);
    }
    SkipSpaces(rgb+11,&rgb);
    msh.inner_angle = fast_atof(&rgb);

    // skip the rest for we can't handle this kind of physically-based lighting information.
}

// ------------------------------------------------------------------------------------------------
void COBImporter::ReadCame_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
{
    if(nfo.version > 2) {
        return UnsupportedChunk_Ascii(splitter,nfo,"Came");
    }

    out.nodes.push_back(std::shared_ptr<Camera>(new Camera()));
    Camera& msh = (Camera&)(*out.nodes.back().get());
    msh = nfo;

    ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);

    // skip the next line, we don't know this differenciation between a
    // standard camera and a panoramic camera.
    ++splitter;
}

// ------------------------------------------------------------------------------------------------
void COBImporter::ReadBone_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
{
    if(nfo.version > 5) {
        return UnsupportedChunk_Ascii(splitter,nfo,"Bone");
    }

    out.nodes.push_back(std::shared_ptr<Bone>(new Bone()));
    Bone& msh = (Bone&)(*out.nodes.back().get());
    msh = nfo;

    ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);

    // TODO
}

// ------------------------------------------------------------------------------------------------
void COBImporter::ReadGrou_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
{
    if(nfo.version > 1) {
        return UnsupportedChunk_Ascii(splitter,nfo,"Grou");
    }

    out.nodes.push_back(std::shared_ptr<Group>(new Group()));
    Group& msh = (Group&)(*out.nodes.back().get());
    msh = nfo;

    ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);
}

// ------------------------------------------------------------------------------------------------
void COBImporter::ReadPolH_Ascii(Scene& out, LineSplitter& splitter, const ChunkInfo& nfo)
{
    if(nfo.version > 8) {
        return UnsupportedChunk_Ascii(splitter,nfo,"PolH");
    }

    out.nodes.push_back(std::shared_ptr<Mesh>(new Mesh()));
    Mesh& msh = (Mesh&)(*out.nodes.back().get());
    msh = nfo;

    ReadBasicNodeInfo_Ascii(msh,++splitter,nfo);

    // the chunk has a fixed order of components, but some are not interesting of us so
    // we're just looking for keywords in arbitrary order. The end of the chunk is
    // either the last `Face` or the `DrawFlags` attribute, depending on the format ver.
    for(;splitter;++splitter) {
        if (splitter.match_start("World Vertices")) {
            const unsigned int cnt = strtoul10(splitter[2]);
            msh.vertex_positions.resize(cnt);

            for(unsigned int cur = 0;cur < cnt && ++splitter;++cur) {
                const char* s = splitter->c_str();

                aiVector3D& v = msh.vertex_positions[cur];

                SkipSpaces(&s);
                v.x = fast_atof(&s);
                SkipSpaces(&s);
                v.y = fast_atof(&s);
                SkipSpaces(&s);
                v.z = fast_atof(&s);
            }
        }
        else if (splitter.match_start("Texture Vertices")) {
            const unsigned int cnt = strtoul10(splitter[2]);
            msh.texture_coords.resize(cnt);

            for(unsigned int cur = 0;cur < cnt && ++splitter;++cur) {
                const char* s = splitter->c_str();

                aiVector2D& v = msh.texture_coords[cur];

                SkipSpaces(&s);
                v.x = fast_atof(&s);
                SkipSpaces(&s);
                v.y = fast_atof(&s);
            }
        }
        else if (splitter.match_start("Faces")) {
            const unsigned int cnt = strtoul10(splitter[1]);
            msh.faces.reserve(cnt);

            for(unsigned int cur = 0; cur < cnt && ++splitter ;++cur) {
                if (splitter.match_start("Hole")) {
                    LogWarn_Ascii(splitter,"Skipping unsupported `Hole` line");
                    continue;
                }

                if (!splitter.match_start("Face")) {
                    ThrowException("Expected Face line");
                }

                msh.faces.push_back(Face());
                Face& face = msh.faces.back();

                face.indices.resize(strtoul10(splitter[2]));
                face.flags = strtoul10(splitter[4]);
                face.material = strtoul10(splitter[6]);

                const char* s = (++splitter)->c_str();
                for(size_t i = 0; i < face.indices.size(); ++i) {
                    if(!SkipSpaces(&s)) {
                        ThrowException("Expected EOL token in Face entry");
                    }
                    if ('<' != *s++) {
                        ThrowException("Expected < token in Face entry");
                    }
                    face.indices[i].pos_idx = strtoul10(s,&s);
                    if (',' != *s++) {
                        ThrowException("Expected , token in Face entry");
                    }
                    face.indices[i].uv_idx = strtoul10(s,&s);
                    if ('>' != *s++) {
                        ThrowException("Expected < token in Face entry");
                    }
                }
            }
            if (nfo.version <= 4) {
                break;
            }
        }
        else if (splitter.match_start("DrawFlags")) {
            msh.draw_flags = strtoul10(splitter[1]);
            break;
        }
    }
}

// ------------------------------------------------------------------------------------------------
void COBImporter::ReadBitM_Ascii(Scene& /*out*/, LineSplitter& splitter, const ChunkInfo& nfo)
{
    if(nfo.version > 1) {
        return UnsupportedChunk_Ascii(splitter,nfo,"BitM");
    }
/*
    "\nThumbNailHdrSize %ld"
    "\nThumbHeader: %02hx 02hx %02hx "
    "\nColorBufSize %ld"
    "\nColorBufZipSize %ld"
    "\nZippedThumbnail: %02hx 02hx %02hx "
*/

    const unsigned int head = strtoul10((++splitter)[1]);
    if (head != sizeof(Bitmap::BitmapHeader)) {
        LogWarn_Ascii(splitter,"Unexpected ThumbNailHdrSize, skipping this chunk");
        return;
    }

    /*union {
        Bitmap::BitmapHeader data;
        char opaq[sizeof Bitmap::BitmapHeader()];
    };*/
//  ReadHexOctets(opaq,head,(++splitter)[1]);
}

// ------------------------------------------------------------------------------------------------
void COBImporter::ReadString_Binary(std::string& out, StreamReaderLE& reader)
{
    out.resize( reader.GetI2());
    for(char& c : out) {
        c = reader.GetI1();
    }
}

// ------------------------------------------------------------------------------------------------
void COBImporter::ReadBasicNodeInfo_Binary(Node& msh, StreamReaderLE& reader, const ChunkInfo& /*nfo*/)
{
    const unsigned int dupes = reader.GetI2();
    ReadString_Binary(msh.name,reader);

    msh.name = format(msh.name)<<'_'<<dupes;

    // skip local axes for the moment
    reader.IncPtr(48);

    msh.transform = aiMatrix4x4();
    for(unsigned int y = 0; y < 3; ++y) {
        for(unsigned int x =0; x < 4; ++x) {
            msh.transform[y][x] = reader.GetF4();
        }
    }
}

// ------------------------------------------------------------------------------------------------
void COBImporter::UnsupportedChunk_Binary( StreamReaderLE& reader, const ChunkInfo& nfo, const char* name)
{
    const std::string error = format("Encountered unsupported chunk: ") <<  name <<
        " [version: "<<nfo.version<<", size: "<<nfo.size<<"]";

    // we can recover if the chunk size was specified.
    if(nfo.size != static_cast<unsigned int>(-1)) {
        DefaultLogger::get()->error(error);
        reader.IncPtr(nfo.size);
    }
    else ThrowException(error);
}

// ------------------------------------------------------------------------------------------------
// tiny utility guard to aid me at staying within chunk boundaries.
class chunk_guard {
public:
    chunk_guard(const COB::ChunkInfo& nfo, StreamReaderLE& reader)
    : nfo(nfo)
    , reader(reader)
    , cur(reader.GetCurrentPos()) {
    }

    ~chunk_guard() {
        // don't do anything if the size is not given
        if(nfo.size != static_cast<unsigned int>(-1)) {
            try {
                reader.IncPtr( static_cast< int >( nfo.size ) - reader.GetCurrentPos() + cur );
            } catch ( DeadlyImportError e ) {
                // out of limit so correct the value
                reader.IncPtr( reader.GetReadLimit() );
            }
        }
    }

private:

    const COB::ChunkInfo& nfo;
    StreamReaderLE& reader;
    long cur;
};

// ------------------------------------------------------------------------------------------------
void COBImporter::ReadBinaryFile(Scene& out, StreamReaderLE* reader)
{
    while(1) {
        std::string type;
         type += reader -> GetI1()
        ,type += reader -> GetI1()
        ,type += reader -> GetI1()
        ,type += reader -> GetI1()
        ;

        ChunkInfo nfo;
        nfo.version  = reader -> GetI2()*10;
        nfo.version += reader -> GetI2();

        nfo.id = reader->GetI4();
        nfo.parent_id = reader->GetI4();
        nfo.size = reader->GetI4();

        if (type == "PolH") {
            ReadPolH_Binary(out,*reader,nfo);
        }
        else if (type == "BitM") {
            ReadBitM_Binary(out,*reader,nfo);
        }
        else if (type == "Grou") {
            ReadGrou_Binary(out,*reader,nfo);
        }
        else if (type == "Lght") {
            ReadLght_Binary(out,*reader,nfo);
        }
        else if (type == "Came") {
            ReadCame_Binary(out,*reader,nfo);
        }
        else if (type == "Mat1") {
            ReadMat1_Binary(out,*reader,nfo);
        }
    /*  else if (type == "Bone") {
            ReadBone_Binary(out,*reader,nfo);
        }
        else if (type == "Chan") {
            ReadChan_Binary(out,*reader,nfo);
        }*/
        else if (type == "Unit") {
            ReadUnit_Binary(out,*reader,nfo);
        }
        else if (type == "OLay") {
            // ignore layer index silently.
            if(nfo.size != static_cast<unsigned int>(-1) ) {
                reader->IncPtr(nfo.size);
            }
            else return UnsupportedChunk_Binary(*reader,nfo,type.c_str());
        }
        else if (type == "END ") {
            return;
        }
        else UnsupportedChunk_Binary(*reader,nfo,type.c_str());
    }
}

// ------------------------------------------------------------------------------------------------
void COBImporter::ReadPolH_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
{
    if(nfo.version > 8) {
        return UnsupportedChunk_Binary(reader,nfo,"PolH");
    }
    const chunk_guard cn(nfo,reader);

    out.nodes.push_back(std::shared_ptr<Mesh>(new Mesh()));
    Mesh& msh = (Mesh&)(*out.nodes.back().get());
    msh = nfo;

    ReadBasicNodeInfo_Binary(msh,reader,nfo);

    msh.vertex_positions.resize(reader.GetI4());
    for(aiVector3D& v : msh.vertex_positions) {
        v.x = reader.GetF4();
        v.y = reader.GetF4();
        v.z = reader.GetF4();
    }

    msh.texture_coords.resize(reader.GetI4());
    for(aiVector2D& v : msh.texture_coords) {
        v.x = reader.GetF4();
        v.y = reader.GetF4();
    }

    const size_t numf = reader.GetI4();
    msh.faces.reserve(numf);
    for(size_t i = 0; i < numf; ++i) {
        // XXX backface culling flag is 0x10 in flags

        // hole?
        bool hole;
        if ((hole = (reader.GetI1() & 0x08) != 0)) {
            // XXX Basically this should just work fine - then triangulator
            // should output properly triangulated data even for polygons
            // with holes. Test data specific to COB is needed to confirm it.
            if (msh.faces.empty()) {
                ThrowException(format("A hole is the first entity in the `PolH` chunk with id ") << nfo.id);
            }
        }
        else msh.faces.push_back(Face());
        Face& f = msh.faces.back();

        const size_t num = reader.GetI2();
        f.indices.reserve(f.indices.size() + num);

        if(!hole) {
            f.material = reader.GetI2();
            f.flags = 0;
        }

        for(size_t x = 0; x < num; ++x) {
            f.indices.push_back(VertexIndex());

            VertexIndex& v = f.indices.back();
            v.pos_idx = reader.GetI4();
            v.uv_idx = reader.GetI4();
        }

        if(hole) {
            std::reverse(f.indices.rbegin(),f.indices.rbegin()+num);
        }
    }
    if (nfo.version>4) {
        msh.draw_flags = reader.GetI4();
    }
    nfo.version>5 && nfo.version<8 ? reader.GetI4() : 0;
}

// ------------------------------------------------------------------------------------------------
void COBImporter::ReadBitM_Binary(COB::Scene& /*out*/, StreamReaderLE& reader, const ChunkInfo& nfo)
{
    if(nfo.version > 1) {
        return UnsupportedChunk_Binary(reader,nfo,"BitM");
    }

    const chunk_guard cn(nfo,reader);

    const uint32_t len = reader.GetI4();
    reader.IncPtr(len);

    reader.GetI4();
    reader.IncPtr(reader.GetI4());
}

// ------------------------------------------------------------------------------------------------
void COBImporter::ReadMat1_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
{
    if(nfo.version > 8) {
        return UnsupportedChunk_Binary(reader,nfo,"Mat1");
    }

    const chunk_guard cn(nfo,reader);

    out.materials.push_back(Material());
    Material& mat = out.materials.back();
    mat = nfo;

    mat.matnum = reader.GetI2();
    switch(reader.GetI1()) {
        case 'f':
            mat.type = Material::FLAT;
            break;
        case 'p':
            mat.type = Material::PHONG;
            break;
        case 'm':
            mat.type = Material::METAL;
            break;
        default:
            LogError_Ascii(format("Unrecognized shader type in `Mat1` chunk with id ")<<nfo.id);
            mat.type = Material::FLAT;
    }

    switch(reader.GetI1()) {
        case 'f':
            mat.autofacet = Material::FACETED;
            break;
        case 'a':
            mat.autofacet = Material::AUTOFACETED;
            break;
        case 's':
            mat.autofacet = Material::SMOOTH;
            break;
        default:
            LogError_Ascii(format("Unrecognized faceting mode in `Mat1` chunk with id ")<<nfo.id);
            mat.autofacet = Material::FACETED;
    }
    mat.autofacet_angle = static_cast<float>(reader.GetI1());

    mat.rgb.r = reader.GetF4();
    mat.rgb.g = reader.GetF4();
    mat.rgb.b = reader.GetF4();

    mat.alpha = reader.GetF4();
    mat.ka    = reader.GetF4();
    mat.ks    = reader.GetF4();
    mat.exp   = reader.GetF4();
    mat.ior   = reader.GetF4();

    char id[2];
    id[0] = reader.GetI1(),id[1] = reader.GetI1();

    if (id[0] == 'e' && id[1] == ':') {
        mat.tex_env.reset(new Texture());

        reader.GetI1();
        ReadString_Binary(mat.tex_env->path,reader);

        // advance to next texture-id
        id[0] = reader.GetI1(),id[1] = reader.GetI1();
    }

    if (id[0] == 't' && id[1] == ':') {
        mat.tex_color.reset(new Texture());

        reader.GetI1();
        ReadString_Binary(mat.tex_color->path,reader);

        mat.tex_color->transform.mTranslation.x = reader.GetF4();
        mat.tex_color->transform.mTranslation.y = reader.GetF4();

        mat.tex_color->transform.mScaling.x = reader.GetF4();
        mat.tex_color->transform.mScaling.y = reader.GetF4();

        // advance to next texture-id
        id[0] = reader.GetI1(),id[1] = reader.GetI1();
    }

    if (id[0] == 'b' && id[1] == ':') {
        mat.tex_bump.reset(new Texture());

        reader.GetI1();
        ReadString_Binary(mat.tex_bump->path,reader);

        mat.tex_bump->transform.mTranslation.x = reader.GetF4();
        mat.tex_bump->transform.mTranslation.y = reader.GetF4();

        mat.tex_bump->transform.mScaling.x = reader.GetF4();
        mat.tex_bump->transform.mScaling.y = reader.GetF4();

        // skip amplitude for I don't know its purpose.
        reader.GetF4();
    }
    reader.IncPtr(-2);
}

// ------------------------------------------------------------------------------------------------
void COBImporter::ReadCame_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
{
    if(nfo.version > 2) {
        return UnsupportedChunk_Binary(reader,nfo,"Came");
    }

    const chunk_guard cn(nfo,reader);

    out.nodes.push_back(std::shared_ptr<Camera>(new Camera()));
    Camera& msh = (Camera&)(*out.nodes.back().get());
    msh = nfo;

    ReadBasicNodeInfo_Binary(msh,reader,nfo);

    // the rest is not interesting for us, so we skip over it.
    if(nfo.version > 1) {
        if (reader.GetI2()==512) {
            reader.IncPtr(42);
        }
    }
}

// ------------------------------------------------------------------------------------------------
void COBImporter::ReadLght_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
{
    if(nfo.version > 2) {
        return UnsupportedChunk_Binary(reader,nfo,"Lght");
    }

    const chunk_guard cn(nfo,reader);

    out.nodes.push_back(std::shared_ptr<Light>(new Light()));
    Light& msh = (Light&)(*out.nodes.back().get());
    msh = nfo;

    ReadBasicNodeInfo_Binary(msh,reader,nfo);
}

// ------------------------------------------------------------------------------------------------
void COBImporter::ReadGrou_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
{
    if(nfo.version > 2) {
        return UnsupportedChunk_Binary(reader,nfo,"Grou");
    }

    const chunk_guard cn(nfo,reader);

    out.nodes.push_back(std::shared_ptr<Group>(new Group()));
    Group& msh = (Group&)(*out.nodes.back().get());
    msh = nfo;

    ReadBasicNodeInfo_Binary(msh,reader,nfo);
}

// ------------------------------------------------------------------------------------------------
void COBImporter::ReadUnit_Binary(COB::Scene& out, StreamReaderLE& reader, const ChunkInfo& nfo)
{
     if(nfo.version > 1) {
        return UnsupportedChunk_Binary(reader,nfo,"Unit");
    }

     const chunk_guard cn(nfo,reader);

    // parent chunks preceede their childs, so we should have the
    // corresponding chunk already.
    for(std::shared_ptr< Node >& nd : out.nodes) {
        if (nd->id == nfo.parent_id) {
            const unsigned int t=reader.GetI2();
            nd->unit_scale = t>=sizeof(units)/sizeof(units[0])?(
                LogWarn_Ascii(format()<<t<<" is not a valid value for `Units` attribute in `Unit chunk` "<<nfo.id)
                ,1.f):units[t];

            return;
        }
    }
    LogWarn_Ascii(format()<<"`Unit` chunk "<<nfo.id<<" is a child of "
        <<nfo.parent_id<<" which does not exist");
}


#endif
