// https://iquilezles.org/articles/distfunctions2d/
float sdRoundedBox( in vec2 p, in vec4 b, in float r )
{
    vec2 q = abs(p-b.xy)-b.zw+r;
    return min(max(q.x,q.y),0.0) + length(max(q,0.0)) - r;
}

float sdRoundedBox( in vec2 p, in vec2 bl, in vec2 tr, in float r )
{
    vec2 c = (bl+tr)*0.5;
    vec2 s = (tr-bl)*0.5;
    vec2 q = abs(p-c)-s+r;
    return min(max(q.x,q.y),0.0) + length(max(q,0.0)) - r;
}

// https://www.shadertoy.com/view/4djSRW
float hash12(vec2 p)
{
	vec3 p3  = fract(vec3(p.xyx) * .1031);
    p3 += dot(p3, p3.yzx + 33.33);
    return fract((p3.x + p3.y) * p3.z);
}

float hash13(vec3 p3)
{
	p3  = fract(p3 * .1031);
    p3 += dot(p3, p3.zyx + 31.32);
    return fract((p3.x + p3.y) * p3.z);
}

// https://www.shadertoy.com/view/ldKGRR
float D(vec2 p, float n) {  // display digit
    int i=int(p.y), b=int(exp2(floor(30.-p.x-n*3.)));
    i = ( p.x<0.||p.x>3.? 0:
                         //  0   1   2   3   4   5   6   7   8   9
        i==5? 973012991: // 111 001 111 111 101 111 111 111 111 111  /* old style 4==972980223 */
        i==4? 690407533: // 101 001 001 001 101 100 100 001 101 101
        i==3? 704642687: // 101 001 111 111 111 111 111 001 111 111
        i==2? 696556137: // 101 001 100 001 001 001 101 001 101 001
        i==1? 972881535: // 111 001 111 111 001 111 111 001 111 111
    0 )/b;
 	return float(i-i/2*2);
}

float N(vec2 p, float v) {  // display number
    for (float n=1.; n>=0.; n--)  // print digit 1 to 0 ( negative = fractionals )
        if ((p.x-=4.)<3.) return D(p,floor(mod(v/pow(10.,n),10.)));
    return 0.;
}
// Fork of "[zznewclear13] Digital Clock" by zznewclear13. https://shadertoy.com/view/stdGRH
// 2023-02-24 00:57:24

// A digital clock (only shows minutes and seconds)
// Inspired by https://www.shadertoy.com/view/Mt3XW8
// Some functions are borrowed from iq, Dave_Hoskins, and FabriceNeyret2 (see Common tab)

// I want a 4 like this, Fabrice please help!
//
//   1   1
//   1   1
//   1 1 1
//       1
//       1

#define GRID_COUNT_Y 18.0
#define ACTIVE_TIME 0.3
#define TWELVE_HOUR_MODE   true
#define PI (2.0*3.141592653589793238)

vec3 hueToRGB(float h, float s, float l)
{
    h = mod(h,360.0);
    h = h / 60.0;
    float c = (1.0 - abs(2.0 * l - 1.0)) * s;
    float x = c * (1.0 - abs(mod(h, 2.0) - 1.0));
    vec3 rgb;
    if(h <= 1.0)
        rgb = vec3(c, x, 0.0);
    else if(h <= 2.0)
        rgb = vec3(x, c, 0.0);
    else if(h <= 3.0)
        rgb = vec3(0.0, c, x);
    else if(h <= 4.0)
        rgb = vec3(0.0, x, c);
    else if(h <= 5.0)
        rgb = vec3(x, 0.0, c);
    else if(h <= 6.0)
        rgb = vec3(c, 0.0, x);

    float m = l - 0.5 * c;

    return rgb + m;
}

float getTimeDigits(vec2 blockIndex, float dateW)
{
    float n = 0.0f;

    // make colons
    if(abs(blockIndex.y-0.5f)==1.0f &&
            (blockIndex.x==5.5f || blockIndex.x==-4.5f) ) n=1.0f;

    // hours
    blockIndex += vec2(17.0f, 3.0f);
    float hours = floor(dateW/3600.0);
    if(TWELVE_HOUR_MODE) {
        if(hours>12.0) {
            hours-= 12.0;
        } else if (hours==0.0) {
            hours = 12.0;
        }
    }
    n += N(blockIndex, hours);

    //minutes
    blockIndex -= vec2(10.0f, 0.0f);
    float minutes = mod(dateW, 3600.0f) / 60.0f;
    n += N(blockIndex, minutes);

    //seconds
    blockIndex -= vec2(10.0f, 0.0f);
    float seconds = mod(dateW, 60.0f);
    n += N(blockIndex, seconds);

    return n;
}

