// Libraries
import 'hammerjs';
// Stencil
import { h } from "@stencil/core";
// Tools
import { MarkdownTool } from '../../../tools/markdown-tool';
export class AudioPlayer {
    constructor() {
        // Internal properties
        this.webAudioGetter = null;
        this.progressIntervalId = null;
        this.lastDeltaX = 0;
        this.draggingPoint = false;
        this.waitProgressionBarCount = 0;
        // Props
        this.contentId = '000000'; // A specific id for this audio
        this.src = '';
        this.audioTitle = ''; // To Delete
        this.type = '';
        this.script = '';
        this.openTranscript = true;
        // States
        this.webAudio = null;
        this.audioPlaying = false;
        this.currentProgress = 0; // The current progression of the audio in %
        this.currentAudioTimeFormatted = '00:00';
        this.totalAudioTime = 0;
        this.totalAudioTimeFormatted = '00:00';
        this.transcriptDisplayed = true;
    }
    ////////////////////////////////////////////////////////////////
    // Life Cycle
    ////////////////////////////////////////////////////////////////
    /**
     * Override
     */
    componentWillLoad() {
        this.referenceWebAudio();
        this.setupPointControl();
        if (this.openTranscript)
            this.transcriptDisplayed = true;
    }
    ////////////////////////////////////////////////////////////////
    // User Interactions
    ////////////////////////////////////////////////////////////////
    /**
     * The user clicks on the play/pause button
     */
    interactWithAudio() {
        if (this.audioPlaying) {
            this.webAudio.pause();
            this.audioPlaying = false;
            if (this.totalAudioTime > 0)
                this.updateAudioProgress(true);
        }
        else {
            this.webAudio.play();
            this.audioPlaying = true;
            this.audioPlayed.emit(true);
            if (this.totalAudioTime > 0)
                this.updateAudioProgress(false);
        }
    }
    /**
     * The suer wants to display the transcript
     */
    displayTranscript() {
        this.transcriptDisplayed = true;
    }
    ////////////////////////////////////////////////////////////////
    // Private Methods
    ////////////////////////////////////////////////////////////////
    /**
     * Return the WebAudio component
     */
    referenceWebAudio() {
        let id = setInterval(() => {
            console.log("looking for Web audio");
            this.webAudio = document.getElementById(this.contentId);
            if (this.webAudio) {
                if (this.webAudio.duration > 0) {
                    this.totalAudioTime = this.webAudio.duration;
                    this.totalAudioTimeFormatted = this.formatAudioTime(this.totalAudioTime);
                }
                console.log("web audio found");
                clearInterval(id);
            }
        }, 100);
    }
    /**
     * Setup the touch controls on the point to update the position in the audio
     */
    setupPointControl() {
        let id = setInterval(() => {
            if (this.totalAudioTime > 0) {
                const progressionBar = document.getElementById(this.contentId + '_progression-bar');
                if (progressionBar) {
                    // Get the bar width
                    const barWidth = progressionBar.offsetWidth;
                    // If the progression bar is here, so it's the point
                    const point = progressionBar.getElementsByClassName('progress-point')[0];
                    // Initialize recognizers when dragging the point
                    var hammerPan = new Hammer(point, {});
                    hammerPan.on('pan', (ev) => {
                        // Inhibit currentTime update
                        this.draggingPoint = true;
                        // Compute the relative deltaX
                        const relDeltaX = ev.deltaX - this.lastDeltaX;
                        this.lastDeltaX = ev.deltaX;
                        // Compute the relative progression in percentage
                        const relProgression = relDeltaX / barWidth * 100;
                        // Apply it to the current progress depending on the bounds
                        if (this.currentProgress + relProgression < 0) {
                            this.currentProgress = 0;
                        }
                        else if (this.currentProgress + relProgression > 100) {
                            this.currentProgress = 100;
                        }
                        else {
                            this.currentProgress = this.currentProgress + relProgression;
                        }
                        // Update the current audio time format
                        this.currentAudioTimeFormatted = this.formatAudioTime(this.currentProgress / 100 * this.totalAudioTime);
                        if (ev.isFinal) {
                            this.webAudio.currentTime = this.currentProgress / 100 * this.totalAudioTime;
                            this.lastDeltaX = 0;
                            this.draggingPoint = false;
                        }
                    });
                    // Initialize this recognizer when tapping on the progress bar
                    var hammerTap = new Hammer(progressionBar, {});
                    hammerTap.on('tap', (ev) => {
                        const diff = ev.center.x - progressionBar.getBoundingClientRect().left;
                        this.currentProgress = diff / progressionBar.offsetWidth * 100;
                        // Update the current audio time format
                        this.currentAudioTimeFormatted = this.formatAudioTime(this.currentProgress / 100 * this.totalAudioTime);
                        this.webAudio.currentTime = this.currentProgress / 100 * this.totalAudioTime;
                    });
                    clearInterval(id);
                }
            }
            // Clear the interval after a certain time
            if (this.waitProgressionBarCount > 50) {
                console.log("clear second interval");
                clearInterval(id);
            }
            else
                ++this.waitProgressionBarCount;
        }, 100);
    }
    /**
     * Compute the audio currentTime progress in percentage
     * @param stopProgressUpdate whether it has to stop the progress update
     */
    updateAudioProgress(stopProgressUpdate) {
        if (stopProgressUpdate) {
            clearInterval(this.progressIntervalId);
            return;
        }
        // Set a new interval to update every quarter second the current progress
        this.progressIntervalId = setInterval(() => {
            if (!this.draggingPoint) {
                const currentTime = this.webAudio.currentTime;
                this.currentAudioTimeFormatted = this.formatAudioTime(currentTime);
                this.currentProgress = Math.floor(currentTime / this.totalAudioTime * 100);
                if (this.currentProgress === 100) {
                    this.currentProgress = 0;
                    this.currentAudioTimeFormatted = this.formatAudioTime(this.currentProgress);
                    this.interactWithAudio();
                    clearInterval(this.progressIntervalId);
                }
            }
        }, 250);
    }
    ////////////////////////////////////////////////////////////////
    // Utils
    ////////////////////////////////////////////////////////////////
    /**
     * Format an audio duration into a readable format
     * composed of minutes and seconds {00:00}
     * @param length
     */
    formatAudioTime(length) {
        let minutes = '' + Math.floor(length / 60);
        if (minutes.length == 1)
            minutes = '0' + minutes;
        let seconds = '' + Math.floor(length % 60);
        if (seconds.length == 1)
            seconds = '0' + seconds;
        return minutes + ':' + seconds;
    }
    ////////////////////////////////////////////////////////////////
    // Render
    ////////////////////////////////////////////////////////////////
    render() {
        return (h("div", null,
            h("audio", { id: this.contentId },
                h("source", { src: this.src, type: this.type })),
            this.webAudio != null
                ? h("div", { class: 'audio-control-container' },
                    h("div", { class: 'audio-button-container' },
                        h("ion-button", { color: "dark", class: "audio-button-controller", onClick: () => this.interactWithAudio() }, this.audioPlaying
                            ? h("ion-icon", { name: 'pause', color: 'light' })
                            : h("ion-icon", { name: 'play', color: 'light' })),
                        "}"),
                    this.totalAudioTime > 0 &&
                        h("div", { class: 'audio-info-container' },
                            h("div", { class: 'audio-duration-container' },
                                h("p", null, this.currentAudioTimeFormatted),
                                h("p", null, this.totalAudioTimeFormatted)),
                            h("div", { id: this.contentId + '_progression-bar', class: 'audio-progression-container' },
                                h("div", { class: 'complete-bar' }),
                                h("div", { style: { width: this.currentProgress + '%' }, class: 'progress-bar' }),
                                h("div", { style: { left: 'calc(' + this.currentProgress + '% - 4px)' }, class: 'progress-point' }))))
                : '',
            this.script && !this.transcriptDisplayed &&
                h("ion-button", { size: 'small', color: 'tertiary', class: 'audio-transcript-button', onClick: () => this.displayTranscript() }, "Transcript"),
            this.script && this.transcriptDisplayed &&
                h("div", { class: 'text-container', innerHTML: MarkdownTool.render(this.script) })));
    }
    static get is() { return "audio-player"; }
    static get originalStyleUrls() { return {
        "$": ["audio-player.scss"]
    }; }
    static get styleUrls() { return {
        "$": ["audio-player.css"]
    }; }
    static get properties() { return {
        "contentId": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "content-id",
            "reflect": false,
            "defaultValue": "'000000'"
        },
        "src": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "src",
            "reflect": false,
            "defaultValue": "''"
        },
        "audioTitle": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "audio-title",
            "reflect": false,
            "defaultValue": "''"
        },
        "type": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "type",
            "reflect": false,
            "defaultValue": "''"
        },
        "script": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "script",
            "reflect": false,
            "defaultValue": "''"
        },
        "openTranscript": {
            "type": "boolean",
            "mutable": false,
            "complexType": {
                "original": "boolean",
                "resolved": "boolean",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "open-transcript",
            "reflect": false,
            "defaultValue": "true"
        },
        "color": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "color",
            "reflect": false
        }
    }; }
    static get states() { return {
        "webAudio": {},
        "audioPlaying": {},
        "currentProgress": {},
        "currentAudioTimeFormatted": {},
        "totalAudioTime": {},
        "totalAudioTimeFormatted": {},
        "transcriptDisplayed": {}
    }; }
    static get events() { return [{
            "method": "audioPlayed",
            "name": "audioPlayed",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "complexType": {
                "original": "boolean",
                "resolved": "boolean",
                "references": {}
            }
        }]; }
}
