/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2026 Rainbownapkin and the TTN Community

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program.  If not, see <https://www.gnu.org/licenses/>.*/

/**
 * Class representing the settings panel
 * @extends panelObj
 */
class settingsPanel extends panelObj{
    /**
     * Instantiates a new Panel Object
     * @param {channel} client - Parent client Management Object
     * @param {Document} panelDocument - Panel Document
     */
    constructor(client, panelDocument){
        super(client, "Client Settings", "/panel/settings", panelDocument);
    }

    closer(){
    }

    docSwitch(){
        /**
         * Youtube Source Selector
         */
        this.youtubeSource = this.panelDocument.querySelector("#settings-panel-youtube-source select");

        /**
         * Internet Archive CDN Server Input
         */
        this.iaCDN = this.panelDocument.querySelector("#settings-panel-ia-server input");

        /**
         * Syncronization Tolerance Input
         */
        this.syncTolerance = this.panelDocument.querySelector("#settings-panel-sync-tolerance input");

        /**
         * Livestream Syncronization Tolerance Input
         */
        this.liveSyncTolerance = this.panelDocument.querySelector("#settings-panel-live-sync-tolerance input");

        /**
         * Syncronization Tolerance Delta
         */
        this.syncDelta = this.panelDocument.querySelector("#settings-panel-sync-delta input");

        /**
         * Chat Width Minimum while Size-Locked to Media Aspect Ratio
         */
        this.chatWidthMinimum = this.panelDocument.querySelector("#settings-panel-min-chat-width input");

        /**
         * Disable Portrait/Mobile Layout
         */
        this.disablePortrait = this.panelDocument.querySelector("#settings-panel-disable-portrait input");

        /**
         * Audible Ping on PM Recieved
         */
        this.rxPMSound = this.panelDocument.querySelector("#settings-panel-ping-on-pm-rx select");

        /**
         * Audible Ping on PM Transmit
         */
        this.txPMSound = this.panelDocument.querySelector("#settings-panel-ping-on-pm-tx input");

        /**
         * Audible Ping on new PM sesh
         */
        this.newSeshSound = this.panelDocument.querySelector("#settings-panel-ping-on-new-sesh input");

        /**
         * Audible Ping on old PM sesh
         */
        this.endSeshSound = this.panelDocument.querySelector("#settings-panel-ping-on-end-sesh input");

        this.renderSettings();
        this.setupInput();

        //Call derived method
        super.docSwitch();
    }

    /**
     * Defines input-related event handlers
     */
    setupInput(){
        this.youtubeSource.addEventListener('change', this.updateYoutubeSource.bind(this));
        this.iaCDN.addEventListener('keydown', this.updateIACDN.bind(this));
        this.syncTolerance.addEventListener('change', this.updateSyncTolerance.bind(this));
        this.liveSyncTolerance.addEventListener('change', this.updateLiveSyncTolerance.bind(this));
        this.syncDelta.addEventListener('change', this.updateSyncDelta.bind(this));
        this.chatWidthMinimum.addEventListener('change', this.updateChatWidthMinimum.bind(this));
        this.disablePortrait.addEventListener('change', this.updateDisablePortrait.bind(this));
        this.rxPMSound.addEventListener('change', this.updateRXPMSound.bind(this));
        this.txPMSound.addEventListener('change', this.updateTXPMSound.bind(this));
        this.newSeshSound.addEventListener('change', this.updateNewPMSeshSound.bind(this));
        this.endSeshSound.addEventListener('change', this.updateEndPMSeshSound.bind(this));
    }

    /**
     * Renders actual user settings state into panel display
     */
    renderSettings(){
        this.youtubeSource.value = localStorage.getItem("ytPlayerType");
        this.iaCDN.value = localStorage.getItem("IACDN");
        this.syncTolerance.value = localStorage.getItem("syncTolerance");
        this.liveSyncTolerance.value = localStorage.getItem("liveSyncTolerance");
        this.syncDelta.value = localStorage.getItem("syncDelta");
        this.chatWidthMinimum.value = localStorage.getItem("chatWidthMin");
        this.disablePortrait.checked = localStorage.getItem("disablePortrait") == 'true';
        this.rxPMSound.value = localStorage.getItem('rxPMSound');
        this.txPMSound.checked = localStorage.getItem('txPMSound') == 'true';
        this.newSeshSound.checked = localStorage.getItem('newSeshSound') == 'true';
        this.endSeshSound.checked = localStorage.getItem('endSeshSound') == 'true';
    }

