const settings = new Settings();
settings.engine.preload = true; // skipping preload (DMX bugging etc)

const deg2rad = 0.01745329251;
window.camPos = [0.0, 0.0, 0.0];
window.camPosLength = 1.0;
window.camFov = 0.0;
window.beat = 60 / 115;
window.tick = window.beat / 8;
window.pattern = window.beat * 8;
window.camNear = 0.0;
window.camFar = 0.0;
window.globalTime = 0.0;
window.globalTime = 0.0;
window.nextSegmentIndex = 0;
window.wrapped = false;

// Directors cut enable
const cut = true;

includeFile('DmxLightManager.js');
includeFile('multiSceneEffects/PostProcess.js');
includeFile('multiSceneEffects/dof.js');
includeFile('multiSceneEffects/effectStarfield.js');

includeFile('background/background1.js');
includeFile('sceneEmojis/emojis.js');
includeFile('sceneBloom/bloom.js');
includeFile('sceneFreddy/freddy.js');
includeFile('sceneSigma/sigma.js');
includeFile('sceneAmigaBall/amigaball.js');

includeFile('sceneSigmaGoat/sigmaGoat.js');
includeFile('sceneGoatBg/goatbg.js');
includeFile('sceneSkibiville/skibiville.js');
includeFile('sceneBackrooms/backrooms.js');
includeFile('sceneMaxxing/maxxing.js');
includeFile('sceneFanumTax/fanumTax.js');
includeFile('sceneAlarm/alarm.js');

includeFile('sceneIntro/intro.js');
includeFile('sceneEnd/end.js');

includeFile('sceneOhio/ohio.js');
includeFile('sceneOhio/ohiobg.js');

//includeFile('sceneAbstract/abstract.js');
//includeFile('sceneAbstract/background.js');
//includeFile('sceneAbstract/tunnel.js');


let currentScene = null;

let writerQueue = [];

Demo.prototype.addAnimationToMainScene = function (animation) {
    if (!currentScene) {
        throw new Error('No scene set for textWriter');
    }

    writerQueue.push({_actualScene: currentScene, ...animation});
}


Demo.prototype.textWriter = function (text, options = {}) {
    this.addAnimationToMainScene({
        start: options.start,
        duration: options.duration,
        image: ["_embedded/defaultWhite.png"],
        perspective: "2d",
        scale: [{ x: 1, y: options.bgScaleY ?? ((options.fontScale ?? 1.0) / 10.0) }],
        position: [{ x: 0, y: options.bgY + (options.y ?? 0), z: 0 }],

    });

    this.addAnimationToMainScene({
        start: options.start,
        duration: options.duration,        
        text: {
            string: text,
            name: [
                'font/TikTokSans-Bold.ttf',
                'font/TikTokSans-Light.ttf',
                'font/TikTokSans-Regular.ttf',
                'font/ComicSans.ttf'
            ][options.fontId ?? 0],
            parameters: { size: 5, depth: 0.01, bevelEnabled: false }
        },
        perspective: "2d",
        position: [{ x: options.x, y: options.y ?? 0, z: options.z }],
        scale: [{ uniform3d: options.fontScale ?? 1.0 }],
        color: [{ r: 0, g: 0, b: 0 }]
    });

    if (options.outline) {
        this.addAnimationToMainScene({
        start: options.start,
        duration: options.duration,            
            text: {
                string: text,
                name: [
                    'font/TikTokSans-Bold.ttf',
                    'font/TikTokSans-Light.ttf',
                    'font/TikTokSans-Regular.ttf',
                    'font/ComicSans.ttf'
                ][options.fontId ?? 0],
                parameters: { size: 5, depth: 0.01, bevelEnabled: false }
            },
            perspective: "2d",
            position: [{ x: (0.01 * options.fontScale) + options.x, y: options.y ?? 0, z: options.z }],
            scale: [{ uniform3d: options.fontScale ?? 1.0 }],
            color: [{ r: 1, g: 1, b: 1 }]
        });
    }
};

