#ifndef __BNE_ANIMATION_EVENT_H__
#define __BNE_ANIMATION_EVENT_H__

#include "Utils/CasualCoreCandidates.h"
#include <CasualCore/Graphics/ParticleManager.h>
#include <RKPersistenceBase.h>

namespace bne {

  ///*******************************************************************
  /// \brief    Animation event description
  ///*******************************************************************
  class AnimationEventBase : public RKPersistBase
  {
  public:
    IGNORE_REFRESH_MEMBER_EVENTS()
    inline RKNamedObject* GetEventObject() const        { return m_pEventObject; }
    inline const RKString& AttachmentBoneName() const   { return m_attachmentBoneName; }

    RKNamedObject* m_pEventObject = nullptr;            //< The event object triggered from animation
    RKString       m_attachmentBoneName;                //< The animation bone name to attach the model to
  };

  ///*******************************************************************
  /// \brief    Animation event PFX description
  ///*******************************************************************
  class AnimationPfxDesc : public AnimationEventBase
  {
    DECLARE_SERIALIZED_BASE(AnimationPfxDesc);
  public:
    inline RKString GetPFXName() const { return (m_pParticleEmitterType != nullptr) ? m_pParticleEmitterType->GetName() : RKString(); }

    CasualCore::ParticleEmitterType* m_pParticleEmitterType = nullptr;    //< The link to the particle emitter to use
  };

  ///*******************************************************************
  /// \brief    Animation event mesh description
  ///*******************************************************************
  class AnimationObjectDesc : public AnimationEventBase
  {
    DECLARE_SERIALIZED_BASE(AnimationObjectDesc);
  public:
    inline const RKString& ObjectTemplateName() const   { return m_objectTemplateName; }
    inline bool IsShown() const                         { return m_bShow; }
    
    RKString m_objectTemplateName;                      //< Name of the template object
    RKString m_objectAnimationName;                     //< Name of the animation to play
    bool     m_bShow = true;                            //< Denotes if the model should be shown (true) or hidden (false)
  };

  ///*******************************************************************
  /// \brief    Animation event SFX description
  ///*******************************************************************
  class AnimationSfxDesc : public AnimationEventBase
  {
    DECLARE_SERIALIZED_BASE(AnimationSfxDesc);
  public:
    inline RKString GetSFXName() const  { return m_sfxName; }
    inline uint32 GetFadeTime() const   { return m_fadeTime; }
    inline bool IsStart() const         { return m_bPlay; }

    // TODO: add separate fade time for in / out

    RKString  m_sfxName;          //< Name of the SFX
    uint32    m_fadeTime  = 0;    //< The fade in/out duration
    bool      m_bPlay     = true; //< Denotes if the SFX should be started (true) or stopped (false)
  };

  struct AnimationEventsDesc
  {
    RKList<AnimationPfxDesc>    m_animationPFXs;        //< The PFX animation events
    RKList<AnimationObjectDesc> m_animationObjects;     //< The objects animation events
    RKList<AnimationSfxDesc>    m_animationSFXs;        //< The SFX animation events
  };

} // namespace bne

#endif //__BNE_ANIMATION_EVENT_H__
