namespace HidSliders.Hid;

public class MixerButtonHelper
{
    public static List<MixerButton> GetSetFlags(long value)
    {
        var setFlags = new List<MixerButton>();
        foreach (MixerButton flag in Enum.GetValues(typeof(MixerButton)))
        {
            if ((value & (long)flag) == (long)flag)
            {
                setFlags.Add(flag);
            }
        }
        return setFlags;
    }

    public static ButtonGroups GetButtonGroup(MixerButton button)
    {
        var buttonValue = (long)button;

        if (((long)ButtonGroups.Channel1 & buttonValue) != 0) return ButtonGroups.Channel1;
        if (((long)ButtonGroups.Channel2 & buttonValue) != 0) return ButtonGroups.Channel2;
        if (((long)ButtonGroups.Channel3 & buttonValue) != 0) return ButtonGroups.Channel3;
        if (((long)ButtonGroups.Channel4 & buttonValue) != 0) return ButtonGroups.Channel4;
        if (((long)ButtonGroups.Channel5 & buttonValue) != 0) return ButtonGroups.Channel5;

        throw new ArgumentException("The provided button does not match any button group.", nameof(button));
    }

    public static ChannelButton GetChannelButton(MixerButton button)
    {
        return GetChannelButton(button, GetButtonGroup(button));
    }

    public static ChannelButton GetChannelButton(MixerButton button, ButtonGroups buttonGroup)
    {
        var longButton = (long)button;
        if (longButton >= 0x10000000000)
        {
            return ChannelButton.ChannelMute;
        }

        int intButton = 0;
        switch (buttonGroup)
        {
            case ButtonGroups.Channel1:
                intButton = (int)(longButton >> 0);
                break;
            case ButtonGroups.Channel2:
                intButton = (int)(longButton >> 8);
                break;
            case ButtonGroups.Channel3:
                intButton = (int)(longButton >> 16);
                break;
            case ButtonGroups.Channel4:
                intButton = (int)(longButton >> 24);
                break;
            case ButtonGroups.Channel5:
                intButton = (int)(longButton >> 32);
                break;
        }

        if (((int)ChannelButton.ChannelA1 & intButton) != 0) return ChannelButton.ChannelA1;
        if (((int)ChannelButton.ChannelA2 & intButton) != 0) return ChannelButton.ChannelA2;
        if (((int)ChannelButton.ChannelA3 & intButton) != 0) return ChannelButton.ChannelA3;
        if (((int)ChannelButton.ChannelA4 & intButton) != 0) return ChannelButton.ChannelA4;
        if (((int)ChannelButton.ChannelA5 & intButton) != 0) return ChannelButton.ChannelA5;
        if (((int)ChannelButton.ChannelB1 & intButton) != 0) return ChannelButton.ChannelB1;
        if (((int)ChannelButton.ChannelB2 & intButton) != 0) return ChannelButton.ChannelB2;
        if (((int)ChannelButton.ChannelB3 & intButton) != 0) return ChannelButton.ChannelB3;

        throw new ArgumentException("The provided button does not match any channel button in the specified button group.", nameof(button));
    }
}