// Original 5x7 pixel lettering for the temporary Noxara startup signature.
// Each glyph is stored as two small bit banks to remain GLSL 1.30 compatible.
ivec2 noxaraSignatureGlyphBits(int glyph) {
    if (glyph == 0)  return ivec2(644913, 17969); // N
    if (glyph == 1)  return ivec2(574912, 14897); // o
    if (glyph == 2)  return ivec2(141856,   554); // x
    if (glyph == 3)  return ivec2(492992, 13937); // a
    if (glyph == 4)  return ivec2(550592, 16912); // r
    if (glyph == 6)  return ivec2(842256, 31281); // b
    if (glyph == 7)  return ivec2(509472, 28737); // y
    if (glyph == 8)  return ivec2(712238, 15895); // @
    if (glyph == 9)  return ivec2(475616, 14881); // s
    if (glyph == 10) return ivec2(575008, 13937); // u
    if (glyph == 11) return ivec2(583360, 17969); // n
    if (glyph == 12) return ivec2(575424, 16926); // p
    if (glyph == 13) return ivec2(162948,  2212); // t
    return ivec2(0); // space or unsupported glyph
}

int noxaraSignatureLineGlyph(int line, int index) {
    // "Noxara by"
    if (line == 0) {
        if (index == 0) return 0;
        if (index == 1) return 1;
        if (index == 2) return 2;
        if (index == 3) return 3;
        if (index == 4) return 4;
        if (index == 5) return 3;
        if (index == 6) return 5;
        if (index == 7) return 6;
        if (index == 8) return 7;
    }

    // "@souanpt"
    if (line == 1) {
        if (index == 0) return 8;
        if (index == 1) return 9;
        if (index == 2) return 1;
        if (index == 3) return 10;
        if (index == 4) return 3;
        if (index == 5) return 11;
        if (index == 6) return 12;
        if (index == 7) return 13;
    }

    return 5;
}

float noxaraSignatureGlyphPixel(int glyph, int column, int row) {
    if (column < 0 || column > 4 || row < 0 || row > 6) return 0.0;

    ivec2 banks = noxaraSignatureGlyphBits(glyph);
    int bankRow = row;
    float bank = float(banks.x);
    if (row >= 4) {
        bank = float(banks.y);
        bankRow = row - 4;
    }

    int bitIndex = bankRow * 5 + (4 - column);
    return mod(floor(bank / exp2(float(bitIndex))), 2.0);
}

float noxaraSignatureTextPixel(vec2 rasterPosition) {
    ivec2 pixel = ivec2(floor(rasterPosition));
    if (pixel.x < 0 || pixel.x >= 49 || pixel.y < 0 || pixel.y >= 19) return 0.0;

    int line = -1;
    int row = 0;
    int lineX = pixel.x;

    if (pixel.y >= 1 && pixel.y < 8) {
        line = 0;
        row = pixel.y - 1;
    } else if (pixel.y >= 11 && pixel.y < 18) {
        line = 1;
        row = pixel.y - 11;
        lineX -= 2; // Center the shorter second line.
    }

    if (line < 0 || lineX < 0) return 0.0;

    int glyphCount = line == 0 ? 9 : 8;
    // Four one-pixel gaps are distributed across each line.  This keeps the
    // lettering readable while fitting the exact 49-pixel reference panel.
    for (int glyphIndex = 0; glyphIndex < 9; glyphIndex++) {
        if (glyphIndex >= glyphCount) break;
        int glyphStart = glyphIndex * 5 + (glyphIndex + 1) / 2;
        if (lineX >= glyphStart && lineX < glyphStart + 5) {
            return noxaraSignatureGlyphPixel(
                noxaraSignatureLineGlyph(line, glyphIndex),
                lineX - glyphStart,
                row
            );
        }
    }

    return 0.0;
}

vec3 noxaraSignatureRayPlaneIntersection(vec3 origin, vec3 direction, vec3 planeNormal) {
    float denominator = dot(direction, planeNormal);
    if (abs(denominator) <= 0.0001) return direction * 1e8;
    return origin + direction * (dot(-origin, planeNormal) / denominator);
}

