#version 330 core

// --- Vertex inputs ---
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec3 aNorm;
layout(location = 2) in vec2 aTex;
layout(location = 3) in uint aBone;

// --- Uniforms ---
uniform mat4 uProj;
uniform mat4 uView;
uniform vec4 u_Bones[256];

uniform vec4 u_bodyLight;
uniform vec4 u_lightPosition;
uniform vec4 u_meshUV;
uniform vec4 u_setting1;
uniform vec4 u_setting2;
uniform bool u_enableLight;

// --- Varyings to fragment shader ---
out vec4 v_color0;
out vec2 v_texcoord0;

void main() {
    // -- Skinning transform from SSBO u_Bones --
    int offset = int(aBone);
    vec4 bonePos;
    bonePos.x = dot(u_Bones[offset + 0], vec4(aPos, 1.0));
    bonePos.y = dot(u_Bones[offset + 1], vec4(aPos, 1.0));
    bonePos.z = dot(u_Bones[offset + 2], vec4(aPos, 1.0));
    bonePos.w = 1.0;

    // -- Compute final clip-space position --
    gl_Position = uProj * uView * bonePos;

    // -- Normal transform --
    vec3 n;
    n.x = dot(u_Bones[offset + 0].xyz, aNorm);
    n.y = dot(u_Bones[offset + 1].xyz, aNorm);
    n.z = dot(u_Bones[offset + 2].xyz, aNorm);
    n = normalize(n);

    // -- Lighting --
    if (u_enableLight) {
        float intensity = max(((dot(n, u_lightPosition.xyz) * 0.8 + 0.4) * u_lightPosition.w + (1.0 - u_lightPosition.w)), 0.2);
        vec4 lightFactor = vec4(intensity, intensity, intensity, u_lightPosition.w);
        v_color0 = clamp(u_bodyLight * lightFactor, 0.0, 1.0);
    } else {
        v_color0 = u_bodyLight;
    }

    // -- Compute chrome4 UV coordinates exactly as on CPU --
    // base.x = dot(n, setting1.xyz)
    // base.y = 1 - dot(n, setting1.xyz)
    vec2 base;
    base.x = dot(n, u_setting1.xyz);
    base.y = 1.0 - dot(n, u_setting1.xyz);

    // dy = (n.z * setting2.x) + (setting1.w * setting2.y)
    float dy = (n.z * u_setting2.x) + (u_setting1.w * u_setting2.y);

    // chrome.x = base.x + (n.y * setting2.z) + (setting1.y * setting2.w)
    // chrome.y = base.y - dy
    vec2 chrome;
    chrome.x = base.x + (n.y * u_setting2.z) + (u_setting1.y * u_setting2.w);
    chrome.y = base.y - dy;

    // final texcoord = chrome + meshUV.xy
    v_texcoord0 = chrome + u_meshUV.xy;
}
