/*Canopy - The next generation of stoner streaming software
Copyright (C) 2024-2025 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 cPanel{
    constructor(client){
        //Client Object
        this.client = client;

        //Panel Objects
        this.activePanel = null;
        this.pinnedPanel = null;
        this.poppedPanels = [];

        //ClickDragger Objects
        this.activePanelDragger = new canopyUXUtils.clickDragger("#cpanel-active-drag-handle", "#cpanel-active-div", false, null, false);
        this.pinnedPanelDragger = new canopyUXUtils.clickDragger("#cpanel-pinned-drag-handle", "#cpanel-pinned-div", false, this.client.chatBox.clickDragger);

        //Element Nodes
        //Active Panel
        this.activePanelDiv = document.querySelector("#cpanel-active-div");
        this.activePanelTitle = document.querySelector("#cpanel-active-title");
        this.activePanelDoc = document.querySelector("#cpanel-active-doc");
        this.activePanelPinIcon = document.querySelector("#cpanel-active-pin-icon");
        this.activePanelPopoutIcon = document.querySelector("#cpanel-active-popout-icon");
        this.activePanelCloseIcon = document.querySelector("#cpanel-active-close-icon");
        //Pinned Panel
        this.pinnedPanelDiv = document.querySelector("#cpanel-pinned-div");
        this.pinnedPanelTitle = document.querySelector("#cpanel-pinned-title");
        this.pinnedPanelDoc = document.querySelector("#cpanel-pinned-doc");
        this.pinnedPanelUnpinIcon = document.querySelector("#cpanel-pinned-unpin-icon");
        this.pinnedPanelPopoutIcon = document.querySelector("#cpanel-pinned-popout-icon");
        this.pinnedPanelCloseIcon = document.querySelector("#cpanel-pinned-close-icon");

        this.setupInput();
    }

    setupInput(){
        this.activePanelCloseIcon.addEventListener("click", this.hideActivePanel.bind(this));
        this.activePanelPinIcon.addEventListener("click", this.pinPanel.bind(this));
        this.activePanelPopoutIcon.addEventListener("click", this.popActivePanel.bind(this));
        this.pinnedPanelCloseIcon.addEventListener("click", this.hidePinnedPanel.bind(this));
        this.pinnedPanelUnpinIcon.addEventListener("click", this.unpinPanel.bind(this));
        this.pinnedPanelPopoutIcon.addEventListener("click", this.popPinnedPanel.bind(this));
    }

    async setActivePanel(panel, panelBody){
        //Set active panel
        this.activePanel = panel;

        //Grab panel hypertext content and load it into div
        this.activePanelDoc.innerHTML = (panelBody == null || panelBody == "") ? await this.activePanel.getPage() : panelBody;
          

        //Display panel
        this.activePanelDiv.style.display = "flex";
        this.activePanelTitle.textContent = this.activePanel.name;

        //Call panel initialization function
        this.activePanel.panelDocument = this.activePanelDoc;
        this.activePanel.docSwitch();
    }

    hideActivePanel(event, keepAlive = false){
        if(!keepAlive){
            this.activePanel.closer();
        }

        //Hide the panel
        this.activePanelDiv.style.display = "none";
        //Clear out the panel
        this.activePanelDoc.innerHTML = '';
        //Set active panel to null
        this.activePanel = null;
    }

    pinPanel(){
        this.setPinnedPanel(this.activePanel, this.activePanelDoc.innerHTML);
        this.hideActivePanel(null, true);
    }

    popActivePanel(){
        this.popPanel(this.activePanel, this.activePanelDoc.innerHTML);
        this.hideActivePanel(null, true);
    }

    async setPinnedPanel(panel, panelBody){
        //Set pinned panel
        this.pinnedPanel = panel;

        //Set Title
        this.pinnedPanelTitle.textContent = this.pinnedPanel.name;

        //Grab panel hypertext content and load it into div
        this.pinnedPanelDoc.innerHTML = (panelBody == null || panelBody == "") ? await this.pinnedPanel.getPage() : panelBody;

        //Display panel
        this.pinnedPanelDiv.style.display = "flex";

        //Call panel initialization function
        this.pinnedPanel.panelDocument = this.pinnedPanelDoc;
        this.pinnedPanel.docSwitch();

        //Resize to window/content
        this.pinnedPanelDragger.fixCutoff();
    }

    hidePinnedPanel(event, keepAlive = false){
        this.pinnedPanelDiv.style.display = "none";

        if(!keepAlive){
            this.pinnedPanel.closer();
        }

        this.pinnedPanel = null;
    }

    unpinPanel(){
        this.setActivePanel(this.pinnedPanel, this.pinnedPanelDoc.innerHTML);
        this.hidePinnedPanel(null, true);
    }

    popPinnedPanel(){
        this.popPanel(this.pinnedPanel, this.pinnedPanelDoc.innerHTML);
        this.hidePinnedPanel(null, true);
    }

    popPanel(panel, panelBody){
        var newPanel = new poppedPanel(panel, panelBody, this)

        this.poppedPanels.push(newPanel);
    }

}

class panelObj{
    constructor(client, name = "Placeholder Panel", pageURL = "/panel/placeholder", panelDocument = window.document){
        this.name = name;
        this.pageURL = pageURL;
        this.panelDocument = panelDocument;
        this.ownerDoc = this.panelDocument.ownerDocument == null ? this.panelDocument : this.panelDocument.ownerDocument; 
        this.client = client;
    }

    async getPage(){
        var response = await fetch(this.pageURL,{
            method: "GET",
        });

        return await response.text();
    }

    docSwitch(){
        //Set owner doc
        this.ownerDoc = this.panelDocument.ownerDocument == null ? this.panelDocument : this.panelDocument.ownerDocument; 
    }

    closer(){
    }
}

class poppedPanel{
    constructor(panel, panelBody, cPanel){
        //Set Panel Object
        this.panel = panel;
        //Set Panel Body
        this.panelBody = panelBody;
        //Set Window Placeholder
        this.window = null;

        //Element Node Placeholders
        this.pinnedPanelDiv = null;
        this.pinnedPanelTitle = null;
        this.pinnedPanelDoc = null;
        this.pinnedPanelCloseIcon = null;

        //Functions
        this.cPanel = cPanel;

        this.keepAlive = false;

        //Continue constructor asynchrnously
        this.asyncConstructor();
    }

    async asyncConstructor(){
        //Set panel body properly
        this.panelBody = (this.panelBody == null || this.panelBody == "") ? await this.panel.getPage() : this.panelBody;

        //Pop the panel
        this.popContainer();
    }

    popContainer(){
        //Set Window Object
        this.window = window.open("/panel/popoutContainer","",`menubar=no,height=850,width=600`);
        this.window.addEventListener("load", this.fillContainer.bind(this)); 
    }

    fillContainer(){
        //Set Element Nodes
        this.panelDiv = this.window.document.querySelector("#cpanel-div");
        this.panelTitle = this.window.document.querySelector("#cpanel-title");
        this.panelDoc = this.window.document.querySelector("#cpanel-doc");
        this.panelPopinIcon = this.window.document.querySelector("#cpanel-popin-icon");
        this.panelPinIcon = this.window.document.querySelector("#cpanel-pin-icon");

        //Set Window Title
        this.window.document.title = this.window.document.title.replace("NULL_POPOUT", `${this.panel.name} (${client.channelName})`);

        //Set Panel Content
        this.panelTitle.innerText = this.panel.name;
        this.panelDoc.innerHTML = this.panelBody;

        //Set panel object document and call the related function
        this.panel.panelDocument = this.window.document;
        this.panel.docSwitch();

        this.setupInput();
    }

    setupInput(){
        this.panelPopinIcon.addEventListener("click", this.unpop.bind(this));
        this.panelPinIcon.addEventListener("click", this.pin.bind(this));
        this.window.addEventListener("unload", this.closer.bind(this));
    }

    closer(){
        if(!this.keepAlive){
            this.panel.closer();
        }

        this.cPanel.poppedPanels.splice(this.cPanel.poppedPanels.indexOf(this),1);
    }

    unpop(){
        //Set active panel
        this.cPanel.setActivePanel(this.panel, this.panelDoc.innerHTML);

        this.keepAlive = true;

        //Close the popped window
        this.window.close();
    }

    pin(){
        this.cPanel.setPinnedPanel(this.panel, this.panelDoc.innerHTML);

        this.keepAlive = true;

        this.window.close();
    }

}