#ifndef __BNE_ANIMATED_EFFECT_OBJECT_H__
#define __BNE_ANIMATED_EFFECT_OBJECT_H__

#include "GameObjects/AnimationEvent.h"

#include <Graphics/Object.h>
#include "Utils/ChildObject.h"
#include "Utils/SoundEmulator.h"
#include "Utils/BNELibTypes.h"

static_assert(BNE_LIB_GLOBAL_TYPE_START == RKSERIAL_GLOBALTYPE_USERDEFINED + 2048, "Update lookup table values");

BEGIN_CUSTOMOBJECT(RKAnimEvent, RKGlobalType)
public:
  enum TYPE { GLOBALTYPE = bne::BNELIB_ANIMEVENT };

  RKAnimEvent()                                     { m_ObjectSubType = GLOBALTYPE; }
  const bne::AnimationEventsDesc& GetDesc() const   { return m_desc; }
private:
  //+ serialized data:
  bne::AnimationEventsDesc m_desc;
  //- serialized data:
END_CUSTOMOBJECT(RKAnimEvent)

namespace bne
{
  /// \brief  handler for events from animation
  /// \details capable of:
  ///          creating vfx attached to bones
  ///          creating other objects attached to bones
  ///          triggering attached objects visibility
  ///          play / pause SFX
  class AnimatedEffectObject
  {
  public:
    typedef CasualCore::Object*(PFXCallback)(const char *a_pfxName);
    typedef void CreateCallback(CasualCore::Object *a_pNewObject);

    AnimatedEffectObject();
    ~AnimatedEffectObject();

#if defined(BNE_OBJECT_CROSSOVER)
    void ClearData(bool bDestroyChildObject);
#else // (!)defined(BNE_OBJECT_CROSSOVER)
    void Clear();
#endif // defined(BNE_OBJECT_CROSSOVER)

    void SetParent(CasualCore::Object* a_pParent, PFXCallback *pCallback);
    void SetEffects(const AnimationEventsDesc* a_pDesc);
    void Update(float a_elapsedTime);
    void OnAnimEvent(const RKString* a_pHandle);
    void ReceiveEvent(int a_eventID, void* userData);

    void HideAnimationObjects();

    static void RegisterCreateCallback(CreateCallback *a_pCallback) { m_pCreateCallback = a_pCallback; }
  private:
    
    CasualCore::Object*         m_pParent = nullptr;        //!< The parrent object that plays animation
    const AnimationEventsDesc*  m_pDesc = nullptr;          //!< Events descriptor
    RKList<ChildObject<>>       m_animationEventObjects;    //!< The objects created for events

    struct SoundInfo
    {
      RKString m_sfxName;   //!< The name of the SFX
      SoundHandle m_handle; //!< The sound handle for the SFX
    };
    RKList<SoundInfo> m_sfxInfo;  //!< The SFXs currently being managed

  private:

    ChildObject<> CreateObject(const char* a_templateName);
    void CreateEffect(const char* a_templateName, const char* a_attachmentBoneName);
    PFXCallback *m_pParticleEffectCallback = nullptr;
    static CreateCallback *m_pCreateCallback;
  };

} // namespace bne

#endif //__BNE_ANIMATED_EFFECT_OBJECT_H__
