const oscilloscopeFinal = p => {
    let analyzerNode = null;
    let samples = null;

    let audioElement = (() => {
        return document.querySelector('audio#amen');
    })();

    let audioContext = (() => {
        const audioContext = new AudioContext();
        const track =
            audioContext.createMediaElementSource(audioElement);
        analyzerNode = audioContext.createAnalyser();

        track.connect(analyzerNode)
             .connect(audioContext.destination);

        return audioContext;
    })();

    p.setup = () => {
        const sketchContainer = document.querySelector('#oscilloscopeFinal');
        const canvasWidth = parseFloat(getComputedStyle(sketchContainer).width);
        let canvas = p.createCanvas(canvasWidth, 250);
        canvas.canvas.removeAttribute('style');
        sketchContainer.appendChild(canvas.canvas);

        p.pixelDensity(p.displayDensity());

        samples = new Float32Array(p.width);

        const playPauseButton = p.createButton('Play');
        playPauseButton.position(10, 10);

        const playPauseButtonElement = playPauseButton.elt;
        playPauseButtonElement.dataset.playing = 'false';
        playPauseButtonElement.addEventListener('click', function() {
            if (audioContext.state === 'suspended') {
                audioContext.resume();
            }

            if (this.dataset.playing === 'false') {
                audioElement.play();
                this.dataset.playing = 'true';
                this.innerHTML = '<span>Pause</span>';
            } else if (this.dataset.playing === 'true') {
                audioElement.pause();
                this.dataset.playing = 'false';
                this.innerHTML = '<span>Play</span>';
            }
        });

        audioElement.addEventListener('ended', function() {
            playPauseButtonElement.dataset.playing = 'false';
            playPauseButtonElement.innerHTML = '<span>Play</span>';
        }, false);
    };

    p.draw = () => {
        const amplitude = p.height / 2;
        const axis = p.height / 2;

        const blue = p.color(24, 62, 140);
        const purple = p.color(255, 0, 255);

        p.background(255);

        if (analyzerNode) {
            analyzerNode.getFloatTimeDomainData(samples);
        }

        for (let i = 0; i < samples.length; i++) {
            const sampleValue = samples[i];
            const absSampleValue = Math.abs(sampleValue);

            const weight = p.lerp(2, 12, 1.5 * absSampleValue);
            p.strokeWeight(sampleValue === 0 ? 1 : weight);
            p.stroke(p.lerpColor(blue, purple, absSampleValue));

            p.point(i, axis + amplitude * sampleValue);
        }
    };

    p.mouseClicked = () => {
        p.clear();
    };
};

new p5(oscilloscopeFinal, 'oscilloscopeFinal');