    /**
     * Event handler for Youtube Source selector
     */
    updateYoutubeSource(){
        localStorage.setItem("ytPlayerType", this.youtubeSource.value);
        client.processConfig("ytPlayerType", this.youtubeSource.value);
    }

    /**
     * Event handler for Internet Archive CDN Server input
     * @param {Event} event - Event handed down by event listener
     */
    updateIACDN(event){
        //If we hit enter
        if(event.key == "Enter"){
            //If we have an invalid server string
            if(!(this.iaCDN.value.match(/^(ia|dn)[0-9]{6}\...$/g) || this.iaCDN.value == "")){
                //reset back to what was set before
                this.iaCDN.value = localStorage.getItem('IACDN');

                //BAIL!
                return;
            }

            localStorage.setItem("IACDN", this.iaCDN.value);
            client.processConfig("IACDN", this.iaCDN.value);
        }
    }

    /**
     * Handles Sync Tolerance Changes
     */
    updateSyncTolerance(){
        //If sync tolerance was set to a negative number
        if(this.syncTolerance.value < 0){
            //Reset setting back to stored value
            this.syncTolerance.value = localStorage.getItem('syncTolerance');

            //BAIL!
            return;
        }

        localStorage.setItem("syncTolerance", this.syncTolerance.value);
        client.processConfig("syncTolerance", this.syncTolerance.value);
    }

    /**
     * Handles Live Sync Tolerance Changes
     */
    updateLiveSyncTolerance(){
        //If sync tolerance was set to a negative number
        if(this.liveSyncTolerance.value < 0){
            //Reset setting back to stored value
            this.liveSyncTolerance.value = localStorage.getItem('liveSyncTolerance');

            //BAIL!
            return;
        }

        localStorage.setItem("liveSyncTolerance", this.liveSyncTolerance.value);
        client.processConfig("liveSyncTolerance", this.liveSyncTolerance.value);
    }

    /**
     * Handles Sync Delta Changes
     */
    updateSyncDelta(){
        //If sync tolerance was set to a negative number
        if(this.syncDelta.value < 0){
            //Reset setting back to stored value
            this.syncDelta.value = localStorage.getItem('syncDelta');

            //BAIL!
            return;
        }

        localStorage.setItem("syncDelta", this.syncDelta.value);
        client.processConfig("syncDelta", this.syncDelta.value);
    }

    /**
     * Handles Chat Width minimum Changes
     */
    updateChatWidthMinimum(){
        //If sync tolerance was set to a negative number
        if(this.chatWidthMinimum.value < 0 || this.chatWidthMinimum > 100){
            //Reset setting back to stored value
            this.syncDelta.value = localStorage.getItem('chatWidthMin');

            //BAIL!
            return;
        }

        localStorage.setItem("chatWidthMin", this.chatWidthMinimum.value);
        client.processConfig("chatWidthMin", this.chatWidthMinimum.value);
    }

    /**
     * Handles change toggle of disable/enable portrait
     */
    updateDisablePortrait(){
        localStorage.setItem('disablePortrait', this.disablePortrait.checked);
        client.processConfig("disablePortrait", this.disablePortrait.checked);
    }

    /**
     * Handles changes to RX PM Sound setting
     */
    updateRXPMSound(){
        localStorage.setItem('rxPMSound', this.rxPMSound.value);
        client.processConfig("rxPMSound", this.rxPMSound.value);
    }

    /**
     * Handles changes to TX PM Sound setting
     */
    updateTXPMSound(){
        localStorage.setItem('txPMSound', this.txPMSound.checked);
        client.processConfig("txPMSound", this.txPMSound.checked);
    }

    /**
     * Handles changes to New PM Sesh Sound setting
     */
    updateNewPMSeshSound(){
        localStorage.setItem('newSeshSound', this.newSeshSound.checked);
        client.processConfig("newSeshSound", this.newSeshSound.checked);
    }

    /**
     * Handles changes to Old PM Sesh Sound setting
     */
    updateEndPMSeshSound(){
        localStorage.setItem('endSeshSound', this.endSeshSound.checked);
        client.processConfig("endSeshSound", this.endSeshSound.checked);
    }
}