#version 430

uniform mat4 projectionMatrix;
uniform mat4 projectionInvMatrix;

uniform mat4 projSecond;
uniform mat4 projInvSecond;

uniform mat4 viewMatrix;
uniform mat4 viewSecond;
uniform mat4 viewInvSecond;

uniform float g_time;

#define PI 3.141592

vec2 rotateXY2(vec2 p, float a) {
  vec2 r = p;
  r.x = cos(a)*p.x - sin(a)*p.y;
  r.y = sin(a)*p.x + cos(a)*p.y;
  return r;
}



uniform float shadowZOfs = -150.0;
uniform float shadowZScale = -5.0;


out float br;




void main() {
    vec4 vp = vec4(0.0);

    float id = float(gl_VertexID);

    float id3 = fract(id/3.0)*3.0; // index of the vertex in a triangle 0,1,2
    float idv = floor((id/3.0-fract(id/3.0))+0.5); // triangle index 0,1,2,3,...
    float idv2 = fract(idv/2.0)*2.0; // every second triangle 0 and 1
    float idq = floor((id/6.0-fract(id/6.0))+0.5); // quad index 0,1,2,3,...

    if (idv2 < 0.5) {
        if (id3 < 0.50) {
            vp = vec4(0.0, 0.0, 0.0, 1.0);
        } else if (id3 < 1.5) {
            vp = vec4(1.0, 0.0, 0.0, 1.0);
        } else if (id3 < 2.5) {
            vp = vec4(0.0, 1.0, 0.0, 1.0);
        }
    } else {
        if (id3 < 0.50) {
            vp = vec4(1.0, 0.0, 0.0, 1.0);
        } else if (id3 < 1.5) {
            vp = vec4(1.0, 1.0, 0.0, 1.0);
        } else if (id3 < 2.5) {
            vp = vec4(0.0, 1.0, 0.0, 1.0);
        }
    }

    br = 1.0;

    // cube
    if (idq < 0.5) {
    } else if (idq < 1.5) {
        vp.z += 1.0;
        br = 1.0;
    } else if (idq < 2.5) {
        vp.xz = rotateXY2(vp.xz, PI*0.5);
        br = 0.5;
    } else if (idq < 3.5) {
        vp.yz = rotateXY2(vp.yz, PI*0.5);
        br = 0.25;
    } else if (idq < 4.5) {
        vp.xz = rotateXY2(vp.xz, PI*0.5);
        vp.x += 1.0;
        br = 0.5;
    } else if (idq < 5.5) {
        vp.yz = rotateXY2(vp.yz, PI*0.5);
        vp.y += 1.0;
        br = 0.25;
    }
    vp.xyz -= vec3(0.5);
    //vp.xyz *= 1.0;

    vp.z += 0.0;
    vp.xy *= 2.0;



    // int zLevel = int(shadowZOfs+pkvLi.z*shadowZScale);

    //shadowZOfs + zStart*shadowZScale = 0.0
    // ->
    float zStart = -shadowZOfs/shadowZScale;
    vec4 vps = vec4(0.0, 0.0, zStart, 1.0);
    vps = projectionMatrix*vps;

    //shadowZOfs + zEnd*shadowZScale = 255.0
    float zEnd = (255.0-shadowZOfs)/shadowZScale;
    vec4 vpe = vec4(0.0, 0.0, zEnd, 1.0);
    vpe = projSecond*vpe;


    vps /= vps.w;
    vpe /= vpe.w;

    if (vp.z < 0.4) {
        vp.z = vps.z;
    } else {
        vp.z = vpe.z;
    }
    //vp.z -= 0.750;

    vp = projInvSecond*vp;
    //vp /= vp.w;
   // vp.w = 0.0;

    vp = viewInvSecond*vp;

    //vp /= vp.w;


    vp = projectionMatrix*viewMatrix*vp;
    //vp = *vp;

//    vp.xyz /= vp.w;

    gl_Position = vp;
}
