/*
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 a helper class to represent an interleaved vertex
  along with arithmetic operations to support vertex operations
  such as subdivision, smoothing etc.

  While the code is kept as general as possible, arithmetic operations
  that are not currently well-defined (and would cause compile errors
  due to missing operators in the math library), are commented.
  */
#ifndef AI_VERTEX_H_INC
#define AI_VERTEX_H_INC

#include <assimp/vector3.h>
#include <assimp/mesh.h>
#include <assimp/ai_assert.h>
#include <functional>

namespace Assimp    {

    ///////////////////////////////////////////////////////////////////////////
    // std::plus-family operates on operands with identical types - we need to
    // support all the (vectype op float) combinations in vector maths.
    // Providing T(float) would open the way to endless implicit conversions.
    ///////////////////////////////////////////////////////////////////////////
    namespace Intern {
        template <typename T0, typename T1, typename TRES = T0> struct plus {
            TRES operator() (const T0& t0, const T1& t1) const {
                return t0+t1;
            }
        };
        template <typename T0, typename T1, typename TRES = T0> struct minus {
            TRES operator() (const T0& t0, const T1& t1) const {
                return t0-t1;
            }
        };
        template <typename T0, typename T1, typename TRES = T0> struct multiplies {
            TRES operator() (const T0& t0, const T1& t1) const {
                return t0*t1;
            }
        };
        template <typename T0, typename T1, typename TRES = T0> struct divides {
            TRES operator() (const T0& t0, const T1& t1) const {
                return t0/t1;
            }
        };
    }

// ------------------------------------------------------------------------------------------------
/** Intermediate description a vertex with all possible components. Defines a full set of
 *  operators, so you may use such a 'Vertex' in basic arithmetics. All operators are applied
 *  to *all* vertex components equally. This is useful for stuff like interpolation
 *  or subdivision, but won't work if special handling is required for some vertex components. */
// ------------------------------------------------------------------------------------------------
class Vertex
{
    friend Vertex operator + (const Vertex&,const Vertex&);
    friend Vertex operator - (const Vertex&,const Vertex&);

//  friend Vertex operator + (const Vertex&,ai_real);
//  friend Vertex operator - (const Vertex&,ai_real);
    friend Vertex operator * (const Vertex&,ai_real);
    friend Vertex operator / (const Vertex&,ai_real);

//  friend Vertex operator + (ai_real, const Vertex&);
//  friend Vertex operator - (ai_real, const Vertex&);
    friend Vertex operator * (ai_real, const Vertex&);
//  friend Vertex operator / (ai_real, const Vertex&);

public:

    Vertex() {}

    // ----------------------------------------------------------------------------
    /** Extract a particular vertex from a mesh and interleave all components */
    explicit Vertex(const aiMesh* msh, unsigned int idx) {
        ai_assert(idx < msh->mNumVertices);
        position = msh->mVertices[idx];

        if (msh->HasNormals()) {
            normal = msh->mNormals[idx];
        }

        if (msh->HasTangentsAndBitangents()) {
            tangent = msh->mTangents[idx];
            bitangent = msh->mBitangents[idx];
        }

        for (unsigned int i = 0; msh->HasTextureCoords(i); ++i) {
            texcoords[i] = msh->mTextureCoords[i][idx];
        }

        for (unsigned int i = 0; msh->HasVertexColors(i); ++i) {
            colors[i] = msh->mColors[i][idx];
        }
    }

public:

    Vertex& operator += (const Vertex& v) {
        *this = *this+v;
        return *this;
    }

    Vertex& operator -= (const Vertex& v) {
        *this = *this-v;
        return *this;
    }


/*
    Vertex& operator += (ai_real v) {
        *this = *this+v;
        return *this;
    }

    Vertex& operator -= (ai_real v) {
        *this = *this-v;
        return *this;
    }
*/
    Vertex& operator *= (ai_real v) {
        *this = *this*v;
        return *this;
    }

    Vertex& operator /= (ai_real v) {
        *this = *this/v;
        return *this;
    }

public:

    // ----------------------------------------------------------------------------
    /** Convert back to non-interleaved storage */
    void SortBack(aiMesh* out, unsigned int idx) const {

        ai_assert(idx<out->mNumVertices);
        out->mVertices[idx] = position;

        if (out->HasNormals()) {
            out->mNormals[idx] = normal;
        }

        if (out->HasTangentsAndBitangents()) {
            out->mTangents[idx] = tangent;
            out->mBitangents[idx] = bitangent;
        }

        for(unsigned int i = 0; out->HasTextureCoords(i); ++i) {
            out->mTextureCoords[i][idx] = texcoords[i];
        }

        for(unsigned int i = 0; out->HasVertexColors(i); ++i) {
            out->mColors[i][idx] = colors[i];
        }
    }

private:

