#include "ReShade.fxh"

texture FontTexture < source = "font.png"; >
{
    Width = 512;
    Height = 512;
    Format = RGBA8;
};
sampler FontSampler { Texture = FontTexture; };
// Time dilation
uniform bool OSD_ShowTD         = false;
uniform bool TD_Enabled         = false;
uniform float TD_World          = 1.0;
uniform float TD_AI             = 1.0;
// God mode
uniform bool OSD_ShowGodMode    = false;
uniform bool GodMode_Enabled    = false;
// Ignore hits
uniform bool OSD_ShowIgnoreHits = false;
uniform bool IgnoreHits_Enabled = false;
// Stealth
uniform bool OSD_ShowStealth	= false;
uniform bool Stealth_Enabled	= false;
// Stamina
uniform bool OSD_ShowStamina    = false;
uniform bool Stamina_Enabled    = false;
// Mana
uniform bool OSD_ShowMana       = false;
uniform bool Mana_Enabled       = false;

// --- Character arrays for labels ---
static const int ON_LENGTH = 2;
static float ON_CHARS[32] = { 
	79-32, 78-32, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0 	
}; // "ON"

static const int OFF_LENGTH = 3;
static float OFF_CHARS[32] = { 
	79-32, 70-32, 70-32, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0 	
}; // "OFF"

