
const int DIRECTIONAL_LIGHT = 0;
const int POINT_LIGHT = 1;

uniform mat4 PROJECTION_MATRIX;
uniform mat4 VIEW_MATRIX;
uniform mat4 WORLD_MATRIX;

uniform vec3 diffuse_light_direction;
uniform vec3 diffuse_light_colour;

attribute vec4 vertex_position;
attribute vec4 vertex_colour;
attribute vec3 vertex_normal;

varying vec4 lit_vertex_colour;

vec3 getLightColour(vec3 normal, vec3 vertex_view, vec3 light_position, vec3 light_colour, vec4 vertex_colour, int type, float falloff)
{
  vec3 vertex_light_offset;
  float attenuation = 1.0;
  if(type == 0)
  {
    vertex_light_offset = normalize(vec3(-light_position.xyz));
    attenuation = 1.0;
  }
  else if(type == 1)
  {
    vertex_light_offset = normalize(light_position.xyz - vertex_view);
    float light_distance = length(light_position.xyz - vertex_view);
    attenuation = 1.0 / (1.0 + falloff * pow(light_distance, 2.0));
  }

  float ambient_val = 0.0;
  vec3 ambient = ambient_val * vertex_colour.rgb * light_colour.rgb;

  float diffuse_val = max(0.0, dot(normal, vertex_light_offset));
  vec3 diffuse = diffuse_val * vertex_colour.rgb * light_colour.rgb;

  vec3 final_colour = ambient + attenuation * (diffuse);
  return final_colour;
}

void main()
{
  mat4 MODELVIEW = VIEW_MATRIX * WORLD_MATRIX;
  mat4 MVP = PROJECTION_MATRIX * MODELVIEW;
  mat3 NORMAL_MATRIX = mat3(WORLD_MATRIX);

  vec4 view_position = WORLD_MATRIX * vertex_position;

  vec3 normal = normalize(NORMAL_MATRIX * vertex_normal);
  vec3 vertex = vec3(view_position);

  vec3 light_colour = vec3(0.0);
  light_colour += getLightColour(normal, vertex, diffuse_light_direction, diffuse_light_colour, vertex_colour, DIRECTIONAL_LIGHT, 0.0);

  lit_vertex_colour = vec4(light_colour, vertex_colour.a);

  gl_Position = MVP * vertex_position;
}