/**
 * The globally-accessible Bumble Object
 * 
 * Here I can store any and all utilities without taking up space in the
 * gloabl namespace.
 */
var Bumble = {};

/**
 * The info panel
 * 
 * The info panel is a utility that allows me to add information to a page
 * in such a way that it can easily be closed when the user is done reading
 * it. 
 * 
 * This aims to improve the SEO of pages by adding as much descriptive
 * text as I want, without harming the usability of the page. This takes into
 * consideration that most of my pages are, currently, JS games on canvasses.
 * 
 * @param {HTMLElement} panel - An HTML element with the .infopanel class
 */
Bumble.InfoPanel = function(panel){
    this.panel = panel;
    this.head = undefined;
    this.body = undefined;
    this.title = undefined
    this.closer = undefined;
    this.icons = {
        close: "uil-times-circle",
        open: "uil-info-circle"
    }
    this.isClosed = false;

    /**
     * Initialzize the info panel
     */
    this.init = function(){
        if(!this.panel){ throw new Error("Panel not found."); }

        this.head = this.panel.querySelector('.infopanel-head');
        this.body = this.panel.querySelector('.infopanel-body');
        this.title = this.head.querySelector('.infopanel-title');
        this.closer = this.head.querySelector('.infopanel-closer');
        this.isClosed = this.panel.classList.contains('closed');

        this.closer.addEventListener("click", ()=>{ this.toggleVisibility(); });
        this.toggleCloseButtonIcon();
        
    }

    /**
     * Close the info panel
     */
    this.close = function() {
        this.panel.classList.add("closed");
        this.isClosed = true;
    }
    /**
     * Open the info panel
     */
    this.open = function() {
        this.panel.classList.remove("closed")
        this.isClosed = false;
    }
    /**
     * Toggle the info panel's visibility
     */
    this.toggleVisibility = function() {
        if(this.isClosed) { this.open(); }
        else { this.close(); }
        
        this.toggleCloseButtonIcon();
    }
    /**
     * Toggle the icon of the info panel's open/close button
     */
    this.toggleCloseButtonIcon = function() {
        if(this.isClosed) {
            this.closer.classList.remove(this.icons.close);
            this.closer.classList.add(this.icons.open);
        }
        else {
            this.closer.classList.remove(this.icons.open);
            this.closer.classList.add(this.icons.close);
        }
    }

    this.init();
}

/**
 * A classic modal
 * 
 * @param {string} DOMID - An option string of the DOM ID for premade modal
 */
Bumble.Modal = function(DOMID) {
    this.overlay = undefined;
    this.modal = {
        base: undefined,
        header: undefined,
        title: undefined,
        closer: undefined,
        body: undefined
    };
    this.isShown = false;

    this.init = function(DOMID) {
        // Build the overlay
        this.overlay = document.createElement("div");
        this.overlay.classList.add("modal-overlay", "hidden");
        // Initialize a predefined modal
        if(DOMID) {
            const elem = document.getElementById(DOMID);
            if(!elem){
                console.warn("No element found with ID: ", DOMID);
                console.warn("Creating modal");
            }
            else {
                this.modal.pane = elem;
                this.modal.header = elem.querySelector(".modal-header");
                this.modal.title = elem.querySelector(".modal-title");
                this.modal.closer = elem.querySelector(".uil-times-circle");
                this.modal.body = elem.querySelector(".modal-body");
            }
        }
        // Build the modal from scratch
        if(!this.modal.pane) {
            this.modal.pane = document.createElement("div");
            this.modal.pane.classList.add("modal");
    
            this.modal.header = document.createElement("div");
            this.modal.header.classList.add("modal-header");
    
            this.modal.title = document.createElement("div");
            this.modal.title.classList.add("modal-title");
    
            const closerContainer = document.createElement("div");
            closerContainer.classList.add("modal-closer", "text-right");
    
            this.modal.closer = document.createElement("i");
            this.modal.closer.classList.add("uil", "uil-times-circle");
            closerContainer.appendChild(this.modal.closer);
    
            this.modal.header.append(this.modal.title, closerContainer);
    
            this.modal.body = document.createElement("div");
            this.modal.body.classList.add("modal-body");
    
            this.modal.pane.append(this.modal.header, this.modal.body);
        }
        // Add event listener to closer button
        this.modal.closer.addEventListener("click", this.hide.bind(this));

        // Add modal pane to the overlay
        this.overlay.appendChild(this.modal.pane);

        // Add overlay to body
        document.body.appendChild(this.overlay);

        return;
    }

    this.SetTitle = function(title) {
        this.modal.title.innerText = title;
    }

    this.SetBody = function(bodyHTML) {
        this.modal.body.innerHTML = bodyHTML;
    }

    this.show = function() {
        this.isShown = true;
        this._toggleVisibility();
    }

    this.hide = function() {
        this.isShown = false;
        this._toggleVisibility();
    }

    this._toggleVisibility = function() {
        if(this.isShown) {
            this.overlay.classList.remove("hidden");
        }
        else {
            this.overlay.classList.add("hidden");
        }
    }

    this.init(DOMID);
}

