/////////////
// GLOBALS //
/////////////
cbuffer MatrixBuffer : register(b0)
{
    matrix knochenMatrix[128];
};

// The projection and view matrix
cbuffer Kamera : register(b1)
{
    matrix view;
    matrix projection;
}

cbuffer LightController : register(b2)
{
    uint lightLength;
    float dayLightFactor;
}

// stores the light for two verticies
struct VertexLight
{
    uint dayLight1;
    uint dynamicLight1;
    uint dayLight2;
    uint dynamicLight2;
};

StructuredBuffer<VertexLight> lightBuffer : register(t0);

//////////////
// TYPEDEFS //
//////////////
struct VertexInputType
{
    float4 position : POSITION;
    float2 tex : TEXCOORD0;
    float3 normal : NORMAL;
    uint knochen : KNOCHEN_ID0;
    uint id : VERTEX_ID0;
};

struct PixelInputType
{
    float4 worldPos : POSITION;
    float4 position : SV_POSITION;
    float2 tex : TEXCOORD0;
    float3 normal : TEXCOORD1;
    float4 light1 : TEXCOORD2;
    float4 light2 : TEXCOORD3;
};

////////////////////////////////////////////////////////////////////////////////
// Vertex Shader
////////////////////////////////////////////////////////////////////////////////
PixelInputType TextureVertexShader(VertexInputType input)
{
    // return input;
    PixelInputType output;
    output.normal
        = normalize(mul(input.normal, (float3x3)knochenMatrix[input.knochen]));

    // Change the position vector to be 4 units for proper matrix calculations.
    input.position.w = 1.0f;

    // Store the texture coordinates for the pixel shader.
    output.tex = input.tex;

    // Calculate the position of the vertex against the world, view, and
    // projection matrices.
    output.worldPos = mul(input.position, knochenMatrix[input.knochen]);
    output.position = mul(output.worldPos, view);
    output.position = mul(output.position, projection);
    output.light1 = float4(1.0f, 1.0f, 1.0f, 0.f);
    output.light2 = float4(0.0f, 0.0f, 0.0f, 0.f);
    uint dayLight = 0;
    uint dynamicLight = 0;
    if (lightLength == 1)
    {
        dayLight = lightBuffer[0].dayLight1;
        dynamicLight = lightBuffer[0].dynamicLight1;
    }
    else if (input.id < lightLength)
    {
        if (input.id % 2 == 0)
        {
            dayLight = lightBuffer[input.id / 2].dayLight1;
            dynamicLight = lightBuffer[input.id / 2].dynamicLight1;
        }
        else
        {
            dayLight = lightBuffer[input.id / 2].dayLight2;
            dynamicLight = lightBuffer[input.id / 2].dynamicLight2;
        }
    }
    if (lightLength > 0 && (input.id < lightLength || lightLength == 1))
    {
        output.light1.x = (((dayLight >> 24) & 0xFF) / 255.f) * dayLightFactor;
        output.light1.y = (((dayLight >> 16) & 0xFF) / 255.f) * dayLightFactor;
        output.light1.z = (((dayLight >> 8) & 0xFF) / 255.f) * dayLightFactor;
        output.light2.x = ((dynamicLight >> 24) & 0xFF) / 255.f;
        output.light2.y = ((dynamicLight >> 16) & 0xFF) / 255.f;
        output.light2.z = ((dynamicLight >> 8) & 0xFF) / 255.f;
        output.light1.w = 1.f;
    }

    return output;
}