//
//  EditEnhance_f.shader
//  BeautyPlus
//
//  Created by Webster Wu on 2/18/16.
//  Copyright © 2016 美图网. All rights reserved.
//

#ifdef GL_ES//for discriminate GLES & GL
#ifdef GL_FRAGMENT_PRECISION_HIGH
precision highp float;
#else
precision mediump float;
#endif
#else
#define highp
#define mediump
#define lowp
#endif

varying highp vec2 texcoordOut;
uniform sampler2D inputImageTexture0;
uniform lowp vec3 redShift;
uniform lowp vec3 orangeShift;
uniform lowp vec3 yellowShift;
uniform lowp vec3 greenShift;
uniform lowp vec3 aquaShift;
uniform lowp vec3 blueShift;
uniform lowp vec3 purpleShift;
uniform lowp vec3 magentaShift;


const lowp vec3 lumCoeff=vec3(0.2125,0.7154,0.0721);

vec3 rgb2hsv(vec3 rgb)
{
float rc = rgb.r;
float gc = rgb.g;
float bc = rgb.b;

float h = 0.0;
float s = 0.0;
float v = 0.0;

float max_v = max(rc, max(gc, bc));
float min_v = min(rc, min(gc, bc));
float delta = max_v - min_v;

v = max_v;

if (max_v != 0.0) {
s = delta / max_v;
} else {
s = 0.0;
}

if (s == 0.0) {
h = 0.0;
} else {
if (rc == max_v) {
h = (gc - bc) / delta;
} else if (gc == max_v) {
h = 2.0 + (bc - rc) / delta;
} else if (bc == max_v) {
h = 4.0 + (rc - gc) / delta;
}

h *= 60.0;
if (h < 0.0) {
h += 360.0;
}
}

return vec3(h,s,v);

}


vec3 hsv2rgb(vec3 rgb)
{
float h, s,v;
float r, g, b;

h=rgb.r;
s=rgb.g;
v=rgb.b;
int i = 0;
float f, p, q, t;
if( s == 0.0 ) {
// achromatic (grey)
r = g = b = v;
} else {
h /= 60.0;            // sector 0 to 5
i = int(floor( h ));
f = h - float(i);            // factorial part of h
p = v * ( 1.0 - s );
q = v * ( 1.0 - s * f );
t = v * ( 1.0 - s * ( 1.0 - f ) );

if (i == 0) {
r = v;
g = t;
b = p;
} else if (i == 1) {
r = q;
g = v;
b = p;
} else if (i == 2) {
r = p;
g = v;
b = t;
} else if (i == 3) {
r = p;
g = q;
b = v;
} else if (i == 4) {
r = t;
g = p;
b = v;

} else {
r = v;
g = p;
b = q;
}
}
return vec3(r,g,b);
}

vec3 hueAdjust(vec3 hsb,vec3 maskHsb,float standHue,float deltaRange,vec3 hueParam,float offset)
{
if ((hueParam.x==0.0) &&(hueParam.y==0.0) &&(hueParam.z==0.0))
return hsb;
//hsb adjust
vec3 tmpHSB;
float fAlpha;
float standHue0,minHue,maxHue,currHue;
//Red
hueParam.x=hueParam.x*30.0/100.0;
hueParam.y=hueParam.y*0.8/100.0;
hueParam.z=hueParam.z/100.0;

//init data
standHue0=standHue+offset;
minHue=standHue0-deltaRange;
maxHue=standHue0+deltaRange;
tmpHSB=hsb;
//check range

if (offset>0.0)
{
if (maskHsb.r>180.0)
currHue=maskHsb.r-360.0+offset;
else
currHue=maskHsb.r+offset;
}
else
currHue=maskHsb.r;
if ((currHue>=minHue) && (currHue <= maxHue))
{
//get alpha
fAlpha=abs(currHue-standHue0);
//fAlpha=1.0-fAlpha/deltaRange;
fAlpha=1.0-fAlpha/deltaRange;

//hue
tmpHSB.x=hsb.r+hueParam.x*fAlpha;
if (tmpHSB.x>360.0)
tmpHSB.x=tmpHSB.x-360.0;
//saturation
tmpHSB.y=hsb.y+hsb.y*hueParam.y*fAlpha;
tmpHSB.y=clamp(tmpHSB.y,0.0,1.0);
//bright
tmpHSB.z=hsb.z+hsb.z*hsb.y*hueParam.z*fAlpha;


tmpHSB.z=clamp(tmpHSB.z,0.0,1.0);
}

return tmpHSB;
}

void main()
{
mediump vec3 clO,clA,clB,clC,clBlur,clTmp;
mediump float lum,fTmp,alpha;
mediump float result,base,blend;

mediump vec4 baseColor=texture2D(inputImageTexture0, texcoordOut);
clO=baseColor.rgb;
clA=clO;

//////////

mediump float fTmpGamma;
mediump float lumBlur=dot(clO,lumCoeff);
lumBlur=lumBlur*2.0-1.0;

if (lumBlur < 0.0)
{
fTmpGamma = pow(10.0, 0.0);
clA=vec3(1.0 - pow(vec3(1.0 - clO), vec3(fTmpGamma)));
}
else
{
fTmpGamma=pow(10.0, 0.0);
clA=pow(clO,vec3(fTmpGamma));
}
/////////////


vec3 hsb=rgb2hsv(clA);
    vec3 hsbGuass;

//hsb adjust
hsbGuass=hsb;
//red
hsb=hueAdjust(hsb,hsbGuass,0.0,30.0,redShift,360.0);
//orangeShift
hsb=hueAdjust(hsb,hsbGuass,15.0,30.0,orangeShift,360.0);
//yellowShift
hsb=hueAdjust(hsb,hsbGuass,50.0,50.0,yellowShift,0.0);
//greenShift
hsb=hueAdjust(hsb,hsbGuass,120.0,60.0,greenShift,0.0); // before standH=120.0
//aquaShift
hsb=hueAdjust(hsb,hsbGuass,180.0,20.0,aquaShift,0.0);
//blueShift
hsb=hueAdjust(hsb,hsbGuass,240.0,60.0,blueShift,0.0);
//purpleShift
hsb=hueAdjust(hsb,hsbGuass,300.0,40.0,purpleShift,0.0);
//magentaShift
hsb=hueAdjust(hsb,hsbGuass,330.0,20.0,magentaShift,0.0);


clA=hsv2rgb(hsb);
gl_FragColor=vec4(clA,baseColor.a);
}
