/*
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 Defines the helper data structures for importing ASE files  */
#ifndef AI_ASEFILEHELPER_H_INC
#define AI_ASEFILEHELPER_H_INC

// public ASSIMP headers
#include <assimp/types.h>
#include <assimp/mesh.h>
#include <assimp/anim.h>

#ifndef ASSIMP_BUILD_NO_3DS_IMPORTER

// for some helper routines like IsSpace()
#include "ParsingUtils.h"
#include "qnan.h"

// ASE is quite similar to 3ds. We can reuse some structures
#include "3DSLoader.h"

namespace Assimp    {
namespace ASE   {

using namespace D3DS;

// ---------------------------------------------------------------------------
/** Helper structure representing an ASE material */
struct Material : public D3DS::Material
{
    //! Default constructor
    Material() : pcInstance(NULL), bNeed (false)
    {}

    //! Contains all sub materials of this material
    std::vector<Material> avSubMaterials;

    //! aiMaterial object
    aiMaterial* pcInstance;

    //! Can we remove this material?
    bool bNeed;
};

// ---------------------------------------------------------------------------
/** Helper structure to represent an ASE file face */
struct Face : public FaceWithSmoothingGroup
{
    //! Default constructor. Initializes everything with 0
    Face()
    {
        mColorIndices[0] = mColorIndices[1] = mColorIndices[2] = 0;
        for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
        {
            amUVIndices[i][0] = amUVIndices[i][1] = amUVIndices[i][2] = 0;
        }

        iMaterial = DEFAULT_MATINDEX;
        iFace = 0;
    }

    //! special value to indicate that no material index has
    //! been assigned to a face. The default material index
    //! will replace this value later.
    static const unsigned int DEFAULT_MATINDEX = 0xFFFFFFFF;



    //! Indices into each list of texture coordinates
    unsigned int amUVIndices[AI_MAX_NUMBER_OF_TEXTURECOORDS][3];

    //! Index into the list of vertex colors
    unsigned int mColorIndices[3];

    //! (Sub)Material index to be assigned to this face
    unsigned int iMaterial;

    //! Index of the face. It is not specified whether it is
    //! a requirement of the file format that all faces are
    //! written in sequential order, so we have to expect this case
    unsigned int iFace;
};

// ---------------------------------------------------------------------------
/** Helper structure to represent an ASE file bone */
struct Bone
{
    //! Constructor
    Bone()
    {
        static int iCnt = 0;

        // Generate a default name for the bone
        char szTemp[128];
        ::ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
        mName = szTemp;
    }

    //! Construction from an existing name
    explicit Bone( const std::string& name)
        :   mName   (name)
    {}

    //! Name of the bone
    std::string mName;
};

// ---------------------------------------------------------------------------
/** Helper structure to represent an ASE file bone vertex */
struct BoneVertex
{
    //! Bone and corresponding vertex weight.
    //! -1 for unrequired bones ....
    std::vector<std::pair<int,float> > mBoneWeights;

    //! Position of the bone vertex.
    //! MUST be identical to the vertex position
    //aiVector3D mPosition;
};

// ---------------------------------------------------------------------------
/** Helper structure to represent an ASE file animation */
struct Animation
{
    enum Type
    {
        TRACK   = 0x0,
        BEZIER  = 0x1,
        TCB     = 0x2
    } mRotationType, mScalingType, mPositionType;

    Animation()
        :   mRotationType   (TRACK)
        ,   mScalingType    (TRACK)
        ,   mPositionType   (TRACK)
    {}

    //! List of track rotation keyframes
    std::vector< aiQuatKey > akeyRotations;

    //! List of track position keyframes
    std::vector< aiVectorKey > akeyPositions;

    //! List of track scaling keyframes
    std::vector< aiVectorKey > akeyScaling;

};

// ---------------------------------------------------------------------------
/** Helper structure to represent the inheritance information of an ASE node */
struct InheritanceInfo
{
    //! Default constructor
    InheritanceInfo()
    {
        // set the inheritance flag for all axes by default to true
        for (unsigned int i = 0; i < 3;++i)
            abInheritPosition[i] = abInheritRotation[i] = abInheritScaling[i] = true;
    }

