#version 330 core
in vec4 vertex_color;
out vec4 fragColor;

uniform float light_mode_meas;

uniform vec4 visible_meas;
uniform vec4 low_meas;
uniform vec4 high_meas;

uniform vec2 t_bounds_meas;
uniform vec2 resolution_meas;

// Translucent boxes
uniform vec4 box_0_meas;
uniform vec4 box_1_meas;
uniform vec4 box_2_meas;
uniform vec4 box_3_meas;

// Markers
uniform vec4 markers_0_meas;
uniform vec4 markers_1_meas;
uniform vec4 markers_2_meas;
uniform vec4 markers_3_meas;

// Colors
uniform vec3 ch1_col_meas;
uniform vec3 ch2_col_meas;
uniform vec3 ch3_col_meas;
uniform vec3 ch4_col_meas;
uniform float ch_start_idx;

uniform sampler2D tex;

float get_pdf(float channel) {
    return texture(tex, vec2(vertex_color.x, 1/64. + channel/32.)).x;
}

vec4 get_pdf4(float ch0) {
    return vec4(get_pdf(ch0), get_pdf(ch0+1.), get_pdf(ch0+2.), get_pdf(ch0+3.));
}

bool in_box(float t, float y, vec4 box) {
    return (t > box.x) && (t < box.y) && (y > box.z) && (y < box.w);
}

vec4 marker_color(float t, float y, vec4 markers, float range) {
    float dt = t_bounds_meas.y - t_bounds_meas.x;
    vec2 res = resolution_meas/resolution_meas.y;

    vec2 thresh = 1.5e-2/res * vec2(dt, range);
    float r0 = length(vec2(abs(t - markers[0]), abs(y - markers[1]))/thresh);
    float r1 = length(vec2(abs(t - markers[2]), abs(y - markers[3]))/thresh);

    if (r0 < 1 || r1 < 1) {
        if (r0 < 0.7 || r1 < 0.7) {
            return vec4(0.2, 0.2, 0.2, 1.);
        } else {
            return vec4(1., 1., 1., 1.);
        }
    }
    return vec4(0.);
}

void main() {
    vec4 pdf = get_pdf4(ch_start_idx);
    vec4 mask = visible_meas*0.7*step(vertex_color.yyyy, 0.1*pdf);

    vec4 range = high_meas - low_meas;
    vec4 y = vertex_color.yyyy * range + low_meas;
    float t = mix(t_bounds_meas.x, t_bounds_meas.y, vertex_color.x);

    vec4 marker = marker_color(t, y.x, markers_0_meas, range.x);
    if (marker.w > 0.5) {fragColor = marker; return;}
    marker = marker_color(t, y.y, markers_1_meas, range.y);
    if (marker.w > 0.5) {fragColor = marker; return;}
    marker = marker_color(t, y.z, markers_2_meas, range.z);
    if (marker.w > 0.5) {fragColor = marker; return;}
    marker = marker_color(t, y.w, markers_3_meas, range.w);
    if (marker.w > 0.5) {fragColor = marker; return;}

    if (
        in_box(t, y.x, box_0_meas)
        || in_box(t, y.y, box_1_meas)
        || in_box(t, y.z, box_2_meas)
        || in_box(t, y.w, box_3_meas)
    ) {
        fragColor = vec4(vec3(1.-light_mode_meas), 0.2 + 0.2*light_mode_meas);
        return;
    }

    // Implement alpha composite passes
    vec4 pix = vec4(ch1_col_meas, 1.) * mask.x;
    pix = vec4(ch2_col_meas, 1.) * mask.y + (1.-mask.y) * pix;
    pix = vec4(ch3_col_meas, 1.) * mask.z + (1.-mask.z) * pix;
    pix = vec4(ch4_col_meas, 1.) * mask.w + (1.-mask.w) * pix;
    fragColor = pix;
}
