varying vec2 texCoord;
varying vec3 vNormal;
varying vec3 eyePos;

uniform float time;
uniform float strength;
uniform float speed;
uniform float deforming;
uniform float bending;
uniform float ground;
uniform vec2 direction;

uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;

// ########################################Settings########################################

vec2 windDirection = direction; // Direction of the wind
float windStrength = strength;  // Strength of the wind
float groundLevel = ground;     // Everything over ground level will have movement
const int windSamples = 3;      // Number of wind sine waves to add
// ########################################Functions########################################

vec2 getWind(vec4 worldPos, float height)
// Function to generate the wind
{
    vec2 wind;
    if (height > groundLevel)
    {
        float windTime = time*speed;
        float windDisplacement = cos(0.375*((17.5+worldPos.x)+(17.5+worldPos.y))+(windTime*1.25));
        
        for (int w = 0; w < windSamples; w++)
        {
            float rAnd = float(w)+1.0-(float(windSamples)/2.0);
            float rCnd = float(w)-1.0+(float(windSamples)/2.0);
            windDisplacement += sin(0.5*((17.5+rAnd+worldPos.x)+(rAnd+worldPos.y))+(windTime*(rAnd*0.1+1.75)));
            windDisplacement -= cos(0.5*((17.5+rCnd+worldPos.x)+(rAnd+worldPos.y))+(windTime*(rCnd*0.1+1.75)));
        }

        wind = windStrength*(height-0.25)*sin((worldPos.xy*normalize(windDirection))+vec2(windTime*0.5))*windDisplacement;
        wind *= ((height - groundLevel) * bending + 1.0 - bending);
    }
    else
    {
        wind = vec2(0.0,0.0);        
    }
    return wind;
    
}

mat4 addWorldPos(mat4 modelMat, vec3 pos)
{
   modelMat[3][0] += pos.x;
   modelMat[3][1] += pos.y;
   modelMat[3][2] += pos.z;   
   return modelMat;
}

// ########################################Main-Function########################################

void main() 
{
    vec4 verts = gl_Vertex;
    vec4 worldSpacePos = ModelMatrix * (verts*deforming+1.0-deforming);
    vec2 wind = getWind(worldSpacePos, verts.z);
    
    mat4 modelViewMatix = ViewMatrix * addWorldPos(ModelMatrix, vec3(wind, 0.0));
    texCoord = gl_MultiTexCoord0.xy;
    vNormal = gl_NormalMatrix * gl_Normal;
    eyePos = (modelViewMatix * verts).xyz;
    gl_Position = gl_ProjectionMatrix * modelViewMatix * verts;
}