    //! Inherit the parent's position?, axis order is x,y,z
    bool abInheritPosition[3];

    //! Inherit the parent's rotation?, axis order is x,y,z
    bool abInheritRotation[3];

    //! Inherit the parent's scaling?, axis order is x,y,z
    bool abInheritScaling[3];
};

// ---------------------------------------------------------------------------
/** Represents an ASE file node. Base class for mesh, light and cameras */
struct BaseNode
{
    enum Type {Light, Camera, Mesh, Dummy} mType;

    //! Constructor. Creates a default name for the node
    explicit BaseNode(Type _mType)
        : mType         (_mType)
        , mProcessed    (false)
    {
        // generate a default name for the  node
        static int iCnt = 0;
        char szTemp[128]; // should be sufficiently large
        ::ai_snprintf(szTemp, 128, "UNNAMED_%i",iCnt++);
        mName = szTemp;

        // Set mTargetPosition to qnan
        const ai_real qnan = get_qnan();
        mTargetPosition.x = qnan;
    }

    //! Name of the mesh
    std::string mName;

    //! Name of the parent of the node
    //! "" if there is no parent ...
    std::string mParent;

    //! Transformation matrix of the node
    aiMatrix4x4 mTransform;

    //! Target position (target lights and cameras)
    aiVector3D mTargetPosition;

    //! Specifies which axes transformations a node inherits
    //! from its parent ...
    InheritanceInfo inherit;

    //! Animation channels for the node
    Animation mAnim;

    //! Needed for lights and cameras: target animation channel
    //! Should contain position keys only.
    Animation mTargetAnim;

    bool mProcessed;
};

// ---------------------------------------------------------------------------
/** Helper structure to represent an ASE file mesh */
struct Mesh : public MeshWithSmoothingGroups<ASE::Face>, public BaseNode
{
    //! Constructor.
    Mesh()
        : BaseNode  (BaseNode::Mesh)
        , bSkip     (false)
    {
        // use 2 texture vertex components by default
        for (unsigned int c = 0; c < AI_MAX_NUMBER_OF_TEXTURECOORDS;++c)
            this->mNumUVComponents[c] = 2;

        // setup the default material index by default
        iMaterialIndex = Face::DEFAULT_MATINDEX;
    }

    //! List of all texture coordinate sets
    std::vector<aiVector3D> amTexCoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];

    //! List of all vertex color sets.
    std::vector<aiColor4D> mVertexColors;

    //! List of all bone vertices
    std::vector<BoneVertex> mBoneVertices;

    //! List of all bones
    std::vector<Bone> mBones;

    //! Material index of the mesh
    unsigned int iMaterialIndex;

    //! Number of vertex components for each UVW set
    unsigned int mNumUVComponents[AI_MAX_NUMBER_OF_TEXTURECOORDS];

    //! used internally
    bool bSkip;
};

// ---------------------------------------------------------------------------
/** Helper structure to represent an ASE light source */
struct Light : public BaseNode
{
    enum LightType
    {
        OMNI,
        TARGET,
        FREE,
        DIRECTIONAL
    };

    //! Constructor.
    Light()
        : BaseNode   (BaseNode::Light)
        , mLightType (OMNI)
        , mColor     (1.f,1.f,1.f)
        , mIntensity (1.f) // light is white by default
        , mAngle     (45.f)
        , mFalloff   (0.f)
    {
    }

    LightType mLightType;
    aiColor3D mColor;
    ai_real mIntensity;
    ai_real mAngle; // in degrees
    ai_real mFalloff;
};

// ---------------------------------------------------------------------------
/** Helper structure to represent an ASE camera */
struct Camera : public BaseNode
{
    enum CameraType
    {
        FREE,
        TARGET
    };

