window.__pad = {
    // generic infos
    padIsMain: false,
    padID: "",
    workspaceID: "",
    loopCounter: 0,

    _padTitle: "",
    _padPrimaryIcon: "",
    _padSecondaryIcon: "",

    // Promises
    _padPromises: {},
    // generates a unique id, not obligator a UUID
    _padGenerateUUID: function() {
        var d = new Date().getTime();
        var uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
            var r = (d + Math.random() * 16) % 16 | 0;
            d = Math.floor(d / 16);
            return (c == "x" ? r : (r & 0x3) | 0x8).toString(16);
        });
        return uuid;
    },
    _padGenPromise: function() {
        var promise = new Promise(function(resolve, reject) {
            // we generate a unique id to reference the promise later
            // from native function
            var promiseId = this._padGenerateUUID();
            // save reference to promise in the global variable
            this._padPromises[promiseId] = {
                resolve,
                reject
            };
        });
        return promise;
    },
    // @param promiseId - id of the promise stored in global variable promises
    padResolvePromise: function(promiseId, data, error) {
        if (error) {
            this._padPromises[promiseId].reject(data);
        } else {
            this._padPromises[promiseId].resolve(data);
        }
        // remove referenfe to stored promise
        delete this._padPromises[promiseId];
    },

    // Setups
    // this funciton is called by native methods
    _setupNativeFuncs: function() {
        const self = this

        // Notification
        window.Notification.permission = "granted";
        window.Notification.requestPermission();

        window.oldAudio = window.Audio;
        window.newAudio = function(s) {
            var a = new window.oldAudio(s);
            var oldPlay = a.play.bind(a);
            a.play = function() {
                console.log(a);
                if (window.__pad.recipeShouldPlaySound(self, a.src)) {
                    oldPlay();
                }
            };
            return a;
        };
        window.Audio = newAudio;
    },

    // Style
    _loadStyle: function() {
        const css = `
                ::-webkit-scrollbar {
                    width: 4px !important;
                    height: 4px !important;
                }
                ::-webkit-scrollbar-button {
                    width: 0px !important;
                    height: 0px !important;
                }
                ::-webkit-scrollbar-thumb {
                    background: #929292;
                    border: 0px none #ffffff;
                    border-radius: 50px;
                }
                ::-webkit-scrollbar-track {
                    background: transparent;
                    border: 0px none #ffffff;
                    border-radius: 50px;
                    margin: 20px;
                }
                ::-webkit-scrollbar-corner {
                   background: transparent;
                }
                `;
        var scrollbarStyle = document.createElement('style');
        scrollbarStyle.type = 'text/css';
        scrollbarStyle.innerHTML = css;
        document.body.appendChild(scrollbarStyle);
    },
    _updateMinWidth: function() {
        const minWidth = this.recipeGetMinWidth(this);
        this.setMinWidth(minWidth);
    },

    // Observer
    _setupObservers: function() {

    },

    // Loop
    _loopTimer: undefined,
    _startLoop: function() {
        if (this._loopTimer !== undefined) {
            clearInterval(this._loopTimer);
        }
        this._loopTimer = setInterval(() => this.performLoop(), 2000);
    },
    _stopLoop: function() {
        if (this._loopTimer !== undefined) {
            clearInterval(this._loopTimer);
            this._loopTimer = undefined
        }
    },

    // handlers
    performStart: function() {
        // Setup native funcs
        this._setupNativeFuncs();
        // Load custom recipe
        if (window.__loadRecipe !== undefined) {
            window.__loadRecipe(this);
        }
        // Load start funcs
        this.recipeOnStart(this)
    },
    performLoad: function() {
        this._loadStyle();
        this._startLoop();
        this._updateMinWidth();
        this.recipeOnLoad(this);
    },
    performLoop: function() {
        // Check Title
        let title = this.recipeGetTitle(this);
        if (title === "") {
            title = document.title
        }
        if (title !== this._padTitle) {
            this._padTitle = title
            this.setNewTitle(this._padTitle);
        }

        // Check Icon
        let primaryIcon = this.recipeGetPrimaryIcon(this);
        if (primaryIcon !== "" && primaryIcon !== this._padPrimaryIcon) {
            this._padPrimaryIcon = primaryIcon;
            this.setNewIcon(this._padPrimaryIcon, true);
        }
        let secondaryIcon = this.recipeGetSecondaryIcon(this);
        if (secondaryIcon !== "" && secondaryIcon !== this._padSecondaryIcon) {
            this._padSecondaryIcon = secondaryIcon;
            this.setNewIcon(this._padSecondaryIcon, false);
        }

        // Badge Level
        let passiveBadge = this.recipeGetPassiveBadge(this);
        if (passiveBadge > 0) {
            this.setNewPassiveBadge(passiveBadge);
        }

        // Other loops
        this.recipeOnLoop(this);

        // Add Counter
        this.loopCounter += 1;
    },
    performUnload: function() {
        this._stopLoop();
        this.recipeOnUnload(this)
    },


    setNewTitle: function(title) {
        if (this.padID === "") {
            return
        }
        window.webkit.messageHandlers.setNewTitle.postMessage({
            padID: this.padID,
            title: title
        });
    },
    setNewIcon: function(iconURL, isPrimary) {
        if (this.padID === "") {
            return
        }
        window.webkit.messageHandlers.setNewIcon.postMessage({
            padID: this.padID,
            iconURL: iconURL,
            isPrimary: isPrimary
        });
    },
    setNewPassiveBadge: function(badgeLevel) {
        if (this.padID === "") {
            return
        }
        window.webkit.messageHandlers.setNewPassiveBadge.postMessage({
            padID: this.padID,
            badgeLevel: badgeLevel
        });
    },
    setPopupPad: function() {
        if (this.padID === "") {
            return
        }
        window.webkit.messageHandlers.setPopupPad.postMessage({
            padID: this.padID
        });
    },
    setMinWidth: function(minWidth) {
        if (this.padID === "") {
            return
        }
        window.webkit.messageHandlers.setMinWidth.postMessage({
            padID: this.padID,
            minWidth: minWidth
        });
    },
    getBestIcon: function() {
        var icons = Array.prototype.slice.call(document.head.querySelectorAll('link[rel$=icon]'))
        if (icons.length > 0) {
            var bestIconSrc = ""
            var bestIconSize = 0
            for (var i = icons.length - 1; i >= 0; i--) {
                if (icons[i].sizes !== undefined) {
                    
                }
            }
        }
    },

    // recipe handlers
    recipeOnStart: function(self) {
        return
    },
    recipeOnLoad: function(self) {
        return
    },
    recipeOnLoop: function(self) {
        return
    },
    recipeOnUnload: function(self) {
        return
    },
    recipeShouldPlaySound: function(self, soundPath) {
        return true;
    },
    recipeGetPrimaryIcon: function(self) {
        if (self._padPrimaryIcon) {
            return self._padPrimaryIcon;
        }

        // check is local file
        if (window.location.href.startsWith("file://")) {
            return "";
        }

        var favicon = undefined;
        var nodeList = document.getElementsByTagName("link");
        for (var i = 0; i < nodeList.length; i++)
        {
            if((nodeList[i].getAttribute("rel") == "icon")||(nodeList[i].getAttribute("rel") == "shortcut icon"))
            {
                favicon = nodeList[i].getAttribute("href");
                break;
            }
        }

        if (favicon !== undefined) {
            if (favicon.startsWith("data:image")) {
                // Let it be
            } else if (favicon.startsWith("//")) {
                favicon = window.location.protocol + favicon;
            } else if (favicon.startsWith("/")) {
                favicon = window.location.origin + favicon;
            } else if (!favicon.startsWith("http")) {
                favicon = window.location.origin + "/" + favicon;
            }
        } else {
            favicon = window.location.origin + "/favicon.ico";
        }

        return favicon;
    },
    recipeGetSecondaryIcon: function(self) {
        return "";
    },
    recipeGetPassiveBadge: function(self) {
        return 0;
    },
    recipeGetMinWidth: function(self) {
        return parseFloat(window.getComputedStyle(document.body).minWidth);
    },
    recipeGetTitle: function(self) {
        return "";
    }
}

window.__pad.performStart()
window.addEventListener('load', function() {
    window.__pad.performLoad();
});
window.addEventListener('unload', function() {
    window.__pad.performUnload();
});