    // ----------------------------------------------------------------------------
    /** Construct from two operands and a binary operation to combine them */
    template <template <typename t> class op> static Vertex BinaryOp(const Vertex& v0, const Vertex& v1) {
        // this is a heavy task for the compiler to optimize ... *pray*

        Vertex res;
        res.position  = op<aiVector3D>()(v0.position,v1.position);
        res.normal    = op<aiVector3D>()(v0.normal,v1.normal);
        res.tangent   = op<aiVector3D>()(v0.tangent,v1.tangent);
        res.bitangent = op<aiVector3D>()(v0.bitangent,v1.bitangent);

        for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
            res.texcoords[i] = op<aiVector3D>()(v0.texcoords[i],v1.texcoords[i]);
        }
        for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
            res.colors[i] = op<aiColor4D>()(v0.colors[i],v1.colors[i]);
        }
        return res;
    }

    // ----------------------------------------------------------------------------
    /** This time binary arithmetics of v0 with a floating-point number */
    template <template <typename, typename, typename> class op> static Vertex BinaryOp(const Vertex& v0, ai_real f) {
        // this is a heavy task for the compiler to optimize ... *pray*

        Vertex res;
        res.position  = op<aiVector3D,ai_real,aiVector3D>()(v0.position,f);
        res.normal    = op<aiVector3D,ai_real,aiVector3D>()(v0.normal,f);
        res.tangent   = op<aiVector3D,ai_real,aiVector3D>()(v0.tangent,f);
        res.bitangent = op<aiVector3D,ai_real,aiVector3D>()(v0.bitangent,f);

        for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
            res.texcoords[i] = op<aiVector3D,ai_real,aiVector3D>()(v0.texcoords[i],f);
        }
        for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
            res.colors[i] = op<aiColor4D,ai_real,aiColor4D>()(v0.colors[i],f);
        }
        return res;
    }

    // ----------------------------------------------------------------------------
    /** This time binary arithmetics of v0 with a floating-point number */
    template <template <typename, typename, typename> class op> static Vertex BinaryOp(ai_real f, const Vertex& v0) {
        // this is a heavy task for the compiler to optimize ... *pray*

        Vertex res;
        res.position  = op<ai_real,aiVector3D,aiVector3D>()(f,v0.position);
        res.normal    = op<ai_real,aiVector3D,aiVector3D>()(f,v0.normal);
        res.tangent   = op<ai_real,aiVector3D,aiVector3D>()(f,v0.tangent);
        res.bitangent = op<ai_real,aiVector3D,aiVector3D>()(f,v0.bitangent);

        for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
            res.texcoords[i] = op<ai_real,aiVector3D,aiVector3D>()(f,v0.texcoords[i]);
        }
        for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS; ++i) {
            res.colors[i] = op<ai_real,aiColor4D,aiColor4D>()(f,v0.colors[i]);
        }
        return res;
    }

public:

    aiVector3D position;
    aiVector3D normal;
    aiVector3D tangent, bitangent;

    aiVector3D texcoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
    aiColor4D colors[AI_MAX_NUMBER_OF_COLOR_SETS];
};



// ------------------------------------------------------------------------------------------------
AI_FORCE_INLINE Vertex operator + (const Vertex& v0,const Vertex& v1) {
    return Vertex::BinaryOp<std::plus>(v0,v1);
}

AI_FORCE_INLINE Vertex operator - (const Vertex& v0,const Vertex& v1) {
    return Vertex::BinaryOp<std::minus>(v0,v1);
}


// ------------------------------------------------------------------------------------------------
/*
AI_FORCE_INLINE Vertex operator + (const Vertex& v0,ai_real f) {
    return Vertex::BinaryOp<Intern::plus>(v0,f);
}

AI_FORCE_INLINE Vertex operator - (const Vertex& v0,ai_real f) {
    return Vertex::BinaryOp<Intern::minus>(v0,f);
}

*/

AI_FORCE_INLINE Vertex operator * (const Vertex& v0,ai_real f) {
    return Vertex::BinaryOp<Intern::multiplies>(v0,f);
}

AI_FORCE_INLINE Vertex operator / (const Vertex& v0,ai_real f) {
    return Vertex::BinaryOp<Intern::multiplies>(v0,1.f/f);
}

// ------------------------------------------------------------------------------------------------
/*
AI_FORCE_INLINE Vertex operator + (ai_real f,const Vertex& v0) {
    return Vertex::BinaryOp<Intern::plus>(f,v0);
}

AI_FORCE_INLINE Vertex operator - (ai_real f,const Vertex& v0) {
    return Vertex::BinaryOp<Intern::minus>(f,v0);
}
*/

AI_FORCE_INLINE Vertex operator * (ai_real f,const Vertex& v0) {
    return Vertex::BinaryOp<Intern::multiplies>(f,v0);
}

/*
AI_FORCE_INLINE Vertex operator / (ai_real f,const Vertex& v0) {
    return Vertex::BinaryOp<Intern::divides>(f,v0);
}
*/

}
#endif
