#ifndef _COLORWHEEL_FXH_
#define _COLORWHEEL_FXH_
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//  ColorWheel effect11 by kingeric1992
//                                  Nov.4.2017
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

static const float ColorWheel_mult = 0.1;

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//  internals
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

struct ColorWheelWeightStruct {
    float highlight, midtone, shadow, gain, gamma, lift;
};

//return [0,1] if within target range, otherwise return 0
ColorWheelWeightStruct ColorWheelWeight( float lum, float low, float high, float overlap) {
    ColorWheelWeightStruct o;
    float2 t;

    t.x = 1 - lum/(low + overlap);
    o.shadow = step(lum, low + overlap) * log2(t.x * t.x + 1.0);

    t  = float2(lum - low, high - lum) + overlap;
    t  = float2(t.x * t.y, 2.0 / ((high - low) + 2.0 * overlap));
    t *= t; 
    o.midtone = step(lum, high + overlap) * step(low - overlap, lum) * log2(t.x * t.y * t.y + 1.0);

    t    = float2(lum, 1.0) - high + overlap;
    t.x /= t.y;
    o.highlight = step(high - overlap, lum) * log2(t.x * t.x + 1.0);

    o.gain  = saturate(lum);
    o.lift  = saturate(1.0 - lum);
    o.gamma = o.gain * o.lift * 4.0;
    
    return o;
}

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//  export function
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

struct ColorWheelStruct {
    bool   State; 
    float  Weight;
    float  lowrange, highrange, overlap;
    float3 shadow, midtone, highlight, lift, gamma, gain, offset;
};

float3 ColorWheel(float3 col, ColorWheelStruct IN) 
{
    if(!IN.State) return col;
    ColorWheelWeightStruct w = ColorWheelWeight(saturate(dot(col, 0.3333)), IN.lowrange, IN.highrange, IN.overlap);

    col += (IN.shadow * w.shadow + IN.midtone * w.midtone + IN.highlight * w.highlight) * ColorWheel_mult;
    col += (IN.lift   * w.lift   + IN.gamma   * w.gamma   + IN.gain      * w.gain) * ColorWheel_mult;
    
    return max(col + IN.offset * ColorWheel_mult, 0.0);
}

#endif //_COLORWHEEL_FXH_