namespace pdinklag.CPW.Common
{
    /// <summary>
    /// Interface for weapons.
    /// </summary>
    public interface IWeapon
    {
        /// <summary>
        /// Access to the weapon prefab component.
        /// </summary>
        /// <value></value>
        WeaponPrefab Prefab { get; }

        /// <summary>
        /// Attempts to get the weapon's main-hand target, if any.
        /// </summary>
        /// <param name="target">the main-hand target; only valid if the result is true</param>
        /// <returns></returns>
        bool TryGetMainHandTarget(ITargetContext ctx, out ITarget target);

        /// <summary>
        /// Attempts to get the weapon's off-hand target, if any.
        /// </summary>
        /// <param name="target">the off-hand target; only valid if the result is true</param>
        /// <returns></returns>
        bool TryGetOffHandTarget(ITargetContext ctx, out ITarget target);

        /// <summary>
        /// The weapon type.
        /// </summary>
        WeaponType Type { get; }

        /// <summary>
        /// Does this weapon need both hands to be carried?
        /// </summary>
        bool NeedsBothHandsToCarry { get; }

        /// <summary>
        /// Adds a script to the weapon.
        /// </summary>
        /// <typeparam name="T">the script type</typeparam>
        /// <returns>the added script instance</returns>
        T AddScript<T>() where T : WeaponScript, new();

        /// <summary>
        /// Removes a script from the weapon.
        /// 
        /// If the script was ever added to the weapon, its <cref="WeaponScript.OnDestroy"/> method will be called.
        /// </summary>
        /// <param name="script">the script to remove</param>
        /// <typeparam name="T">the script type</typeparam>
        /// <returns><c>true</c> if the script has actually been removed</returns>
        bool RemoveScript<T>(T script) where T : WeaponScript, new();
    }
}
