#version 430 core

layout(std430, binding = 0) buffer SSBO
{
    vec3 values[100];
};



#pragma optionNV unroll all
#define MAX_LIGHTS 14
#define TMAX_LIGHTS 20
#define MAX_BONES 78

#define NUMLIGHTS 4

uniform sampler2D normalMap;

uniform mat4 ModelViewProjectionMatrix;
uniform mat4 ModelViewMatrix;
uniform mat3 NormalMatrix;

uniform float lightsPosx[MAX_LIGHTS];
uniform float lightsPosy[MAX_LIGHTS];
uniform float lightsPosz[MAX_LIGHTS];

out vec4 vpos; 

    out vec3 v;
    out vec3 N;
    out vec3 T;
    out vec3 B;

in vec3 vertexPosition;
in vec3 vertexNormal;
in vec2 textureCoord;
in vec3 vertexTangent;
in float vertexTangentHandedness;
in vec4 vertexBones;
in vec4 vertexWeights;

uniform mat4 depthBiasMVP[NUMLIGHTS];
out vec4 ShadowCoord[NUMLIGHTS];

uniform vec4 Lights[NUMLIGHTS];
uniform vec4 LightsPos[NUMLIGHTS];

out float ShadowAngle[NUMLIGHTS];
out vec4 vN_;
out vec4 vP_;



uniform int hasAnim[1];
uniform mat4 bonePos[MAX_BONES];
uniform mat4 boneRPos[MAX_BONES];
uniform mat4 boneRot[MAX_BONES];
uniform mat4 boneScl[MAX_BONES];

out vec3 alightVec[TMAX_LIGHTS];
out vec3 aeyeVec[TMAX_LIGHTS];
out vec2 texCoord;
uniform float lightsEnabled[MAX_LIGHTS];





vec3 tmpVec;