Demo.prototype.cameraSetup = function (stopCamAt) {
    this.loader.addAnimation({
        "camera": "cam1"
        , "position": [{ "x": 0, "y": 0, "z": 10 }]
        , "lookAt": [{ "x": 0.0, "y": 0.0, "z": 0.0 }]
        , "up": [{ "x": 0, "y": 1, "z": 0 }]
        , "perspective": [{ "fov": 75, "aspect": 16 / 9, "near": .05, "far": 1000 }]
        , "distYawPitch": [-5.0, 1, 2.0]
        , "instableTimer": [0.0, 0.0, 0.0, 0.0, 0.0]
        , "runPreFunction": (animation) => {
            for (let i = 0; i < animation.instableTimer.length; i++) {
                animation.instableTimer[i] += Math.random() * getDeltaTime();
            }
            let distance = .05 * Sync.get('Cam:Instability') * Math.sin(2 * animation.instableTimer[3]) + Sync.get('Cam:Distance');
            let pitch = (Sync.get('Cam:Instability') * 5 * Math.cos(2 * animation.instableTimer[1]) + Sync.get('Cam:Yaw')) * deg2rad;
            let roll = (Sync.get('Cam:Instability') * 5 * Math.sin(2 * animation.instableTimer[2]) + Sync.get('Cam:Pitch')) * deg2rad;
            let yaw = 0.0;
            let target = [Sync.get('Cam:TargetX'), Sync.get('Cam:TargetY'), Sync.get('Cam:TargetZ')];
            let points = [0, 0, distance];
            let cosa = Math.cos(yaw),
                sina = Math.sin(yaw);
            let cosb = Math.cos(pitch),
                sinb = Math.sin(pitch);
            let cosc = Math.cos(roll),
                sinc = Math.sin(roll);
            let Axx = cosa * cosb,
                Axy = cosa * sinb * sinc - sina * cosc,
                Axz = cosa * sinb * cosc + sina * sinc;
            let Ayx = sina * cosb,
                Ayy = sina * sinb * sinc + cosa * cosc,
                Ayz = sina * sinb * cosc - cosa * sinc;
            let Azx = -sinb,
                Azy = cosb * sinc,
                Azz = cosb * cosc;
            let px = points[0];
            let py = points[1];
            let pz = points[2];
            let newPoints = [
                (Axx * px + Axy * py + Axz * pz) + target[0],
                Ayx * px + Ayy * py + Ayz * pz + target[1],
                Azx * px + Azy * py + Azz * pz + target[2]
            ];
            window.camPos = newPoints;
            window.camPosLength = Math.sqrt(newPoints[0] * newPoints[0] + newPoints[1] * newPoints[1] + newPoints[2] * newPoints[2]);
            animation.position[0].x = newPoints[0];
            animation.position[0].y = newPoints[1];
            animation.position[0].z = newPoints[2];
            animation.lookAt[0].x = Sync.get('Cam:Instability') * .25 * Math.sin(2 * animation.instableTimer[3]) + Sync.get('Cam:TargetX');
            animation.lookAt[0].y = Sync.get('Cam:Instability') * .25 * Math.cos(2 * animation.instableTimer[4]) + Sync.get('Cam:TargetY');
            animation.lookAt[0].z = Sync.get('Cam:TargetZ');
            animation.perspective[0].fov = Sync.get('Cam:FOV');
            window.camNear = animation.perspective[0].near;
            window.camFar = animation.perspective[0].far;
            window.camFov = animation.perspective[0].fov * deg2rad;

        }
    });


};

Demo.prototype.setScene = function (sceneName) {
    this.loader.setScene(sceneName);
    currentScene = sceneName;
    //this.cameraSetup();
};

settings.demo.renderer.sortObjects = false;
settings.demo.renderer.logarithmicDepthBuffer = false;
settings.demo.sync.rocketFile = 'sync/demo.rocket';
settings.demo.sync.beatsPerMinute = 115;
settings.demo.sync.rowsPerBeat = 8;
settings.demo.camera.near = 0.1;
settings.demo.camera.far = 1000.0;
//settings.demo.clearColor = { r: 1.0, g: 1.0, b: 1.0, a: 1.0 };
settings.demo.model.shape.material.type = 'Standard';
settings.demo.shadow.mapSize.width = 2048;
settings.demo.shadow.mapSize.height = settings.demo.shadow.mapSize.width;
settings.demo.image.texture.minFilter = 'NearestFilter';
settings.demo.image.texture.magFilter = 'NearestFilter';
//settings.demo.image.texture.wrapS = 'RepeatWrapping';
//settings.demo.image.texture.wrapT = 'RepeatWrapping';
settings.demo.fbo.color.texture.minFilter = 'NearestFilter';
settings.demo.fbo.color.texture.magFilter = 'NearestFilter';
//settings.demo.fbo.color.texture.wrapS = 'RepeatWrapping';
//settings.demo.fbo.color.texture.wrapT = 'RepeatWrapping';

