#pragma once

#ifdef GAMEQC
	#include <common/sounds/all.qh>
#endif
#ifndef SVQC
#include <common/util.qh> // for icon_path_from_HUDskin
#endif

REGISTRY(StatusEffects, 32)
REGISTER_REGISTRY(StatusEffects)
#define REGISTER_STATUSEFFECT(id, inst) REGISTER(StatusEffects, STATUSEFFECT, id, m_id, inst)

REGISTRY_SORT(StatusEffects)
REGISTRY_CHECK(StatusEffects)

REGISTRY_DEFINE_GET(StatusEffects, NULL)
STATIC_INIT(StatusEffects) { FOREACH(StatusEffects, true, it.m_id = i); }

enum
{
    STATUSEFFECT_FLAG_ACTIVE = BIT(0),
    STATUSEFFECT_FLAG_PERSISTENT = BIT(1) ///< Effect is currently being granted passively.
};

enum
{
    STATUSEFFECT_REMOVE_NORMAL,        ///< Effect is being removed by a function, calls regular removal mechanics.
    STATUSEFFECT_REMOVE_TIMEOUT,
    STATUSEFFECT_REMOVE_CLEAR          ///< Effect is being forcibly removed without calling any additional mechanics.
};

CLASS(StatusEffect, Object)
	ATTRIB(StatusEffect, m_id, int, 0);
	ATTRIB(StatusEffect, m_name, string);
	ATTRIB(StatusEffect, m_icon, string);
	ATTRIB(StatusEffect, m_color, vector, '1 1 1');
	/** Whether the effect is displayed in the HUD */
	ATTRIB(StatusEffect, m_hidden, bool, false);
	/** Lifetime scale for HUD progress bars */
	ATTRIB(StatusEffect, m_lifetime, float, 30);
#ifdef GAMEQC
	ATTRIB(StatusEffect, m_sound, Sound, SND_Null);
	ATTRIB(StatusEffect, m_sound_rm, Sound, SND_Null);
	METHOD(StatusEffect, m_tick, void(StatusEffect this, entity actor));
	METHOD(StatusEffect, m_active, bool(StatusEffect this, entity actor));
	/** Stores times of status effects, the id being the index */
	ATTRIBARRAY(StatusEffect, statuseffect_time, float, REGISTRY_MAX(StatusEffects));
	ATTRIBARRAY(StatusEffect, statuseffect_flags, int, REGISTRY_MAX(StatusEffects));
#endif
#ifdef SVQC
	METHOD(StatusEffect, m_apply, void(StatusEffect this, entity actor, float eff_time, int eff_flags));
	METHOD(StatusEffect, m_remove, void(StatusEffect this, entity actor, int removal_type));
	/** Sets the persistent flag and updates client side if returning true */
	METHOD(StatusEffect, m_persistent, bool(StatusEffect this, entity actor)) { return false; };
#endif
#ifndef SVQC
	METHOD(StatusEffect, display, void(StatusEffect this, void(string name, string icon) returns))
	{
		TC(StatusEffect, this);
		returns(this.m_name, icon_path_from_HUDskin(this.m_icon));
	}
#endif
ENDCLASS(StatusEffect)
