UI/GameMenu/Word/GameWord.razor
@using Sandbox;
@using Sandbox.UI;
@using System;
@attribute [StyleSheet]

@namespace GuessIt

<root>
    @if (string.IsNullOrEmpty(Override))
    {
        <div class="header">@Header</div>
    }
    else
    {
        <div class="override">@Override</div>
    }
    <div @ref="WordContainer" class="word @WordClasses()">
    </div>
</root>

@code
{
    Panel WordContainer { get; set; }
    string Override = "";
    string Header = "Guess the following:";
    string Word = "BUCKAROO";

    public void SetOverride(string over)
    {
        Override = over;
        Word = "";

        foreach (var child in WordContainer.Children)
        {
            child.Delete();
        }

        StateHasChanged();
    }

    public void SetWord(string word, string header = "Guess the following:", bool visible = false)
    {
        Override = "";
        Word = word;
        Header = header;

        StateHasChanged();

        foreach (var child in WordContainer.Children)
        {
            child.Delete();
        }

        for (int i = 0; i < Word.Length; i++)
        {
            var letter = Word[i];
            var letterPanel = WordContainer.AddChild<GameLetter>();
            letterPanel.Style.AnimationDelay = 0.08f * i;
            letterPanel.Letter = letter.ToString();
            // check if letter is alphanumeric
            if (!Char.IsLetterOrDigit(letter) || Char.IsSymbol(letter))
            {
                letterPanel.AddClass("symbol");
                letterPanel.Hidden = false;
            }
            if (visible) letterPanel.Hidden = false;
        }
    }

    public void RevealLetter()
    {
        if(!Networking.IsHost) return;

        List<GameLetter> visibleLetters = new();
        List<GameLetter> hiddenLetters = new();
        foreach (var child in WordContainer.Children)
        {
            if (child is GameLetter letter)
            {
                if (letter.Hidden)
                {
                    hiddenLetters.Add(letter);
                }
                else
                {
                    visibleLetters.Add(letter);
                }
            }
        }
        // Don't reveal if 30% or more is already visible
        if (visibleLetters.Count >= WordContainer.Children.Count() * 0.3f) return;
        if (hiddenLetters.Count == 0) return;
        var index = Random.Shared.Int(0, hiddenLetters.Count - 1);
        GameMenu.Instance.BroadcastRevealLetter(index);
    }

    public void RevealLetter(int index)
    {
        if (index < 0 || index >= WordContainer.Children.Count()) return;
        if (!(WordContainer.Children.ElementAt(index) is GameLetter letter)) return;
        letter.Hidden = false;
    }

    string WordClasses()
    {
        if (Word == "") return "hidden";
        return "";
    }

    protected override int BuildHash()
    {
        return HashCode.Combine(Override, Word, Header);
    }
}