Demo.prototype.init = function () {
    writerQueue = [];

    const bpm = 115;
    const beat = 60 / bpm;

    this.sceneEmojis();
    this.sceneBackground1();
    this.sceneBloom();
    this.sceneFreddy();
    this.sceneSigma();
    this.sceneAmigaBall();
    this.sceneSigmaGoat();
    this.sceneGoatbg();
    this.sceneSkibiville();
    this.sceneBackrooms();
    this.sceneMaxxing();
    this.sceneFanumTax();
    this.sceneAlarm();
    this.sceneIntro();
    this.sceneEnd();
    this.sceneOhio();
    this.sceneOhioBg();
    
    this.loader.setScene('main');

    const scenes = [
        { start: 0 * window.pattern, duration: 4 * window.pattern, name: 'amigaBall', dof: false, polaroid: false, feedback: false },
        { start: 4 * window.pattern, duration: 4 * window.pattern, name: 'sigma', dof: false, polaroid: false, feedback: true },
        { start: 4 * window.pattern, duration: 4 * window.pattern, name: 'freddy', dof: false, polaroid: false, feedback: false },
        { start: 8 * window.pattern, duration: 4 * window.pattern, name: 'goatbg', dof: true, polaroid: false, feedback: false },        
        { start: 8 * window.pattern, duration: 4 * window.pattern, name: 'sigmaGoat', dof: false, polaroid: false, feedback: false },
        { start: 12 * window.pattern, duration: 4 * window.pattern, name: 'background1', dof: false, polaroid: false, feedback: false },
        { start: 12 * window.pattern, duration: 4 * window.pattern, name: 'skibiville', dof: false, polaroid: false, feedback: false },
        { start: 16 * window.pattern, duration: 5 * window.pattern, name: 'backrooms', dof: false, polaroid: false, feedback: false },

        { start: 21 * window.pattern, duration: 4 * window.pattern, name: 'maxxing', dof: false, polaroid: false, feedback: true, feedbackAmount: 0.98, feedbackFadeAmount: 0.9 },
        { start: 21 * window.pattern, duration: 4 * window.pattern, name: 'maxxing', dof: false, polaroid: false, feedback: false },
        {start: 25*window.pattern, duration: 4*window.pattern, name: 'alarm', dof:false, polaroid:false, feedback: false},
        {start: 29*window.pattern, duration: 4*window.pattern, name: 'ohiobg', dof:false, polaroid:false, feedback: false},        
        {start: 29*window.pattern, duration: 4*window.pattern, name: 'ohio', dof:false, polaroid:false, feedback: false},
        {start: 33*window.pattern, duration: 4*window.pattern, name: 'fanumTax', dof:false, polaroid:false, feedback: false},
        {start: 41*window.pattern, duration: 4*window.pattern, name: 'intro', dof:false, polaroid:false, feedback: false},
        {start: 45*window.pattern, duration: 4*window.pattern, name: 'end', dof:false, polaroid:false, feedback: false},
        // filler particles on top of everything
        {start: 0*window.pattern, duration: 41*window.pattern, name: 'emojis', dof:false, polaroid:false},
    ];

    // cutting system
    init = true;
    var demoStartTimeMilliseconds = 0
    this.loader.addAnimation({
        runPreFunction: () => {
            if ((new DemoEngine.LoadingBar()).isLoading() === true) {
                return;
            }

            if(!cut) return;

            if(init)
            {
                const d = new Date();
                demoStartTimeMilliseconds = d.getTime();
                init = false;
            }
            
           // if(settings.engine.tool) return;
            
            let currentDemoTime = new Date() - demoStartTimeMilliseconds;

            const timer = new DemoEngine.Timer();
            const nextCut = GetNextCutTime(currentDemoTime);
            if (nextCut !== null) {
                timer.setTime(nextCut);
            }
        }
    });

    scenes.forEach((scene) => {
        this.loader.addAnimation({ start: scene.start, scale: scene.scale == undefined ? 1 : scene.scale, duration: scene.duration, scene: { name: scene.name, fbo: { name: scene.name + 'Fbo' } }, ...(scene.parameters || {}) });
    });

    scenes.forEach((scene) => {
        if (!scene.polaroid || !scene.prePostProcessing) {
            this.loader.addAnimation({ start: scene.start, duration: scene.duration, color: scene.color, image: scene.name + 'Fbo.color.fbo' });
        }
    });

    this.loader.addAnimation({ fbo: { name: 'screenDof', action: 'begin', storeDepth: false } });
    scenes.forEach((scene) => {
        if (scene.dof) {
            this.loader.addAnimation({
                start: scene.start, duration: scene.duration, color: scene.color, image: [scene.name + 'Fbo.depth.fbo', scene.name + 'Fbo.color.fbo'],
                material: { blending: 'CustomBlending', blendEquation: 'MaxEquation', blendSrc: 'SrcColorFactor', blendDst: 'SrcColorFactor' },
                shader: { name: 'multiSceneEffects/depthToColor.fs' }
            });
        }
    });



    this.loader.addAnimation({ fbo: { name: 'screenDof', action: 'unbind' } });

    // Create persistent feedback buffer for scenes that need it
    scenes.forEach((scene) => {
        if (scene.feedback) {
            this.loader.addAnimation({ fbo: { name: scene.name + 'Feedback', action: 'begin', storeDepth: false } });
            this.loader.addAnimation({ image: '_embedded/defaultTransparent.png' });
            this.loader.addAnimation({ fbo: { name: scene.name + 'Feedback', action: 'unbind' } });
        }
    });

    // Render feedback scenes to temp FBO and copy to feedback buffer
    scenes.forEach((scene) => {
        if (scene.feedback) {
            this.loader.addAnimation({
                start: scene.start,
                duration: scene.duration,
                fbo: { name: scene.name + 'FeedbackTemp', action: 'begin', storeDepth: false }
            });
            this.loader.addAnimation({
                start: scene.start,
                duration: scene.duration,
                image: [scene.name + 'Fbo.color.fbo', scene.name + 'Feedback.color.fbo'],
                shader: {
                    name: 'multiSceneEffects/feedback.fs',
                    variable: [
                        { "name": "feedbackAmount", "value": [scene.feedbackAmount || 0.98] },
                        { "name": "fadeAmount", "value": [scene.feedbackFadeAmount || 0.99] }
                    ]
                }
            });
            this.loader.addAnimation({
                start: scene.start,
                duration: scene.duration,
                fbo: { name: scene.name + 'FeedbackTemp', action: 'unbind' }
            });

            // Copy temp result to feedback buffer for next frame
            this.loader.addAnimation({
                start: scene.start,
                duration: scene.duration,
                fbo: { name: scene.name + 'Feedback', action: 'begin', storeDepth: false }
            });
            this.loader.addAnimation({
                start: scene.start,
                duration: scene.duration,
                image: scene.name + 'FeedbackTemp.color.fbo',
                additive: true
            });
            this.loader.addAnimation({
                start: scene.start,
                duration: scene.duration,
                fbo: { name: scene.name + 'Feedback', action: 'unbind' }
            });
        }
    });

    this.loader.addAnimation({ fbo: { name: 'screenFbo', action: 'begin', storeDepth: false } });
    scenes.forEach((scene) => {
        if (scene.feedback) {
            this.loader.addAnimation({
                start: scene.start,
                duration: scene.duration,
                image: scene.name + 'FeedbackTemp.color.fbo'
            });
        } else if (!scene.polaroid || !scene.prePostProcessing) {
            this.loader.addAnimation({ start: scene.start, duration: scene.duration, color: scene.color, image: scene.name + 'Fbo.color.fbo' });
        }
    });



    this.loader.addAnimation({ fbo: { name: 'screenFbo', action: 'unbind' } });

    this.loader.addAnimation({ fbo: { name: 'blur', action: 'begin', storeDepth: false } });
    this.loader.addAnimation({
        image: 'screenFbo.color.fbo',
        shader: {
            name: 'multiSceneEffects/gaussianBlur.fs',
            variable: [
                { "name": "directions", "value": [32.0] },
                { "name": "quality", "value": [2.0] }, // 4
                { "name": "size", "value": [1.0] } // 16
            ]
        }
    });
    this.loader.addAnimation({ fbo: { name: 'blur', action: 'unbind' } });

    this.loader.addAnimation({ fbo: { name: 'postProcessableFbo', action: 'begin', storeDepth: false } });
    this.loader.addAnimation({
        image: ['screenFbo.color.fbo', 'blur.color.fbo', 'screenDof.color.fbo'],
        shader: {
            name: 'multiSceneEffects/dof.fs',
            variable: [
                { "name": "dofCenter", "value": [() => Sync.get('General:dofCenter')] },
                { "name": "dofWidth", "value": [() => Sync.get('General:dofWidth')] }
            ]
        }
    });

    this.loader.addAnimation({ fbo: { name: 'postProcessableFbo', action: 'unbind' } });



    this.addPostProcess('postProcessableFbo.color.fbo');

    this.loader.addAnimation({ fbo: { name: 'finalfinal', action: 'begin', storeDepth: false } });

        this.loader.addAnimation({
            image: 'finalFbo.color.fbo'
        });

    writerQueue.forEach(animation => {
        if (animation._actualScene) {
            const scene = scenes.find(s => s.name === animation._actualScene);
            if (scene) {
                if (animation.start === undefined) {
                    animation.start = scene.start;
                } else {
                    animation.start += scene.start;
                }
                if (animation.duration === undefined) {
                    animation.duration = scene.duration;
                }
            }
        }
        this.loader.addAnimation(animation);
    });

    this.loader.addAnimation({ fbo: { name: 'finalfinal', action: 'unbind' } });




  this.loader.addAnimation({
    start: 0,
    image: '_embedded/defaultWhite.png',
    color: [{ r: 0, g: 0, b: 0, a: 1 }],

  });

    // 0-4 amiga ball 1:1
    this.loader.addAnimation({
        start: 0 * window.pattern,
        duration: 128 * window.pattern,
        image: 'finalfinal.color.fbo',
        angle: [{ degreesZ: () => Sync.get('AspectRatio:Rotation', 0) }],
        shader: {
            name: 'fakePerspective.fs', variable: [
                { name: "w", value: [() => Sync.get('AspectRatio:width')] },
                { name: "h", value: [() => Sync.get('AspectRatio:height')] },
                { name: "vignetteAmount", value: [0] },
                { name: "vignetteStart", value: [0.75] },
                { name: "vignetteEnd", value: [1.35] },
                { name: "fillBorders", value: [1.0] },

            ]
        }
    });

    this.loader.addAnimation({
        image: ["_embedded/defaultTransparent.png"],
        color: [{ r: 1, g: 1, b: 1, a: 0.05 }]
        , shader: {
            name: "dmxsimulator.fs", variable: [
                { name: "lightColor", value: [() => dmxLightManager?.mockColor || [[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], [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], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]] },
            ]
        }
        , initFunction: () => {

            createDmxLightManager()
        }
        , runFunction: () => {

            const lightTypes = {
                OFF: 0,
                CONSTANT: 1,
                ALTERNATING_FLASHES: 2,
                LEFT_RIGHT: 3,
                RANDOM_FLASHES: 4,
                KLAXON: 5,
            };

            const lightType = Math.floor(Sync.getSyncValue('dmx:type',lightTypes.ALTERNATING_FLASHES));
            const lightMin = Math.floor(Sync.getSyncValue('dmx:lightIdMin',0));
            const lightMax = Math.floor(Sync.getSyncValue('dmx:lightIdMax',dmxLightManager.lightCount));

            const frequence = Sync.getSyncValue('dmx:frequence', 10);

            const intensity = Sync.getSyncValue('dmx:intensity', 1);
            const r = (Sync.getSyncValue('dmx:r', 1) * intensity);
            const g = (Sync.getSyncValue('dmx:g', 1) * intensity);
            const b = (Sync.getSyncValue('dmx:b', 1) * intensity);

            const fadeInStart = Sync.getSyncValue('dmx:fadeInStart', -1);
            const fadeInEnd = Sync.getSyncValue('dmx:fadeInEnd', -1);
            const fadeOutStart = Sync.getSyncValue('dmx:fadeOutStart', dmxLightManager.lightCount);
            const fadeOutEnd = Sync.getSyncValue('dmx:fadeOutEnd', dmxLightManager.lightCount);

 
            const calculateFade = (lightId) => {
                let fade = 1.0;
                if (lightId >= fadeInStart && lightId <= fadeInEnd) {
                    fade = (lightId - fadeInStart) / (fadeInEnd - fadeInStart);
                } else if (lightId >= fadeOutStart && lightId <= fadeOutEnd) {
                    fade = 1.0 - ((lightId - fadeOutStart) / (fadeOutEnd - fadeOutStart));
                } else if (lightId < fadeInStart || lightId > fadeOutEnd) {
                    fade = 0.0;
                }
                return fade;
            };


            if (lightType == lightTypes.RANDOM_FLASHES) {
                for (let i = lightMin; i < lightMax; i++) {
                    let c = Math.floor((Math.random() >= Sync.getSyncValue('dmx:randomBias', 0.5) ? 0xFF : 0x00) * calculateFade(i));
                    dmxLightManager.setColor(c * r, c * g, c * b, i, i + 1);
                }
            } else if (lightType == lightTypes.ALTERNATING_FLASHES) {
                for (let i = lightMin; i < lightMax; i++) {
                    let c = 0x00;
                    if (i % 2 == 0) {
                        c = Math.floor((Math.sin(getSceneTimeFromStart() * frequence) + 1) / 2 * 0xFF);
                    } else {
                        c = Math.floor((Math.cos(getSceneTimeFromStart() * frequence) + 1) / 2 * 0xFF);
                    }
                    c = Math.floor(c * calculateFade(i));
                    dmxLightManager.setColor(c * r, c * g, c * b, i, i + 1);
                }
            } else if (lightType == lightTypes.LEFT_RIGHT) {
                var c = Math.floor((Math.sin(getSceneTimeFromStart() * frequence) + 1) / 2 * 0xFF);
                dmxLightManager.setColor(c * r, c * g, c * b, Math.max(lightMin, 0), Math.min(lightMax, dmxLightManager.lightCount) / 2);
                var c = Math.floor((Math.cos(getSceneTimeFromStart() * frequence) + 1) / 2 * 0xFF);
                dmxLightManager.setColor(c * r, c * g, c * b, Math.max(lightMin, dmxLightManager.lightCount / 2), Math.min(lightMax, dmxLightManager.lightCount));
            } else if (lightType == lightTypes.OFF) {
                dmxLightManager.setColor(0x00, 0x00, 0x00, 0, dmxLightManager.lightCount);
            } else if (lightType == lightTypes.CONSTANT) {
                for (let i = lightMin; i < lightMax; i++) {
                    let c = Math.floor(0xFF * calculateFade(i));
                    dmxLightManager.setColor(c * r, c * g, c * b, i, i + 1);
                }
            } else if (lightType == lightTypes.KLAXON) {
                var c = Math.floor((Math.sin(getSceneTimeFromStart() * frequence) + 1) / 2 * 0xFF);
                for (let i = lightMin; i < lightMax; i++) {
                    let bias = (i % 2 == 0) ? Sync.getSyncValue('dmx:klaxonBias', 0.5) : (1 - Sync.getSyncValue('dmx:klaxonBias', 0.5));
                    let finalC = Math.floor(c * bias * calculateFade(i));
                    dmxLightManager.setColor(finalC * r, 0x00, 0x00, i, i + 1);
                }
            }

            dmxLightManager.sendData();
        }
        , deinitFunction: () => {
            if (dmxLightManager && dmxLightManager.isInitialized()) {
                dmxLightManager.setColor(0x00, 0x00, 0x00, 0, dmxLightManager.lightCount);
                dmxLightManager.sendData();
                dmxLightManager.deinit();
                dmxLightManager = void null; //reload will fuck up without this
            }
        }
    });
};