void main(void)
{
vec4 vP;
vec4 vN;
vec4 vT;
vec4 vPa[4];
vec4 vNa[4];
vec4 vTa[4];
	
	
	
	vP=vec4(vertexPosition.xyz, 1.0);
	vN=vec4(vertexNormal.xyz, 1.0);
	vT=vec4(vertexTangent.xyz, 1.0);
    

vN_=vN;
vP_=vP;


	if (hasAnim[0]>0){
        if (vertexBones.x>=0){

            vPa[0]=vP;
            vPa[0].x-=bonePos[int(vertexBones.x)][0][3];
            vPa[0].y-=bonePos[int(vertexBones.x)][1][3];
            vPa[0].z-=bonePos[int(vertexBones.x)][2][3];
            vPa[0]=boneRot[int(vertexBones.x)]*vPa[0];
            vPa[0].x+=bonePos[int(vertexBones.x)][0][3];
            vPa[0].y+=bonePos[int(vertexBones.x)][1][3];
            vPa[0].z+=bonePos[int(vertexBones.x)][2][3];
            vPa[0].x+=boneRPos[int(vertexBones.x)][0][3];vPa[0].y+=boneRPos[int(vertexBones.x)][1][3];vPa[0].z+=boneRPos[int(vertexBones.x)][2][3];

            vNa[0]=vN;
            vNa[0]=boneRot[int(vertexBones.x)]*vNa[0];
            
            

            vTa[0]=vT;
            vTa[0]=boneRot[int(vertexBones.x)]*vTa[0];
            
            


            
            
            
        }
        if (vertexBones.y>=0){
            
            
            vPa[1]=vP;
            vPa[1].x-=bonePos[int(vertexBones.y)][0][3];
            vPa[1].y-=bonePos[int(vertexBones.y)][1][3];
            vPa[1].z-=bonePos[int(vertexBones.y)][2][3];
            vPa[1]=boneRot[int(vertexBones.y)]*vPa[1];
            vPa[1].x+=bonePos[int(vertexBones.y)][0][3];
            vPa[1].y+=bonePos[int(vertexBones.y)][1][3];
            vPa[1].z+=bonePos[int(vertexBones.y)][2][3];
            vPa[1].x+=boneRPos[int(vertexBones.y)][0][3]; vPa[1].y+=boneRPos[int(vertexBones.y)][1][3]; vPa[1].z+=boneRPos[int(vertexBones.y)][2][3];

            vNa[1]=vN;
            vNa[1]=boneRot[int(vertexBones.y)]*vNa[1];
            
            

            vTa[1]=vT;
            vTa[1]=boneRot[int(vertexBones.y)]*vTa[1];
            
            

        }
        if (vertexBones.z>=0){
            
            
            vPa[2]=vP;
            vPa[2].x-=bonePos[int(vertexBones.z)][0][3];
            vPa[2].y-=bonePos[int(vertexBones.z)][1][3];
            vPa[2].z-=bonePos[int(vertexBones.z)][2][3];
            vPa[2]=boneRot[int(vertexBones.z)]*vPa[2];
            vPa[2].x+=bonePos[int(vertexBones.z)][0][3];
            vPa[2].y+=bonePos[int(vertexBones.z)][1][3];
            vPa[2].z+=bonePos[int(vertexBones.z)][2][3];
            vPa[2].x+=boneRPos[int(vertexBones.z)][0][3];vPa[2].y+=boneRPos[int(vertexBones.z)][1][3];vPa[2].z+=boneRPos[int(vertexBones.z)][2][3];

            vNa[2]=vN;
            vNa[2]=boneRot[int(vertexBones.z)]*vNa[2];
            
            

            vTa[2]=vT;
            vTa[2]=boneRot[int(vertexBones.z)]*vTa[2];
            
            
        }
        if (vertexBones.w>=0){
            
            
            vPa[3]=vP;
            vPa[3].x-=bonePos[int(vertexBones.w)][0][3];
            vPa[3].y-=bonePos[int(vertexBones.w)][1][3];
            vPa[3].z-=bonePos[int(vertexBones.w)][2][3];
            vPa[3]=boneRot[int(vertexBones.w)]*vPa[3];
            vPa[3].x+=bonePos[int(vertexBones.w)][0][3];
            vPa[3].y+=bonePos[int(vertexBones.w)][1][3];
            vPa[3].z+=bonePos[int(vertexBones.w)][2][3];
            vPa[3].x+=boneRPos[int(vertexBones.w)][0][3];vPa[3].y+=boneRPos[int(vertexBones.w)][1][3]; vPa[3].z+=boneRPos[int(vertexBones.w)][2][3];

            vNa[3]=vN;
            vNa[3]=boneRot[int(vertexBones.w)]*vNa[3];
            
            

            vTa[3]=vT;
            vTa[3]=boneRot[int(vertexBones.w)]*vTa[3];
            
            
        }

        vP=vPa[0]*vertexWeights.x+vPa[1]*vertexWeights.y+vPa[2]*vertexWeights.z+vPa[3]*vertexWeights.w;
        vN=vNa[0]*vertexWeights.x+vNa[1]*vertexWeights.y+vNa[2]*vertexWeights.z+vNa[3]*vertexWeights.w;
        vN=vec4(vN.xyz, 1.0);
        vT=vTa[0]*vertexWeights.x+vTa[1]*vertexWeights.y+vTa[2]*vertexWeights.z+vTa[3]*vertexWeights.w;
        vT=vec4(vT.xyz, 1.0);
	}

    
    gl_Position = ModelViewProjectionMatrix * vec4(vP.xyz, 1.0f); 

    


 




vpos=ModelViewMatrix * vec4(vP.xyz, 1.0f);


for (int i=0;i<NUMLIGHTS;i++){
    ShadowCoord[i] = depthBiasMVP[i] * vec4(vP.xyz, 1.0f);
}

    texCoord = textureCoord;

	
	vec3 n = normalize(NormalMatrix * vec3(vN.x,vN.y,vN.z));
	vec3 t = normalize(NormalMatrix * vec3(vT.x,vT.y,vT.z));
	
	
	
	


	vec3 b = cross(n, t) * vertexTangentHandedness;
    
	
	

	
	vec3 vVertex = vec3(ModelViewMatrix * vec4(vP.xyz, 1.0));

    
    
    

    
for (int i=0;i<NUMLIGHTS;i++){
    ShadowAngle[i] = dot(normalize(vec3(Lights[i].xyz)),n);
}

for (int i=0; i<2; i++)
   {
	//if (lightsEnabled[i]>0.0)
	{
    //float x=0,y=0,z=0;
    //tmpVec = vec3(x,y,z) - vVertex;
    tmpVec = vec3(lightsPosx[i],lightsPosy[i],lightsPosz[i]) - vVertex;
	alightVec[i].x = dot(tmpVec, t);
	alightVec[i].y = dot(tmpVec, b);
	alightVec[i].z = dot(tmpVec, n);
    //values[i]=vec3(x,y,z);
    /*
	tmpVec = -vVertex;
	aeyeVec[i].x = dot(tmpVec, t);
	aeyeVec[i].y = dot(tmpVec, b);
	aeyeVec[i].z = dot(tmpVec, n);
    */
	}
   }
   
for (int i=0; i<1; i++) //100 /// removed beacuse ssbo stuff is not working at all and alightVec is calculated in fragment shader
   {
	//if (lightsEnabled[i]>0.0)
	{
    uint x1 = uint(texture(normalMap,vec2(float(i*18+0)*(1.0/2048.0),0.0)).r*255.0);
    uint x2 = uint(texture(normalMap,vec2(float(i*18+1)*(1.0/2048.0),0.0)).r*255.0);
    uint x3 = uint(texture(normalMap,vec2(float(i*18+2)*(1.0/2048.0),0.0)).r*255.0);
    uint x4 = uint(texture(normalMap,vec2(float(i*18+3)*(1.0/2048.0),0.0)).r*255.0);
    uint y1 = uint(texture(normalMap,vec2(float(i*18+4)*(1.0/2048.0),0.0)).r*255.0);
    uint y2 = uint(texture(normalMap,vec2(float(i*18+5)*(1.0/2048.0),0.0)).r*255.0);
    uint y3 = uint(texture(normalMap,vec2(float(i*18+6)*(1.0/2048.0),0.0)).r*255.0);
    uint y4 = uint(texture(normalMap,vec2(float(i*18+7)*(1.0/2048.0),0.0)).r*255.0);
    uint z1 = uint(texture(normalMap,vec2(float(i*18+8)*(1.0/2048.0),0.0)).r*255.0);
    uint z2 = uint(texture(normalMap,vec2(float(i*18+9)*(1.0/2048.0),0.0)).r*255.0);
    uint z3 = uint(texture(normalMap,vec2(float(i*18+10)*(1.0/2048.0),0.0)).r*255.0);
    uint z4 = uint(texture(normalMap,vec2(float(i*18+11)*(1.0/2048.0),0.0)).r*255.0);
    uint intx = (x1 << 24) | (x2 << 16) | (x3 << 8) | x4;
    float x = uintBitsToFloat(intx);
    uint inty = (y1 << 24) | (y2 << 16) | (y3 << 8) | y4;
    float y = uintBitsToFloat(inty);
    uint intz = (z1 << 24) | (z2 << 16) | (z3 << 8) | z4;
    float z = uintBitsToFloat(intz);
    //float x=0,y=0,z=0;
    //tmpVec = vec3(lightsPosx[i],lightsPosy[i],lightsPosz[i]) - vVertex;
    tmpVec = vec3(x,y,z) - vVertex;
    vec3 alightVec_;
	alightVec_.x = dot(tmpVec, t);
	alightVec_.y = dot(tmpVec, b);
	alightVec_.z = dot(tmpVec, n);
    values[i]=alightVec_;//vec3(x,y,z);
	}
   }
   
   
    v=vVertex;
    N=normalize(n);
    T=normalize(t);
    B=normalize(b);
}