vec3 renderBlock(vec2 blockUV, vec3 colorTop, vec3 colorBottom, float invPixelCountY, float progress)
{
    vec4 box1Params = vec4(0.05f, 0.05f, 0.95f, 0.95f);
    float box1Radius = 0.05f;
    float sdfBox1 = sdRoundedBox(blockUV, box1Params.xy, box1Params.zw, box1Radius);
    float box1 = smoothstep(0.0f, 1.5f * invPixelCountY, sdfBox1);

    float sinVal = sin(progress * 1.5708);
    float cosVal = cos(progress * 1.5708);
    float seperatorThickness = 0.06f;
    float seperator = (1.0f - seperatorThickness * 0.5f) - sinVal * (1.0f - seperatorThickness);

    float minMargin = 0.01f;
    float maxMargin = 0.05f;
    float sideMargin = 0.04f;
    float bottomMargin = minMargin;
    float topMargin = minMargin;

    // bottom
    vec4 box2Params = vec4(0.05f + minMargin, 0.05f + bottomMargin,
                            0.95f - sideMargin, seperator-seperatorThickness*0.5f);
    float box2Radius = 0.05f;
    float sdfBox2 = sdRoundedBox(blockUV, box2Params.xy, box2Params.zw, box2Radius);
    float box2 = smoothstep(0.0f, 1.5f * invPixelCountY, sdfBox2);

    // top
    vec4 box3Params = vec4(0.05f + minMargin, seperator+seperatorThickness*0.5f,
                            0.95f - sideMargin, 0.95f-topMargin);
    float box3Radius = 0.05f;
    float sdfBox3 = sdRoundedBox(blockUV, box3Params.xy, box3Params.zw, box3Radius);
    float box3 = smoothstep(0.0f, 1.5f * invPixelCountY, sdfBox3);


    vec2 lightSource = normalize(vec2(0.5, 2.0f));
    // background
    vec3 color0 = vec3(0.40f, 0.40f, 0.20f);
    // edge
    vec3 color1 = vec3(0.95f, 0.95f, 0.85f) * lightSource.y;
    // bottom
    vec3 color2 = colorBottom * (dot(lightSource, vec2(cosVal, -sinVal)) * 0.3f + 0.7f);
    // top
    vec3 color3 = colorTop * (dot(lightSource, vec2(sinVal, cosVal)) * 0.3f + 0.7f);

    vec3 color = mix(color1, color0, box1);
    color = mix(color2, color, box2);
    color = mix(color3, color, box3);
    return color;
}

void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
    vec2 pixelCount = iResolution.yy / GRID_COUNT_Y;
    vec2 centerFragCoord = fragCoord+0.5f*pixelCount-(iResolution.xy)*0.5f;

    float invPixelCountY = 1.0f / pixelCount.y;
    ivec2 blockIndex = ivec2(floor(centerFragCoord * invPixelCountY));
    vec2 blockUV = mod(centerFragCoord, pixelCount) * invPixelCountY;

    float progress = 0.5f;
    // if(iMouse.z > 0.0f) {progress = 1.0f - fract(2.0f * iMouse.y / iResolution.y);}

    float floorTime = floor(iDate.w);
    float fractTime = fract(iDate.w);
    float inactive = 1.0f - ACTIVE_TIME;
    float randomVal = hash13(vec3(vec2(blockIndex), floorTime)) * inactive;

    float dateW = floorTime;
    progress = clamp((fractTime-randomVal) / ACTIVE_TIME, 0.0f, 1.0f);

    float d1 = getTimeDigits(vec2(blockIndex)+vec2(0.5f), dateW);
    float d2 = getTimeDigits(vec2(blockIndex)+vec2(0.5f), dateW+1.0f);

    vec3 colorBackground = vec3(0.95f, 0.95f, 0.85f);

    float time = mod(iTime*10.0,360.0);
    colorBackground = hueToRGB( time+(60.0*(fragCoord.y/iResolution.y)),
                          1.0, 0.7 );

    vec3 colorDigit = vec3(0.2f, 0.2f, 0.4f);
    vec3 color1 = mix(colorBackground, colorDigit, d1);
    vec3 color2 = mix(colorBackground, colorDigit, d2);
    vec3 color = renderBlock(blockUV, color2, color1, invPixelCountY, progress);

    fragColor = vec4(color, 1.0f);
}