function GetNextCutTime(actualTimeInMs) {
    const segs = window.segments;
    if (!segs || segs.length === 0) return null;

    if (window.nextSegmentIndex >= segs.length) {
        if(window.wrapped == false)
        {
            window.nextSegmentIndex = 0; // wrap if needed
            window.wrapped = true;
        }
        else
            return null;
    }

    const seg = segs[window.nextSegmentIndex];
    const segActualMs = seg.actualTime * 1000; // convert sec → ms

    if (actualTimeInMs >= segActualMs) {
        const cutMs = seg.cutTime * 1000; // convert sec → ms
        window.nextSegmentIndex++;
        console.log("cut time " + cutMs + " ms, next segment: " + window.nextSegmentIndex);
        return cutMs;
    }
    return null;
}

window.segments = [
  { "actualTime": 0.000000, "cutTime": 171.130435 },
  { "actualTime": 16.564279, "cutTime": 50.086957 },
  { "actualTime": 24.912105, "cutTime": 63.130435 },
  { "actualTime": 28.564279, "cutTime": 91.304348 },
  { "actualTime": 41.216291, "cutTime": 0.813847 },
  { "actualTime": 52.042540, "cutTime": 22.434783 },
  { "actualTime": 62.921459, "cutTime": 106.434783 },
  { "actualTime": 72.312763, "cutTime": 138.073797 },
  { "actualTime": 85.250763, "cutTime": 38.527720 },
  { "actualTime": 96.000000, "cutTime": 121.043478 },
  { "actualTime": 105.574386, "cutTime": 66.782609 },
  { "actualTime": 126.443951, "cutTime": 187.826087 }
]



