using NixUniversalSDK;
using Windows.UI;

namespace NixExampleWinUI.Helpers;

/// <summary>
/// Helper functions related to <see cref="Windows.UI.Color"/>
/// </summary>
public static class ColorHelper
{
    /// <summary>
    /// Gets a <see cref="Color"/> instance based on the sRGB representation of <see cref="IColorData"/>
    /// </summary>
    /// <param name="data"><see cref="IColorData"/> to interpret</param>
    /// <param name="alpha">Alpha value for rendered color</param>
    /// <returns></returns>
    public static Color GetUiColor(this IColorData data, byte alpha = 255)
    {
        var rgb = data.RgbValue;
        return Windows.UI.Color.FromArgb(
            a: alpha,
            r: rgb[0],
            g: rgb[1],
            b: rgb[2]);
    }

    /// <summary>
    /// Evaluates if a <see cref="Color"/> value provides a 'light' or 'dark' background, useful for determining text overlay color
    /// </summary>
    public static bool? IsDark(this Color? color)
    {
        if (color is null) { return null; }

        // Convert input color sRGB to linear RGB
        var rgbLinear = new double[3];
        for (var i = 0; i < rgbLinear.Length; i++)
        {
            var c = i switch
            {
                0 => color?.R ?? 0.0,
                1 => color?.G ?? 0.0,
                2 => color?.B ?? 0.0,
                _ => 0.0
            };
            c /= 255.0;
            if (c <= 0.03928)
            {
                c /= 12.92;
            }
            else
            {
                c = Math.Pow((c + 0.055) / 1.055, 2.4);
            }
            rgbLinear[i] = c;
        }

        // Compute luminance
        var l = 0.2126 * rgbLinear[0] + 0.7152 * rgbLinear[1] + 0.0722 * rgbLinear[2];

        // If l is low, this color is dark
        return l <= 0.179;

    }

    /// <summary>
    /// Gets text overlay color for a provided background <see cref="Color"/> value
    /// </summary>
    /// <param name="color"></param>
    /// <returns></returns>
    public static Color GetOverlayUiColor(this Color? color)
    {
        if (color.IsDark() == true) 
        {
            return Microsoft.UI.Colors.White;
        }
        else
        {
            return Microsoft.UI.Colors.Black;
        }
    }
}