// Copyright (c) .NET Foundation and Contributors (https://dotnetfoundation.org/ & https://stride3d.net) and Silicon Studio Corp. (https://www.siliconstudio.co.jp)
// Distributed under the MIT license. See the LICENSE.md file in the project root for more information.
/// <summary>
/// Various helper functions to convert color between RGB and HSV.
/// </summary>
shader HSVUtils
{
    float GetSaturation(float3 tex)
    {
        float e = 1.0e-10;
        float maxChannel = max(max(tex.r, tex.g), tex.b);
        if(maxChannel < e)
            return 0.0f;
        else
            return 1.0f - min(min(tex.r, tex.g), tex.b) / maxChannel;
    }

    float GetValue(float3 tex)
    {
        return max(max(tex.r, tex.g), tex.b);
    }

    float GetHue(float3 tex)
    {
        float e = 1.0e-10;
        float maxChannel = max(max(tex.r, tex.g), tex.b);
        
        float delta = maxChannel - min(min(tex.r, tex.g), tex.b);
        if (delta < e)
            return 0.0f;
        if(maxChannel == tex.r)
        {
            return frac(1.0f + (tex.g - tex.b) / (6.0f * delta));
        }
        else if(maxChannel == tex.g)
        {
            return 1.0f / 3.0f + (tex.b - tex.r) / (6.0f * delta);
        }
        else 
        {
            return 2.0f / 3.0f + (tex.r - tex.g) / (6.0f * delta);
        }
    }
    /*
    float3 ToHSV(float3 tex)
    {
        return float3(GetHue(tex), GetSaturation(tex), GetValue(tex));
    }

    float3 ToRGB(float3 hsv)
    {

        float s = hsl[1];
        float v = hsl[2];

        if(s == 0)
            return float3(v);

        float h = hsl[0];

        int i = floor(h);
        float f = h - i;
        float p = v * (1.0f - s);
        float q = v * (1.0f - s * f);
        float t = v * (1.0f - s * (1.0f - f));

        switch(i)
        {
            case 0 :
                return float3(v, t, p);
            case 1 :
                return float3(q, v, p);
            case 2 :
                return float3(p, v, t);
            case 3 :
                return float3(p, q, v);
            case 4 :
                return float3(t, p, v);
            default :
                return float3(v, p, q);
        }
    }
    */
    // From http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
    float3 ToHSV(float3 color)
    {
        float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
        float4 p = lerp(float4(color.bg, K.wz), float4(color.gb, K.xy), step(color.b, color.g));
        float4 q = lerp(float4(p.xyw, color.r), float4(color.r, p.yzx), step(p.x, color.r));

        float d = q.x - min(q.w, q.y);
        float e = 1.0e-10;
        return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
    }
    
    float3 ToRGB(float3 color)
    {
        float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
        float3 p = abs(frac(color.xxx + K.xyz) * 6.0 - K.www);
        return color.z * lerp(K.xxx, saturate(p - K.xxx), color.y);
    }
    
};
