UI/Player/PlayerStatusUI.razor
@using Sandbox
@using Sandbox.UI
@using Opium

@namespace Opium
@implements Opium.Actor.IEventListener
@inherits PanelComponent

<root>
    <div class="medkits @MedkitsClass()">
        <img class="icon" src="ui/HUD/health.png"/> 

        <img class="quadrant one @IsBlockActive( 0 )" src="ui/HUD/circle_quadrant.png" />
        <img class="quadrant two @IsBlockActive( 1 )" src="ui/HUD/circle_quadrant.png" />
        <img class="quadrant three @IsBlockActive( 2 )" src="ui/HUD/circle_quadrant.png" />
        <img class="quadrant four @IsBlockActive( 3 )" src="ui/HUD/circle_quadrant.png" />
    </div>

    @if ( !ShowMedkits )
    {
        <div class="hints" style="flex-direction: column; gap: 8px;">
            <div class="input">
                <label>@Input.GetButtonOrigin("Score")</label>
                <label class="small">View your objectives</label>
            </div>

            @if ( Player.PlayerInfo.HealthKits > 0 )
            {
                <div class="input">
                    <label>@Input.GetButtonOrigin("Heal")</label>
                    <label class="small">Use pile of meds</label>
                </div>
            }

            @*
            <div class="input">
                <label>@Input.GetButtonOrigin("Kick")</label>
                <label class="small">Kick someone</label>
            </div> *@
        </div>
    }

    
    @if (( TimeSinceDurabilityLost < 1f && durability <= 40) || (TimeSinceAmmoLost < 1f && ammo <= 0 ) )
    {
        <div class="durability_event">
        </div>
    }
</root>

@code
{
    /// <summary>
    /// The player
    /// </summary>
    public Opium.PlayerController Player => Components.Get<Opium.PlayerController>(FindMode.EverythingInSelfAndAncestors);

    public float HealthKitQuadrant => Player.PlayerInfo.HealthKits * 25f;
    public float HealthKits => Player.PlayerInfo.HealthKits;

    TimeSince TimeSinceMedkitsVisible { get; set; }

    [Property]
    public float MedkitFadeoutTime { get; set; } = 5f;

    bool showMedkits;
    bool ShowMedkits
    {
        get
        {
            return showMedkits;
        }
        set
        {
            if (showMedkits == value) return;

            showMedkits = value;

            if (showMedkits)
            {
                TimeSinceMedkitsVisible = 0;
            }
        }
    }

    string MedkitsClass()
    {
        return showMedkits ? "active" : "";
    }

    string IsBlockActive(int blockId)
    {
        var block = HealthKitQuadrant / 25f;
        block = block.CeilToInt();

        if (blockId < block) return "active";

        return "";
    }

    int lastMedkits = 0;
    float lastHealth = 100f;
    void UpdateMedkits()
    {
        // did the medkits change
        if (HealthKits != lastMedkits)
        {
            ShowMedkits = true;
            lastMedkits = HealthKits.CeilToInt();
        }

        if ( Player.Health != lastHealth )
        {
            ShowMedkits = true;
            lastHealth = Player.Health;
        }

        if (Input.Down("Score"))
        {
            ShowMedkits = true;
        }

        if (Input.Released("Score"))
        {
            ShowMedkits = false;
            TimeSinceMedkitsVisible = MedkitFadeoutTime - 1f;
        }

        if ( TimeSinceMedkitsVisible > MedkitFadeoutTime )
        {
            ShowMedkits = false;
        }
    }

    protected override void OnUpdate()
    {
        UpdateMedkits();
    }

    protected override int BuildHash()
    {
        return HashCode.Combine( Time.Delta );
    }

    string DurabilityClass()
    {
        return TimeSinceDurabilityLost < 1f && durability <= 100 ? "visible" : "";
    }


    float durability = 100f;
    TimeSince TimeSinceDurabilityLost = 100;

    float ammo = 100f;
    TimeSince TimeSinceAmmoLost = 100;

    [Property] SoundEvent DurabilitySound { get; set; }
    [Property] SoundEvent AmmoSound { get; set; }

    public void OnEvent( Opium.Actor actor, string eventName, params object[] objects )
    {
        if ( actor is not Opium.PlayerController player )
        {
            return;
        }

        if ( eventName == "durability_loss" )
        {
            TimeSinceDurabilityLost = 0;
            durability = (int)objects.First();

            if ( durability <= 0 )
            {
                actor.GameObject.PlaySound( DurabilitySound );
            }
        }


        if ( eventName == "ammo_loss" )
        {
            TimeSinceAmmoLost = 0;
            ammo = (int)objects.First();

            if ( ammo <= 0 )
            {
                actor.GameObject.PlaySound( AmmoSound );
            }
        }
    }
}