    //! Constructor
    Camera()
        : BaseNode    (BaseNode::Camera)
        , mFOV        (0.75f)   // in radians
        , mNear       (0.1f)
        , mFar        (1000.f)  // could be zero
        , mCameraType (FREE)
    {
    }

    ai_real mFOV, mNear, mFar;
    CameraType mCameraType;
};

// ---------------------------------------------------------------------------
/** Helper structure to represent an ASE helper object (dummy) */
struct Dummy : public BaseNode
{
    //! Constructor
    Dummy()
        : BaseNode  (BaseNode::Dummy)
    {
    }
};

// Parameters to Parser::Parse()
#define AI_ASE_NEW_FILE_FORMAT 200
#define AI_ASE_OLD_FILE_FORMAT 110

// Internally we're a little bit more tolerant
#define AI_ASE_IS_NEW_FILE_FORMAT() (iFileFormat >= 200)
#define AI_ASE_IS_OLD_FILE_FORMAT() (iFileFormat < 200)

// -------------------------------------------------------------------------------
/** \brief Class to parse ASE files
 */
class Parser
{

private:

    Parser() {}

public:

    // -------------------------------------------------------------------
    //! Construct a parser from a given input file which is
    //! guaranted to be terminated with zero.
    //! @param szFile Input file
    //! @param fileFormatDefault Assumed file format version. If the
    //!   file format is specified in the file the new value replaces
    //!   the default value.
    Parser (const char* szFile, unsigned int fileFormatDefault);

    // -------------------------------------------------------------------
    //! Parses the file into the parsers internal representation
    void Parse();


private:

    // -------------------------------------------------------------------
    //! Parse the *SCENE block in a file
    void ParseLV1SceneBlock();

    // -------------------------------------------------------------------
    //! Parse the *MESH_SOFTSKINVERTS block in a file
    void ParseLV1SoftSkinBlock();

    // -------------------------------------------------------------------
    //! Parse the *MATERIAL_LIST block in a file
    void ParseLV1MaterialListBlock();

    // -------------------------------------------------------------------
    //! Parse a *<xxx>OBJECT block in a file
    //! \param mesh Node to be filled
    void ParseLV1ObjectBlock(BaseNode& mesh);

    // -------------------------------------------------------------------
    //! Parse a *MATERIAL blocks in a material list
    //! \param mat Material structure to be filled
    void ParseLV2MaterialBlock(Material& mat);

    // -------------------------------------------------------------------
    //! Parse a *NODE_TM block in a file
    //! \param mesh Node (!) object to be filled
    void ParseLV2NodeTransformBlock(BaseNode& mesh);

    // -------------------------------------------------------------------
    //! Parse a *TM_ANIMATION block in a file
    //! \param mesh Mesh object to be filled
    void ParseLV2AnimationBlock(BaseNode& mesh);
    void ParseLV3PosAnimationBlock(ASE::Animation& anim);
    void ParseLV3ScaleAnimationBlock(ASE::Animation& anim);
    void ParseLV3RotAnimationBlock(ASE::Animation& anim);

    // -------------------------------------------------------------------
    //! Parse a *MESH block in a file
    //! \param mesh Mesh object to be filled
    void ParseLV2MeshBlock(Mesh& mesh);

    // -------------------------------------------------------------------
    //! Parse a *LIGHT_SETTINGS block in a file
    //! \param light Light object to be filled
    void ParseLV2LightSettingsBlock(Light& light);

    // -------------------------------------------------------------------
    //! Parse a *CAMERA_SETTINGS block in a file
    //! \param cam Camera object to be filled
    void ParseLV2CameraSettingsBlock(Camera& cam);

    // -------------------------------------------------------------------
    //! Parse the *MAP_XXXXXX blocks in a material
    //! \param map Texture structure to be filled
    void ParseLV3MapBlock(Texture& map);