static const int TD_LABEL_LEN = 14;
static float TD_LABEL[32] = {
    84-32, 105-32, 109-32, 101-32, 32-32, 100-32, 105-32, 108-32, // Time dilation :
    97-32, 116-32, 105-32, 111-32, 110-32, 32-32,0,0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

static const int WORLD_LEN = 8;
static float WORLD_CHARS[32] = { 
	32-32, 87-32, 111-32, 114-32, 108-32, 100-32, 58-32, 32-32, // World :
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0 
};
static const int AI_LEN = 5;
static float AI_CHARS[32] = {
	32-32,65-32,73-32,58-32,32-32,0,0,0, // AI :
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0
};

// New labels
static const int GOD_LEN = 9;
static float GOD_CHARS[32] = { 
	71-32, 111-32, 100-32, 32-32, 77-32, 111-32, 100-32, 101-32, // God Mode :
	32 -32, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0
 };

static const int INV_LEN = 12;
static float INV_CHARS[32] = {
	73-32, 103-32, 110-32, 111-32, 114-32, 101-32, 32-32, 104-32, // Ignore hits :
	105-32, 116-32, 115-32, 32-32, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0
};

static const int STEALTH_LEN = 13;
static float STEALTH_CHARS[32] = {
	83-32, 116-32, 101-32, 97-32, 108-32, 116-32, 104-32, 32-32, // Stealth Mode :
	77-32, 111-32, 100-32, 101-32, 32-32, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0 
};

static const int STAMINA_LEN = 8;
static float STAMINA_CHARS[32] = {
    83 - 32, 116 - 32, 97 - 32, 109 - 32, 105 - 32, 110 - 32, 97 - 32, 32 - 32, // Stamina
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0
};

static const int MANA_LEN = 5;
static float MANA_CHARS[32] = {
    77 - 32, 97 - 32, 110 - 32, 97 - 32, 32 - 32, 0, 0, 0, // Mana :
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0
};

// --- SDF Rectangle ---
float sdRoundRect(float2 p, float2 b, float r) {
    float2 q = abs(p) - b + r;
    return min(max(q.x, q.y), 0.0) + length(max(q,0.0)) - r;
}

// --- Draw a character ---
float4 DrawChar(float2 uv, float2 posPx, float2 charSizePx, float charIndex) {
    float2 pixelPos = uv * ReShade::ScreenSize;
    float2 local = (pixelPos - posPx) / charSizePx;

    if (local.x < 0 || local.x > 1 || local.y < 0 || local.y > 1)
        return float4(0, 0, 0, 0);

    float2 texSize = float2(14.0, 7.0);
    float2 fontUV = float2(charIndex - texSize.x * floor(charIndex / texSize.x),
                       floor(charIndex / texSize.x)) / texSize;

    float2 fontUVSize = 1.0 / texSize;
    float2 finalUV = fontUV + local * fontUVSize;

    return tex2D(FontSampler, finalUV);
}

// --- Draw text array ---
float4 DrawText(float2 uv, float2 startPosPx, float2 charSizePx, float chars[32], int length) {
    float4 col = float4(0, 0, 0, 0);

    [unroll]
    for (int i = 0; i < 32; i++) {
        if (i >= length) break;

        float2 charPos = startPosPx + float2(i * charSizePx.x, 0);
        float4 glyph = DrawChar(uv, charPos, charSizePx, chars[i]);

        col.rgb = lerp(col.rgb, glyph.rgb, glyph.a);
        col.a = max(col.a, glyph.a);
    }

    return col;
}

// --- Draw float number as text ---
float4 DrawFloat(float2 uv, float2 startPosPx, float2 charSizePx, float value) {
    float4 col = float4(0, 0, 0, 0);

    float v = abs(value);
    int iv = (int) (v * 100.0 + 0.5);

    int i0 = iv / 100;
    int i1 = (iv / 10) % 10;
    int i2 = iv % 10;

    float chars[4];
    chars[0] = i0 + 16;
    chars[1] = 14;
    chars[2] = i1 + 16;
    chars[3] = i2 + 16;

    [unroll]
    for (int i = 0; i < 4; i++) {
        float2 pos = startPosPx + float2(i * charSizePx.x, 0);
        float4 g = DrawChar(uv, pos, charSizePx, chars[i]);

        col.rgb = lerp(col.rgb, g.rgb, g.a);
        col.a = max(col.a, g.a);
    }

    return col;
}

// --- Alpha blend ---
void AlphaBlend(inout float4 dst, float4 src) {
    dst.rgb = lerp(dst.rgb, src.rgb, src.a);
    dst.a   = max(dst.a, src.a);
}

// --- Draw ON/OFF flag dynamically ---
float4 DrawFlag(float2 uv, inout float2 pen, float2 charSize, const float label[32], int labelLen, bool enabled) {
    float4 combined = DrawText(uv, pen, charSize, label, labelLen);
    pen.x += labelLen*charSize.x;

    float4 state = enabled ? DrawText(uv, pen, charSize, ON_CHARS, ON_LENGTH)
                           : DrawText(uv, pen, charSize, OFF_CHARS, OFF_LENGTH);
    pen.x += (enabled ? ON_LENGTH : OFF_LENGTH)*charSize.x;

    AlphaBlend(combined, state);
    return combined;
}

// --- Pixel Shader ---
float4 PS_OSD(float4 pos : SV_Position, float2 uv : TEXCOORD) : SV_Target {
    float4 col = tex2D(ReShade::BackBuffer, uv);

    if (!OSD_ShowTD && !OSD_ShowGodMode && !OSD_ShowIgnoreHits && !OSD_ShowStealth && !OSD_ShowStamina && !OSD_ShowMana)
        return col;

    float2 pixelPos = uv * ReShade::ScreenSize;

    float margin_top = 20.0;
    float2 centerPx = float2(ReShade::ScreenSize.x * 0.5, margin_top);
    float2 p = pixelPos - centerPx;

    // --- Frame rect ---
    float2 charSize = float2(14.0, 20.0); // pixels
    float charAdvance = charSize.x;

    float totalLen = 0;
    float3 color;
	if (TD_Enabled && OSD_ShowTD) {
		totalLen = TD_LABEL_LEN + ON_LENGTH + WORLD_LEN + 4 + AI_LEN + 4;
		color = float3(0.3, 1.0, 0.3); // Green
	}
	if (!TD_Enabled && OSD_ShowTD) {
		totalLen = TD_LABEL_LEN + OFF_LENGTH;
		color = float3(1.0, 0.3, 0.3); // Red
	}
	if (GodMode_Enabled && OSD_ShowGodMode) {
		totalLen = GOD_LEN + ON_LENGTH;
		color = float3(0.3, 1.0, 0.3);
	}
	if (!GodMode_Enabled && OSD_ShowGodMode) {
		totalLen = GOD_LEN + OFF_LENGTH;
		color = float3(1.0, 0.3, 0.3);
	}
	if (IgnoreHits_Enabled && OSD_ShowIgnoreHits) {
		totalLen = INV_LEN + ON_LENGTH;
		color = float3(0.3, 1.0, 0.3);
	}
	if (!IgnoreHits_Enabled && OSD_ShowIgnoreHits) {
		totalLen = INV_LEN + OFF_LENGTH;
		color = float3(1.0, 0.3, 0.3);
	}
	if (Stealth_Enabled && OSD_ShowStealth) {
		totalLen = STEALTH_LEN + ON_LENGTH;
		color = float3(0.3, 1.0, 0.3);
	}
	if (!Stealth_Enabled && OSD_ShowStealth) {
		totalLen = STEALTH_LEN + OFF_LENGTH;
		color = float3(1.0, 0.3, 0.3);
	}
	if (Stamina_Enabled && OSD_ShowStamina) {
		totalLen = STAMINA_LEN + ON_LENGTH;
		color = float3(0.3, 1.0, 0.3);
	}
    if (!Stamina_Enabled && OSD_ShowStamina) {
        totalLen = STAMINA_LEN + OFF_LENGTH;
		color = float3(1.0, 0.3, 0.3);
	}
    if (Mana_Enabled && OSD_ShowMana) {
        totalLen = MANA_LEN + ON_LENGTH;
        color = float3(0.3, 1.0, 0.3);
    }
    if (!Mana_Enabled && OSD_ShowMana) {
        totalLen = MANA_LEN + OFF_LENGTH;
        color = float3(1.0, 0.3, 0.3);
    }

    float verticalPadding = 6.0; // ajuste ici
    float2 sizePx = float2(totalLen * charAdvance * 0.5 + charAdvance,
                           charSize.y * 0.5 + verticalPadding);
    float thickness = 1.0;
    float radius = 4.0;

    float d = sdRoundRect(p, sizePx, radius);

    if (abs(d) < thickness) col.rgb = lerp(col.rgb, color, 0.85);

    // --- Draw all flags ---
    float2 pen = centerPx;
    pen.x -= totalLen * charAdvance * 0.5;
    pen.y -= charSize.y * 0.45;
    float4 combined = float4(0,0,0,0);

    // Time Dilation
    if (OSD_ShowTD) {
        AlphaBlend(combined, DrawText(uv, pen, charSize, TD_LABEL, TD_LABEL_LEN));
        pen.x += TD_LABEL_LEN * charAdvance;
        AlphaBlend(combined, TD_Enabled ? DrawText(uv, pen, charSize, ON_CHARS, ON_LENGTH)
                                        : DrawText(uv, pen, charSize, OFF_CHARS, OFF_LENGTH));
        pen.x += (TD_Enabled ? ON_LENGTH : OFF_LENGTH) * charAdvance;
        if (TD_Enabled) {
	        AlphaBlend(combined, DrawText(uv, pen, charSize, WORLD_CHARS, WORLD_LEN));
	        pen.x += WORLD_LEN * charAdvance;
	        AlphaBlend(combined, DrawFloat(uv, pen, charSize, TD_World));
	        pen.x += 4 * charAdvance;
	        AlphaBlend(combined, DrawText(uv, pen, charSize, AI_CHARS, AI_LEN));
	        pen.x += AI_LEN * charAdvance;
	        AlphaBlend(combined, DrawFloat(uv, pen, charSize, TD_AI));
	        pen.x += 4 * charAdvance;
        }
    }

    if (OSD_ShowGodMode)
        AlphaBlend(combined, DrawFlag(uv, pen, charSize, GOD_CHARS, GOD_LEN, GodMode_Enabled));

    if (OSD_ShowIgnoreHits)
        AlphaBlend(combined, DrawFlag(uv, pen, charSize, INV_CHARS, INV_LEN, IgnoreHits_Enabled));

    if (OSD_ShowStealth)
        AlphaBlend(combined, DrawFlag(uv, pen, charSize, STEALTH_CHARS, STEALTH_LEN, Stealth_Enabled));

    if (OSD_ShowStamina)
        AlphaBlend(combined, DrawFlag(uv, pen, charSize, STAMINA_CHARS, STAMINA_LEN, Stamina_Enabled));

    if (OSD_ShowMana)
        AlphaBlend(combined, DrawFlag(uv, pen, charSize, MANA_CHARS, MANA_LEN, Mana_Enabled));

    combined.rgb *= color;
    col.rgb = lerp(col.rgb, combined.rgb, combined.a);

    return col;
}

// --- Technique ---
technique OSD {
    pass {
        VertexShader = PostProcessVS;
        PixelShader  = PS_OSD;
    }
}