void drawNoxaraStartupSignature(inout vec3 color, vec2 coord, float elapsedSeconds) {
#ifdef NOXARA_STARTUP_SIGNATURE
    // Full visibility for four real seconds, followed by a smooth three-second fade.
    float visibility = 1.0 - smoothstep(4.0, 7.0, elapsedSeconds);
    if (visibility <= 0.0) return;

    vec4 viewPoint = gbufferProjectionInverse * vec4(coord * 2.0 - 1.0, 1.0, 1.0);
    vec3 viewDirection = normalize(viewPoint.xyz / max(abs(viewPoint.w), 0.00001));

    float pitchAngle = acos(clamp(dot(gbufferModelView[1].xyz, vec3(0.0, 0.0, -1.0)), -1.0, 1.0))
                     - 1.57079632679;
    pitchAngle = -0.5 * pitchAngle + 0.1;
    float pitchCos = cos(pitchAngle);
    float pitchSin = sin(pitchAngle);
    mat3 pitchRotation = mat3(
        1.0, 0.0,       0.0,
        0.0, pitchCos,  pitchSin,
        0.0, -pitchSin, pitchCos
    );

    float yawAngle = noxaraTitleEyeYawSmooth * 7.0;
    float yawCos = cos(yawAngle);
    float yawSin = sin(yawAngle);
    mat3 yawRotation = mat3(
        yawCos, 0.0, -yawSin,
        0.0,    1.0, 0.0,
        yawSin, 0.0, yawCos
    );

    mat3 panelRotation = yawRotation * pitchRotation;
    vec3 panelOrigin = panelRotation * vec3(0.0, 0.0, 4.0);
    vec3 panelDirection = panelRotation * viewDirection;

    #if MC_VERSION >= 11400
    vec3 cameraTranslation = gbufferModelViewInverse[3].xyz * 0.1;
    panelOrigin = mat3(gbufferModelViewInverse) * panelOrigin + cameraTranslation;
    panelDirection = mat3(gbufferModelViewInverse) * panelDirection + cameraTranslation;
    #else
    panelOrigin = mat3(gbufferModelViewInverse) * panelOrigin;
    panelDirection = mat3(gbufferModelViewInverse) * panelDirection;
    #endif

    panelOrigin = panelOrigin * yawRotation;
    vec3 planeNormal = -gbufferModelViewInverse[2].xyz;
    vec3 panelPosition = mat3(gbufferModelView) * noxaraSignatureRayPlaneIntersection(
        panelOrigin,
        panelDirection,
        planeNormal
    );

    if (panelPosition.x < -1.9 || panelPosition.x > 2.1 ||
        panelPosition.y < -1.0 || panelPosition.y > 1.0) return;

    // Match Iteration's exact 49x19 projected panel footprint.  The Noxara
    // glyphs use compact five-pixel cells so no one-pixel stroke is skipped.
    vec2 panelCoord = panelPosition.xy * vec2(0.25, -0.25) + vec2(0.48, 0.28);
    vec2 referenceTexel = floor(panelCoord * 50.0) + vec2(0.0, -4.0);
    vec2 rasterPosition = referenceTexel;
    float foreground = noxaraSignatureTextPixel(rasterPosition);
    float shadow = max(
        noxaraSignatureTextPixel(rasterPosition - vec2(1.0)) - foreground,
        0.0
    );

    // Iteration injects title alpha into its later bloom chain.  Noxara's
    // bloom pyramid has already been built by final, so reproduce the small
    // local halo with a fixed eight-tap mask only during the seven-second intro.
    float glow = 0.0;
    glow = max(glow, noxaraSignatureTextPixel(rasterPosition + vec2( 2.0,  0.0)));
    glow = max(glow, noxaraSignatureTextPixel(rasterPosition + vec2(-2.0,  0.0)));
    glow = max(glow, noxaraSignatureTextPixel(rasterPosition + vec2( 0.0,  2.0)));
    glow = max(glow, noxaraSignatureTextPixel(rasterPosition + vec2( 0.0, -2.0)));
    glow = max(glow, noxaraSignatureTextPixel(rasterPosition + vec2( 1.0,  1.0)));
    glow = max(glow, noxaraSignatureTextPixel(rasterPosition + vec2(-1.0,  1.0)));
    glow = max(glow, noxaraSignatureTextPixel(rasterPosition + vec2( 1.0, -1.0)));
    glow = max(glow, noxaraSignatureTextPixel(rasterPosition + vec2(-1.0, -1.0)));
    color += vec3(max(glow - foreground, 0.0) * 0.12 * visibility);

    color = mix(color, vec3(0.0), shadow * (229.0 / 255.0) * visibility);
    color = mix(color, vec3(1.0), foreground * visibility);
#endif
}