/**
 * Store GET Parameters
 * 
 * A convenient place to store and access GET parameters sent to the page.
 */
Bumble._GET = {
    /**
     * Loads the GET parameters into this object
     */
    __init: function() {
        const params = (new URL(document.location)).searchParams.entries();
        for(const entry of params) {
            if(entry[0] == "__init"){ continue; }
            this[entry[0]] = !isNaN(entry[1]) ? Number(entry[1]) : entry[1];
        }
    }
}

Bumble.XFN = {
    me: "uil-cell",
    friend: "uil-user-check",
    colleague: "uil-books",

    _buildIcon: function(iconClass) {
        const icon = document.createElement("i");
            icon.classList.add("uil", iconClass);

        return icon;
    },

    init: function() {
        const links = document.querySelectorAll("a[rel]");

        for(const link of links) {
            const rels = link.rel.split(' ');
            let rel = null;

            if(rels.indexOf("me") >= 0) {
                rel = this.me;
            }
            else if(rels.indexOf("friend") >= 0) {
                rel = this.friend;
            }
            else if(rels.indexOf("colleague") >= 0) {
                rel = this.colleague;
            }

            if(rel) {
                link.insertAdjacentElement("afterbegin", this._buildIcon(rel));
            }
        }
    },
}

/**
 * Quotes that either have a lot of meaning to me, or I just really enjoy
 */
