/***************************************************************************
*                                                                          *
*  Copyright (C) Golaem S.A.  All Rights Reserved.                         *
*                                                                          *
***************************************************************************/

#pragma once

//golaem motion includes
#include "glmMotionDefinitions.h"
#include "glmSDKAPI.h"
#include "glmSmartPointer.h"
#include <glmTypes.h>
#include <glmVector3.h>
#include <glmGolaemMotionDeclarations.h> // GolaemMotion declarations

namespace glm
{
    class GroundManager;
    class BlendTreePosture;

    /**
	* \brief Type of a target
	*/
    class OrientationTargetMode
    {
    public:
        enum Value
        {
            ABSOLUTE_ORIENTATION,
            ENTITY_RELATIVE_ORIENTATION,
            END
        };
    };

    /**
	 *
	 * \brief Describe an Orientation Constraint target
	 *
	 * \author dev@golaem.com
	 *
	 */
    class GLM_SDK_API OrientationTarget : public ReferenceCounter
    {
    public:
        GLM_CLASS_STAT_ID( glm::MemoryStatIds::Simulation);

        /// definition of a smart pointer on an instance of this class.
        typedef SmartPointer<OrientationTarget> SP;

    protected:
        /**
		 * \brief default constructor
		 */
        OrientationTarget(const Quaternion& orientation = Quaternion::getIdentity(), OrientationTargetMode::Value targetmode = OrientationTargetMode::ENTITY_RELATIVE_ORIENTATION);

    public:
        /**
		 * \brief Comparison operator
		 * \param otherInstance
		 * \return true if constraint sets are identical
		 */
        bool operator==(const OrientationTarget& otherInstance) const;

        /**
		 * \brief Comparison operator
		 * \param otherInstance
		 * \return true if constraint sets are identical
		 */
        bool operator!=(const OrientationTarget& otherInstance) const
        {
            return !((*this) == otherInstance);
        }

        /**
		 * \brief Instance Creator
		 */
        static OrientationTarget* create(const Quaternion& orientation = Quaternion::getIdentity(), OrientationTargetMode::Value targetmode = OrientationTargetMode::ENTITY_RELATIVE_ORIENTATION);
        //@}

        //************************************************************
        //! @name Validation and computation accessors
        //************************************************************
        //@{
        inline bool isValid() const;

        virtual Quaternion computeTargetOri(int64_t entityIndex, const BlendTreePosture& posture);
        //@}

    protected:
        Quaternion computeTargetOriInternal(const Quaternion& inOri, const BlendTreePosture& posture);

    protected:
        OrientationTargetMode::Value _targetMode;                            //!< see OrientationTargetMode for available values
        Quaternion _orientation;                                    //!< if _orientationTargetMode is POS LOCATOR or ORI LOCATOR, this represent the absolute position to be reached
    };

    //------------------------------------------------------------
    inline bool
    OrientationTarget::isValid() const
    {
        return _targetMode < OrientationTargetMode::END;
    }
} // namespace glm
