import { insert_after } from "../../../../../core/primitives/strings/insert_after.js";
import { insert_after_or_replace } from "../../../../../core/primitives/strings/insert_after_or_replace.js";
import { FP_SHADER_CHUNK_ACCUMULATION } from "./FP_SHADER_CHUNK_ACCUMULATION.js";
import { FP_SHADER_CHUNK_DECODE_PARS } from "./FP_SHADER_CHUNK_DECODE_PARS.js";
import { FP_INJECTION_POINT_ACCUMULATION } from "./FP_INJECTION_POINT_ACCUMULATION.js";
import { FP_SHADER_CHUNK_PREAMBLE } from "./FP_SHADER_CHUNK_PREAMBLE.js";
import { insert_before } from "../../../../../core/primitives/strings/insert_before.js";
import { FP_SHADER_CHUNK_APPLY_DECALS } from "./FP_SHADER_CHUNK_APPLY_DECALS.js";
import { FP_SHADER_CHUNK_LOAD_METADATA } from "./FP_SHADER_CHUNK_LOAD_METADATA.js";

const three_chunk_accummulation_mark = '#include <lights_fragment_begin>';

const accumulation_pars = `
        vec3 clip_v = vec3( vec2(gl_FragCoord.x, gl_FragCoord.y) / fp_resolution, convert_depth_to_linear(gl_FragCoord.z));
        clip_v.x = 1.0 - clip_v.x;
       ${FP_SHADER_CHUNK_LOAD_METADATA}
    `;

const preamble = `
    ${FP_SHADER_CHUNK_PREAMBLE}
    `;

/**
 *
 * @param {string} base
 * @returns {string}
 */
export function fp_build_fragment_shader(base) {
    let result = preamble;

    if (base.indexOf('v_world_position') === -1) {
        result = result + `
        varying vec3 v_world_position;
        `;
    }

    if (base.indexOf('#define gl_FragColor') === -1 && base.indexOf('pc_fragColor') === -1) {
        result = result + `
            out highp vec4 pc_fragColor;
            #define gl_FragColor pc_fragColor
            `;
    }

    result = result + base;

    result = insert_after(result, 'void main() {', accumulation_pars);

    result = insert_after(result, '#include <lights_pars_begin>', FP_SHADER_CHUNK_DECODE_PARS);

    result = insert_before(result, '#include <lights_fragment_begin>', FP_SHADER_CHUNK_APPLY_DECALS);

    result = insert_after_or_replace(
        result,
        three_chunk_accummulation_mark,
        FP_INJECTION_POINT_ACCUMULATION,
        FP_SHADER_CHUNK_ACCUMULATION
    );

    return result;
}