Bumble.FooterQuotes = {
    all_quotes: [
        {
            "text":"We can't rewind now; we've gone too far",
            "source":"The Limousines - Interenet Killed The Video Star"
        },
        {
            "text":"There is no justice or no peace, there's only forgiveness",
            "source":"John Reuben - There's only Forgiveness"
        },
        {
            "text":"Love is like a circle; there's no easy way to end",
            "source":"Oliver Tree - Cowboys Don't Cry"
        },
        {
            "text":"No crime is as bad as meaninglessness",
            "source":"Futhermore - Letter To Myself"
        },
        {
            "text":"Independence was the goal, now you miss home sick",
            "source":"Futhermore - Letter To Myself"
        },
        {
            "text":"Apathy's a tragedy, and boredom is a crime",
            "source":"Bo Burnham - Welcome To The Internet"
        },
        {
            "text":"All I ever wanted was a little bit of everything all of the time",
            "source":"Bo Burnham - Welcome To The Internet"
        },
        {
            "text":"The taste of blood; It's murder; This is your fault; You chose this path.",
            "source":"Mayhem - It's Murder"
        },
        {
            "text":"So it goes.",
            "source":"Kurt Vonnegaut - Slaughter-house Five"
        },
        {
            "text":"He has always pressed it, and he always will. We always let him and we always will let him. The moment is structured that way.",
            "source":"Kurt Vonnegaut - Slaughter-house Five"
        },
        {
            "text":"This isn't a man. It's a broken kite.",
            "source":"Kurt Vonnegaut - Slaughter-house Five"
        },
        {
            "text":"Why you? Why us for that matter? Why Anything? Because the moment simply is.",
            "source":"Kurt Vonnegaut - Slaughter-house Five"
        },
        {
            "text":"Poo-tee-tweet?",
            "source":"Kurt Vonnegaut - Slaughter-house Five"
        },
        {
            "text":"Yeah there's nothing left to ruin, yeah we finally got free / How's that for manifesting our destiny",
            "source":"Sylvan Esso - PARAD(w/m)E"
        },
        {
            "text":"Where you been? I wonder / We've been waitin so long around here for days, days, days",
            "source":"Mr. Gnome - Pixie Dust"
        },
        {
            "text":"We will laugh at the fact that we ever resisted this blissful togetherness",
            "source":"Rachel Kann - I Know This"
        },
        {
            "text":"Who mistook the steak for chicken?",
            "source":"Moldy Peaches - Steak For Chicken"
        },
        {
            "text":"We're not those kids, sitting on the couch",
            "source":"Moldy Peaches - Steak For Chicken"
        },
        {
            "text":"Death will give us back to God / Just like the setting sun is returned to lonesome ocean",
            "source":"Bright Eyes - At The Bottom Of Everything"
        },
        {
            "text":"I'm happy just because / I found out I am really no one",
            "source":"Bright Eyes - At The Bottom Of Everything"
        },
        {
            "text":"There'll always be a few things, maybe several things / That you're gonna find really difficult to forgive",
            "source":"The Mountain Goates - Up The Wolves"
        },
        {
            "text":"It's gonna take you people years to recover from all of the damage",
            "source":"The Mountain Goates - Up The Wolves"
        },
        {
            "text":"Your sleepy anarchy... Wake it Up! Wake it up!",
            "source":"TeddyLoid Ft. Debra Zeer - D City Rock"
        },
        {
            "text":"I just miss how it felt standing next to you / Wearing matching dresses before the world was big",
            "source":"Girlpool - Before The World Was Big"
        },
        {
            "text":"I have to be fucking with something I love if I'm burning both ends of my candle stick",
            "source":"Girlpool - Before The World Was Big"
        },
        {
            "text":"Why you tweetin' at the top of your lungs?",
            "source":"Lil Darkie - COMFORT IN DISCOMFORT"
        },
        {
            "text":"It's almost over / It's just begun",
            "source":"Bo Burnham - All Eyes On Me"
        },
        {
            "text":"You say the whole world's ending, honey, it already did",
            "source":"Bo Burnham - All Eyes On Me"
        },
        {
            "text":"You're drowning in the grief of Jupiter's waters",
            "source":"Terrance Zdunich - Grief (Alternate Version)"
        },
        {
            "text":"I'd rather nap than wonder, restlessly / Will you ever be impressed by me?",
            "source":"Crying - ES"
        },
        {
            "text":"How did you become this way?",
            "source":"Crying - ES"
        },
        {
            "text":"I'll embrace dreams again when I can breathe again / And at that point I won't be needing them",
            "source":"John Reuben - Chapter 1"
        },
        {
            "text":"The revolution didn't leave you, it never came",
            "source":"John Reuben - Chapter 1"
        },
        {
            "text":"When real life is reality TV, no wonder our youth don't belive in anything",
            "source":"John Reuben - Chapter 1"
        },
        {
            "text":"There are no heroes, just those of us with high hopes",
            "source":"John Reuben - Chapter 1"
        },
        {
            "text":"Puff the magic Jesus floats around the universe; The United States is his favorite place on the whole entire Earth",
            "source":"John Reuben - What About Them?"
        },
        {
            "text":"History is best forgotten and even better rewritten / And since there's no forgetting, let's remember it different",
            "source":"John Reuben - What About Them?"
        },
        {
            "text":"Four walls with no windows doesn't mean you're it / Four walls with no windows doesn't mean they don't exist",
            "source":"John Reuben - What About Them?"
        },
        {
            "text":"Ignore the crying outside the door / Sure, you'll pray for their burdens, but you don't want to make it yours",
            "source":"John Reuben - What About Them?"
        },
        {
            "text":"The more you have, the less you care / The less you care, the more you become unware",
            "source":"John Reuben - What About Them?"
        },
        {
            "text":"God bless us as we sweep this mess under the rug",
            "source":"John Reuben - What About Them?"
        },
        {
            "text":"It's not the way I'm meant to be / It's just the way the operation made me",
            "source":"The Dresden Dolls - Girl Anachronism"
        },
        {
            "text":"Behold the world's worst accident / I am the girl anachronism",
            "source":"The Dresden Dolls - Girl Anachronism"
        },
        {
            "text":"I don't necessarily belive there is a cure for this, so I might join your century as a doubtful guest",
            "source":"The Dresden Dolls - Girl Anachronism"
        },
        {
            "text":"Do you love me? Yes, no, maybe. I'll be seeing Hades soon",
            "source":"JACK THE STRIPPER Ft. Byrds - PHANTASM"
        },
        {
            "text":"Define \"terrorist\"",
            "source":"Me - On the subject of governments trying to stop \"terrorists\""
        },
        {
            "text":"What goal would justify the suffering of your life",
            "source":"Jordon Peterson"
        },
        {
            "text":"The goal is to be wrong in interesting ways",
            "source":"Abigail Thorn"
        },
        {
            "text":"God help the outcast with her witchcraft / Some day I'm gonna go home",
            "source":"Sherclop Pones - Pinkie's Brew"
        },
        {
            "text":"When I wrote this code, only God and I knew how it worked. Now, only God knows it!",
            "source":"Unknown Developer"
        },
        {
            "text":"It's okay to be different things in different places.",
            "source":"@alis@fandom.ink - https://fandom.ink/@alis/109545392718134930"
        },
        {
            "text":"You're nobody till somebody wants you dead",
            "source":"Saint Motel - You're Nobody Till Somebody Wants You Dead"
        },
    ],

    PlaceQuote: function() {
        const div = document.getElementById("footer-quote");
        if (div) {
            quote = this.all_quotes[Math.floor(Math.random() * this.all_quotes.length)];
            div.innerText = quote.text;
            console.log(`Quote source: ${quote.source}`);
        }
    }
}

function page_init() {
    /* Initialize info panels */
    const panels = document.querySelectorAll('.infopanel');
    for(const panel of panels) {
        panel._infoPanel = new Bumble.InfoPanel(panel);
    }

    Bumble._GET.__init();
    Bumble.XFN.init();
    Bumble.FooterQuotes.PlaceQuote();
}

if(document.readyState != 'loading') {
    page_init();
}
else {
    document.addEventListener('DOMContentLoaded', page_init);
}