    // -------------------------------------------------------------------
    //! Parse a *MESH_VERTEX_LIST block in a file
    //! \param iNumVertices Value of *MESH_NUMVERTEX, if present.
    //! Otherwise zero. This is used to check the consistency of the file.
    //! A warning is sent to the logger if the validations fails.
    //! \param mesh Mesh object to be filled
    void ParseLV3MeshVertexListBlock(
        unsigned int iNumVertices,Mesh& mesh);

    // -------------------------------------------------------------------
    //! Parse a *MESH_FACE_LIST block in a file
    //! \param iNumFaces Value of *MESH_NUMFACES, if present.
    //! Otherwise zero. This is used to check the consistency of the file.
    //! A warning is sent to the logger if the validations fails.
    //! \param mesh Mesh object to be filled
    void ParseLV3MeshFaceListBlock(
        unsigned int iNumFaces,Mesh& mesh);

    // -------------------------------------------------------------------
    //! Parse a *MESH_TVERT_LIST block in a file
    //! \param iNumVertices Value of *MESH_NUMTVERTEX, if present.
    //! Otherwise zero. This is used to check the consistency of the file.
    //! A warning is sent to the logger if the validations fails.
    //! \param mesh Mesh object to be filled
    //! \param iChannel Output UVW channel
    void ParseLV3MeshTListBlock(
        unsigned int iNumVertices,Mesh& mesh, unsigned int iChannel = 0);

    // -------------------------------------------------------------------
    //! Parse a *MESH_TFACELIST block in a file
    //! \param iNumFaces Value of *MESH_NUMTVFACES, if present.
    //! Otherwise zero. This is used to check the consistency of the file.
    //! A warning is sent to the logger if the validations fails.
    //! \param mesh Mesh object to be filled
    //! \param iChannel Output UVW channel
    void ParseLV3MeshTFaceListBlock(
        unsigned int iNumFaces,Mesh& mesh, unsigned int iChannel = 0);

    // -------------------------------------------------------------------
    //! Parse an additional mapping channel
    //! (specified via *MESH_MAPPINGCHANNEL)
    //! \param iChannel Channel index to be filled
    //! \param mesh Mesh object to be filled
    void ParseLV3MappingChannel(
        unsigned int iChannel, Mesh& mesh);

    // -------------------------------------------------------------------
    //! Parse a *MESH_CVERTLIST block in a file
    //! \param iNumVertices Value of *MESH_NUMCVERTEX, if present.
    //! Otherwise zero. This is used to check the consistency of the file.
    //! A warning is sent to the logger if the validations fails.
    //! \param mesh Mesh object to be filled
    void ParseLV3MeshCListBlock(
        unsigned int iNumVertices, Mesh& mesh);

    // -------------------------------------------------------------------
    //! Parse a *MESH_CFACELIST block in a file
    //! \param iNumFaces Value of *MESH_NUMCVFACES, if present.
    //! Otherwise zero. This is used to check the consistency of the file.
    //! A warning is sent to the logger if the validations fails.
    //! \param mesh Mesh object to be filled
    void ParseLV3MeshCFaceListBlock(
        unsigned int iNumFaces, Mesh& mesh);

    // -------------------------------------------------------------------
    //! Parse a *MESH_NORMALS block in a file
    //! \param mesh Mesh object to be filled
    void ParseLV3MeshNormalListBlock(Mesh& mesh);

    // -------------------------------------------------------------------
    //! Parse a *MESH_WEIGHTSblock in a file
    //! \param mesh Mesh object to be filled
    void ParseLV3MeshWeightsBlock(Mesh& mesh);

    // -------------------------------------------------------------------
    //! Parse the bone list of a file
    //! \param mesh Mesh object to be filled
    //! \param iNumBones Number of bones in the mesh
    void ParseLV4MeshBones(unsigned int iNumBones,Mesh& mesh);

    // -------------------------------------------------------------------
    //! Parse the bone vertices list of a file
    //! \param mesh Mesh object to be filled
    //! \param iNumVertices Number of vertices to be parsed
    void ParseLV4MeshBonesVertices(unsigned int iNumVertices,Mesh& mesh);

    // -------------------------------------------------------------------
    //! Parse a *MESH_FACE block in a file
    //! \param out receive the face data
    void ParseLV4MeshFace(ASE::Face& out);

    // -------------------------------------------------------------------
    //! Parse a *MESH_VERT block in a file
    //! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL  ...)
    //! \param apOut Output buffer (3 floats)
    //! \param rIndexOut Output index
    void ParseLV4MeshFloatTriple(ai_real* apOut, unsigned int& rIndexOut);

    // -------------------------------------------------------------------
    //! Parse a *MESH_VERT block in a file
    //! (also works for MESH_TVERT, MESH_CFACE, MESH_VERTCOL  ...)
    //! \param apOut Output buffer (3 floats)
    void ParseLV4MeshFloatTriple(ai_real* apOut);

    // -------------------------------------------------------------------
    //! Parse a *MESH_TFACE block in a file
    //! (also works for MESH_CFACE)
    //! \param apOut Output buffer (3 ints)
    //! \param rIndexOut Output index
    void ParseLV4MeshLongTriple(unsigned int* apOut, unsigned int& rIndexOut);

    // -------------------------------------------------------------------
    //! Parse a *MESH_TFACE block in a file
    //! (also works for MESH_CFACE)
    //! \param apOut Output buffer (3 ints)
    void ParseLV4MeshLongTriple(unsigned int* apOut);

    // -------------------------------------------------------------------
    //! Parse a single float element
    //! \param fOut Output float
    void ParseLV4MeshFloat(ai_real& fOut);

    // -------------------------------------------------------------------
    //! Parse a single int element
    //! \param iOut Output integer
    void ParseLV4MeshLong(unsigned int& iOut);

    // -------------------------------------------------------------------
    //! Skip everything to the next: '*' or '\0'
    bool SkipToNextToken();

    // -------------------------------------------------------------------
    //! Skip the current section until the token after the closing }.
    //! This function handles embedded subsections correctly
    bool SkipSection();

    // -------------------------------------------------------------------
    //! Output a warning to the logger
    //! \param szWarn Warn message
    void LogWarning(const char* szWarn);

    // -------------------------------------------------------------------
    //! Output a message to the logger
    //! \param szWarn Message
    void LogInfo(const char* szWarn);

    // -------------------------------------------------------------------
    //! Output an error to the logger
    //! \param szWarn Error message
    AI_WONT_RETURN void LogError(const char* szWarn) AI_WONT_RETURN_SUFFIX;

    // -------------------------------------------------------------------
    //! Parse a string, enclosed in double quotation marks
    //! \param out Output string
    //! \param szName Name of the enclosing element -> used in error
    //! messages.
    //! \return false if an error occurred
    bool ParseString(std::string& out,const char* szName);

public:

    //! Pointer to current data
    const char* filePtr;

    //! background color to be passed to the viewer
    //! QNAN if none was found
    aiColor3D m_clrBackground;

    //! Base ambient color to be passed to all materials
    //! QNAN if none was found
    aiColor3D m_clrAmbient;

    //! List of all materials found in the file
    std::vector<Material> m_vMaterials;

    //! List of all meshes found in the file
    std::vector<Mesh> m_vMeshes;

    //! List of all dummies found in the file
    std::vector<Dummy> m_vDummies;

    //! List of all lights found in the file
    std::vector<Light> m_vLights;

    //! List of all cameras found in the file
    std::vector<Camera> m_vCameras;

    //! Current line in the file
    unsigned int iLineNumber;

    //! First frame
    unsigned int iFirstFrame;

    //! Last frame
    unsigned int iLastFrame;

    //! Frame speed - frames per second
    unsigned int iFrameSpeed;

    //! Ticks per frame
    unsigned int iTicksPerFrame;

    //! true if the last character read was an end-line character
    bool bLastWasEndLine;

    //! File format version
    unsigned int iFileFormat;
};


} // Namespace ASE
} // Namespace ASSIMP

#endif // ASSIMP_BUILD_NO_3DS_IMPORTER

#endif // !! include guard
