jQuery(document).ready(function ($) {
    "use strict";

    function changeHeight(myClass) {
        const height = $(myClass).data("height");
        const heightMobile = $(myClass).data("heightmobile");
        const heightTablet = $(myClass).data("heighttablet");
        const heightDesktop = $(myClass).data("heightdesktop");
        const videoRatio = $(myClass).data("ratio");

        function changeHeight() {
            requestAnimationFrame(() => {
                const frameElement = $(".minimalio-video-banner__frame");
                
                // Ensure frameElement exists and has dimensions
                if (!frameElement.length || !frameElement.innerWidth() || !frameElement.innerHeight()) {
                    // Retry after a short delay if dimensions aren't available
                    setTimeout(changeHeight, 100);
                    return;
                }
                
                const ratio = frameElement.innerWidth() / frameElement.innerHeight();

                if (height == "custom") {
                    if ($(window).width() > 992) {
                        $(myClass)
                            .find(".minimalio-video-banner__frame")
                            .css("height", heightDesktop + "vh");
                    } else if ($(window).width() < 992 && $(window).width() > 767) {
                        $(myClass)
                            .find(".minimalio-video-banner__frame")
                            .css("height", heightTablet + "vh");
                    } else {
                        $(myClass)
                            .find(".minimalio-video-banner__frame")
                            .css("height", heightMobile + "vh");
                    }
                }
                if (videoRatio === "16-9") {
                    if (ratio > 1.77) {
                        $(myClass)
                            .find(".minimalio-video-banner__frame")
                            .attr("data-orientation", "horizontal");
                    } else {
                        $(myClass)
                            .find(".minimalio-video-banner__frame")
                            .attr("data-orientation", "vertical");
                    }
                } else if (videoRatio === "4-3") {
                    if (ratio > 1.33) {
                        $(myClass)
                            .find(".minimalio-video-banner__frame")
                            .attr("data-orientation", "horizontal");
                    } else {
                        $(myClass)
                            .find(".minimalio-video-banner__frame")
                            .attr("data-orientation", "vertical");
                    }
                } else {
                    if (ratio > 2.39) {
                        $(myClass)
                            .find(".minimalio-video-banner__frame")
                            .attr("data-orientation", "horizontal");
                    } else {
                        $(myClass)
                            .find(".minimalio-video-banner__frame")
                            .attr("data-orientation", "vertical");
                    }
                }
            });
        }
        
        // Enhanced mobile orientation handling
        function createOrientationHandler() {
            let orientationTimeout;
            let resizeTimeout;
            let lastOrientation = null;
            
            // Detect current orientation using matchMedia
            const portraitQuery = window.matchMedia("(orientation: portrait)");
            const landscapeQuery = window.matchMedia("(orientation: landscape)");
            
            function handleOrientationChange() {
                // Clear any pending timeouts
                if (orientationTimeout) clearTimeout(orientationTimeout);
                if (resizeTimeout) clearTimeout(resizeTimeout);
                
                const currentOrientation = portraitQuery.matches ? 'portrait' : 'landscape';
                
                // Only proceed if orientation actually changed
                if (currentOrientation !== lastOrientation) {
                    lastOrientation = currentOrientation;
                    
                    // Multiple timeout intervals to handle different devices
                    changeHeight();                    // Immediate call
                    setTimeout(changeHeight, 100);     // Short delay for Android
                    setTimeout(changeHeight, 500);     // Medium delay for iOS
                    orientationTimeout = setTimeout(changeHeight, 1000); // Long delay for problematic iOS Safari
                }
            }
            
            function handleResize() {
                // Debounce resize events to prevent excessive calls
                if (resizeTimeout) clearTimeout(resizeTimeout);
                resizeTimeout = setTimeout(changeHeight, 50);
            }
            
            // Modern screen orientation API (preferred)
            if (screen.orientation && screen.orientation.addEventListener) {
                screen.orientation.addEventListener('change', handleOrientationChange);
            }
            
            // matchMedia listeners for orientation changes (reliable fallback)
            if (portraitQuery.addEventListener) {
                portraitQuery.addEventListener('change', handleOrientationChange);
                landscapeQuery.addEventListener('change', handleOrientationChange);
            } else {
                // Fallback for older browsers
                portraitQuery.addListener(handleOrientationChange);
                landscapeQuery.addListener(handleOrientationChange);
            }
            
            // Traditional resize event (fallback)
            window.addEventListener('resize', handleResize);
            
            // Deprecated orientationchange event (for older devices)
            if ('orientationchange' in window) {
                window.addEventListener('orientationchange', handleOrientationChange);
            }
            
            // Visual Viewport API for iOS 13+ (handles address bar changes)
            if (window.visualViewport) {
                window.visualViewport.addEventListener('resize', handleResize);
            }
            
            // Initial orientation setup
            lastOrientation = portraitQuery.matches ? 'portrait' : 'landscape';
            
            return {
                destroy: function() {
                    if (screen.orientation && screen.orientation.removeEventListener) {
                        screen.orientation.removeEventListener('change', handleOrientationChange);
                    }
                    if (portraitQuery.removeEventListener) {
                        portraitQuery.removeEventListener('change', handleOrientationChange);
                        landscapeQuery.removeEventListener('change', handleOrientationChange);
                    } else {
                        portraitQuery.removeListener(handleOrientationChange);
                        landscapeQuery.removeListener(handleOrientationChange);
                    }
                    window.removeEventListener('resize', handleResize);
                    if ('orientationchange' in window) {
                        window.removeEventListener('orientationchange', handleOrientationChange);
                    }
                    if (window.visualViewport) {
                        window.visualViewport.removeEventListener('resize', handleResize);
                    }
                    if (orientationTimeout) clearTimeout(orientationTimeout);
                    if (resizeTimeout) clearTimeout(resizeTimeout);
                }
            };
        }
        
        // Create orientation handler
        const orientationHandler = createOrientationHandler();
        
        // Store reference for cleanup if needed  
        if ($(myClass)[0]) {
            $(myClass)[0]._orientationHandler = orientationHandler;
        }
        
        // Initial call
        changeHeight();
    }

    // Initialize height calculation after DOM is ready and images are loaded
    if ($(".minimalio-video-banner").length > 0) {
        // Run immediately
        changeHeight(".minimalio-video-banner");
        
        // Run after images and other resources are loaded
        $(window).on('load', function() {
            changeHeight(".minimalio-video-banner");
        });
        
        // Run after a short delay to ensure all elements are rendered
        setTimeout(function() {
            changeHeight(".minimalio-video-banner");
        }, 100);
    }
    // YouTube API will be loaded conditionally when this script is enqueued
    function loadYouTubeAPI() {
        if (!window.youtubeAPILoaded && !window.youtubeAPILoading) {
            window.youtubeAPILoading = true;
            var tag = document.createElement("script");
            tag.src = "https://www.youtube.com/player_api";
            tag.onload = function() {
                window.youtubeAPILoaded = true;
                window.youtubeAPILoading = false;
            };
            var firstScriptTag = document.getElementsByTagName("script")[0];
            firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
        }
    }
    
    // Load API immediately when this script runs (since it's only loaded when needed)
    loadYouTubeAPI();
    $(".minimalio-video-banner").each(function () {
        const autoplay = $(this).data("autoplay");
        const myControls = $(this).data("controls");

        //native addClass, removeClass, hasClass and toggleClass
        if (!window.hasOwnProperty("d0")) {
            window.d0 = {};

            d0.hasClass = function (element, className) {
                if (element.classList) {
                    return element.classList.contains(className);
                }
                return new RegExp("\\b" + className + "\\b").test(element.className);
            };

            d0.addClass = function (element, className) {
                if (element.classList) {
                    element.classList.add(className);
                    return;
                }

                if (!d0.hasClass(element, className)) {
                    element.className += " " + className;
                }
            };

            d0.removeClass = function (element, className) {
                if (element.classList) {
                    element.classList.remove(className);
                    return;
                }

                element.className = element.className.replace(
                    new RegExp("\\b" + className + "\\b", "g"),
                    ""
                );
            };

            d0.toogleClass = function (element, className) {
                if (d0.hasClass(element, className)) {
                    d0.removeClass(element, className);
                } else {
                    d0.addClass(element, className);
                }
            };
        }

        function YoutubeBackground(elem, params, id, uid) {
            this.is_mobile = this.isMobile();

            this.element = elem;
            this.ytid = id;
            this.uid = uid;
            this.player = null;
            this.buttons = {};

            this.state = {};
            this.state.play = false;
            this.state.mute = false;

            this.params = {};

            this.defaults = {
                pause: false, //deprecated
                "play-button": false,
                "mute-button": false,
                autoplay: autoplay,
                muted: true,
                loop: true,
                mobile: true,
                "load-background": true,
                resolution: "16/9",
                offset: 200,
            };

            this.__init__ = function () {
                if (!this.ytid) {
                    return;
                }

                this.parseProperties(params);
                this.params.resolution_mod = this.parseResolutionString(
                    this.params.resolution
                );
                this.state.playing = this.params.autoplay;
                this.state.muted = this.params.muted;

                this.buildHTML();
                this.injectIFrame();

                if (this.params["play-button"]) {
                    this.generateActionButton({
                        name: "play",
                        className: "play-toggle",
                        innerHtml: "<span></span>",
                        initialState: false,
                        stateClassName: "paused",
                        condition_parameter: "autoplay",
                        stateChildClassNames: ["fa-pause-circle", "fa-play-circle"],
                        actions: ["play", "pause"],
                    });
                }

                if (this.params["mute-button"]) {
                    this.generateActionButton({
                        name: "mute",
                        className: "mute-toggle",
                        innerHtml: "<span></span>",
                        initialState: true,
                        stateClassName: "muted",
                        condition_parameter: "muted",
                        stateChildClassNames: ["fa-volume-up", "fa-volume-off"],
                        actions: ["unmute", "mute"],
                    });
                }
            };


            this.__init__();
        }

        YoutubeBackground.prototype.initYTPlayer = function () {
            var self = this;

            if (window.hasOwnProperty("YT")) {
                this.player = new YT.Player(this.uid, {
                    events: {
                        onReady: function (event) {
                            self.onVideoPlayerReady(event);
                        },
                        onStateChange: function (event) {
                            self.onVideoStateChange(event);
                        },
                        onError: function (event) {
                            //console.error('player_api', event);
                        },
                    },
                });
            }
        };

        YoutubeBackground.prototype.onVideoPlayerReady = function (event) {
            if (this.params.autoplay) {
                event.target.playVideo();
            }
        };

        YoutubeBackground.prototype.onVideoStateChange = function (event) {
            if (event.data === 0 && this.params.loop) {
                event.target.playVideo();
            }

            if (event.data === -1 && this.params.autoplay) {
                event.target.playVideo();
            }

            if (event.data === 1) {
                this.iframe.style.opacity = 1;
            }
        };

        YoutubeBackground.prototype.parseProperties = function (params) {
            if (!params) {
                this.params = this.defaults;
            } else {
                //load in defaults
                for (var k in this.defaults) {
                    if (!this.params.hasOwnProperty(k)) {
                        this.params[k] = this.defaults[k];
                    }
                }
            }

            // load params from data attributes
            for (var k in this.params) {
                var data = this.element.getAttribute("data-ytbg-" + k);

                if (data !== undefined && data !== null) {
                    switch (data) {
                        case data === "false":
                            data = false;
                            break;
                        case data === "true":
                            data = true;
                            break;
                    }

                    this.params[k] = data;
                }
            }

            //pause deprecated
            if (this.params.pause) {
                this.params["play-button"] = this.params.pause;
            }
        };

        YoutubeBackground.prototype.injectIFrame = function () {
            this.iframe = document.createElement("iframe");
            this.iframe.setAttribute("frameborder", 0);
            this.iframe.setAttribute("class", "youtube-iframe");
            this.iframe.setAttribute("allow", "autoplay; encrypted-media");
            var src =
                "https://www.youtube.com/embed/" +
                this.ytid +
                "?enablejsapi=1&disablekb=1&controls=0&rel=0&iv_load_policy=3&cc_load_policy=0&playsinline=1&showinfo=0&fs=0&origin=" +
                window.location.origin;

            if (this.params.muted) {
                src += "&mute=1";
            }

            if (this.params.autoplay) {
                src += "&autoplay=1";
            }

            if (this.params.loop) {
                src += "&loop=1";
            }

            this.iframe.src = src;

            if (this.uid) {
                this.iframe.id = this.uid;
            }

            this.iframe.style.top = "50%";
            this.iframe.style.left = "50%";
            this.iframe.style.transform = "translateX(-50%) translateY(-50%)";
            this.iframe.style.position = "absolute";
            this.iframe.style.opacity = 0;

            this.element.parentNode.appendChild(this.iframe);
            this.iframe.parentNode.removeChild(this.element);

            var self = this;

            function onResize() {
                var h = self.iframe.parentNode.offsetHeight + self.params.offset; // since showinfo is deprecated and ignored after September 25, 2018. we add +200 to hide it in the overflow
                var w = self.iframe.parentNode.offsetWidth + self.params.offset;
                var res = self.params.resolution_mod;

                if (res > w / h) {
                    self.iframe.style.width = h * res + "px";
                    self.iframe.style.height = h + "px";
                } else {
                    self.iframe.style.width = w + "px";
                    self.iframe.style.height = w / res + "px";
                }
                //    self.iframe.style.width = h*res + 'px';
                //     self.iframe.style.height = h + 'px';
            }

            window.addEventListener("resize", onResize);
            onResize();
        };

        YoutubeBackground.prototype.buildHTML = function () {
            var parent = this.element.parentNode;
            // wrap
            var wrapper = document.createElement("div");
            wrapper.className = "youtube-background";
            parent.insertBefore(wrapper, this.element);
            wrapper.appendChild(this.element);
            var id = this.element.id;
            this.element.id = "";
            wrapper.id = id;

            //set css rules
            var wrapper_styles = {
                height: "100%",
                width: "100%",
                "z-index": "0",
                position: "absolute",
                overflow: "hidden",
                top: 0, // added by @insad
                left: 0,
                bottom: 0,
                right: 0,
            };

            if (!this.params["mute-button"]) {
                wrapper_styles["pointer-events"] = "none"; // avoid right mouse click popup menu
            }

            if (this.params["load-background"]) {
                wrapper_styles["background-image"] =
                    "url(https://img.youtube.com/vi/" + this.ytid + "/maxresdefault.jpg)";
                wrapper_styles["background-size"] = "cover";
                wrapper_styles["background-repeat"] = "no-repeat";
                wrapper_styles["background-position"] = "center";
            }

            for (var property in wrapper_styles) {
                wrapper.style[property] = wrapper_styles[property];
            }

            wrapper.parentNode.style.position = "relative";

            if (this.is_mobile && !this.params.mobile) {
                return wrapper;
            }

            // set play/mute controls wrap
            if (this.params["play-button"] || this.params["mute-button"]) {
                var controls = document.createElement("div");
                controls.className = "video-background-controls " + myControls;

                controls.style.position = "absolute";
                controls.style["z-index"] = 2;

                this.controls_element = controls;
                wrapper.parentNode.appendChild(controls);
            }

            return wrapper;
        };

        YoutubeBackground.prototype.play = function () {
            if (this.buttons.hasOwnProperty("play")) {
                var btn_obj = this.buttons.play;
                d0.removeClass(
                    btn_obj.element,
                    btn_obj.button_properties.stateClassName
                );
                d0.addClass(
                    btn_obj.element.firstChild,
                    btn_obj.button_properties.stateChildClassNames[0]
                );
                d0.removeClass(
                    btn_obj.element.firstChild,
                    btn_obj.button_properties.stateChildClassNames[1]
                );
            }

            if (this.player) {
                this.player.playVideo();
            }
        };

        YoutubeBackground.prototype.pause = function () {
            if (this.buttons.hasOwnProperty("play")) {
                var btn_obj = this.buttons.play;
                d0.addClass(btn_obj.element, btn_obj.button_properties.stateClassName);
                d0.removeClass(
                    btn_obj.element.firstChild,
                    btn_obj.button_properties.stateChildClassNames[0]
                );
                d0.addClass(
                    btn_obj.element.firstChild,
                    btn_obj.button_properties.stateChildClassNames[1]
                );
            }

            if (this.player) {
                this.player.pauseVideo();
            }
        };

        YoutubeBackground.prototype.unmute = function () {
            if (this.buttons.hasOwnProperty("mute")) {
                var btn_obj = this.buttons.mute;
                d0.removeClass(
                    btn_obj.element,
                    btn_obj.button_properties.stateClassName
                );
                d0.addClass(
                    btn_obj.element.firstChild,
                    btn_obj.button_properties.stateChildClassNames[0]
                );
                d0.removeClass(
                    btn_obj.element.firstChild,
                    btn_obj.button_properties.stateChildClassNames[1]
                );
            }

            if (this.player) {
                this.player.unMute();
            }
        };

        YoutubeBackground.prototype.mute = function () {
            if (this.buttons.hasOwnProperty("mute")) {
                var btn_obj = this.buttons.mute;
                d0.addClass(btn_obj.element, btn_obj.button_properties.stateClassName);
                d0.removeClass(
                    btn_obj.element.firstChild,
                    btn_obj.button_properties.stateChildClassNames[0]
                );
                d0.addClass(
                    btn_obj.element.firstChild,
                    btn_obj.button_properties.stateChildClassNames[1]
                );
            }

            if (this.player) {
                this.player.mute();
            }
        };

        //TODO: refactor states to be equal for all buttons
        YoutubeBackground.prototype.generateActionButton = function (obj) {
            var btn = document.createElement("button");
            btn.className = obj.className;
            btn.innerHTML = obj.innerHtml;
            d0.addClass(btn.firstChild, obj.stateChildClassNames[0]);
            btn.style.background = $(".minimalio-video-banner").data("controls-color")

            if (this.params[obj.condition_parameter] == obj.initialState) {
                d0.addClass(btn, obj.stateClassName);
                d0.removeClass(btn.firstChild, obj.stateChildClassNames[0]);
                d0.addClass(btn.firstChild, obj.stateChildClassNames[1]);
            }

            var self = this;
            btn.addEventListener("click", function (e) {
                if (d0.hasClass(this, obj.stateClassName)) {
                    self.state[obj.name] = false;
                    self[obj.actions[0]]();
                } else {
                    self.state[obj.name] = true;
                    self[obj.actions[1]]();
                }
            });

            this.buttons[obj.name] = {
                element: btn,
                button_properties: obj,
            };

            this.controls_element.appendChild(btn);
        };

        YoutubeBackground.prototype.parseResolutionString = function (res) {
            var pts = res.split(/\s?:\s?/i);
            if (pts.length < 2) {
                return 16 / 9;
            }

            var w = parseInt(pts[0], 10);
            var h = parseInt(pts[1], 10);

            if (isNaN(w) || isNaN(h)) {
                return 16 / 9;
            }

            return w / h;
        };

        YoutubeBackground.prototype.isMobile = function (event) {
            var is_mobile = false;
            (function (a) {
                if (
                    /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(
                        a
                    ) ||
                    /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(
                        a.substr(0, 4)
                    )
                )
                    is_mobile = true;
            })(navigator.userAgent || navigator.vendor || window.opera);

            return is_mobile;
        };

        YoutubeBackground.prototype.error = function (message, value) {
            if (
                window.hasOwnProperty("console") &&
                window.console.hasOwnProperty("error")
            ) {
                console.error(message, value);
            }
        };

        function ActivityMonitor(
            on_activity,
            on_inactivity,
            activity_timeout,
            inactivity_timeout,
            events
        ) {
            this.timer = null;
            this.timeout = inactivity_timeout || 10000;
            this.activity_timer = null; //for event throttling
            this.activity_timeout = activity_timeout || 1000;
            this.last_activity = null;

            this.resetTimer = function () {
                if (this.timer) {
                    clearTimeout(this.timer);
                    this.timer = null;
                }

                var self = this;
                this.timer = setTimeout(function () {
                    if (
                        self.last_activity + self.timeout + self.activity_timeout >=
                        new Date().getTime()
                    ) {
                        if (on_inactivity) {
                            on_inactivity();
                        }
                    }
                }, this.timeout);
            };

            this.logActivity = function () {
                this.last_activity = new Date().getTime();

                if (on_activity) {
                    on_activity();
                }
            };

            this.onActivity = function () {
                if (!this.activity_timer) {
                    var self = this;
                    this.activity_timer = setTimeout(function () {
                        self.logActivity();
                        self.resetTimer();

                        clearTimeout(self.activity_timer);
                        self.activity_timer = null;
                    }, this.activity_timeout);
                }
            };

            this.__init__ = function () {
                var self = this;

                if (!events) {
                    events = ["click", "mousemove", "scroll"];
                } else {
                    if (typeof events === "string") {
                        events = [events];
                    }
                }

                for (var i = 0; i < events.length; i++) {
                    document.addEventListener(events[i], function () {
                        self.onActivity();
                    });
                }
            };

            this.__init__();
        }

        function VideoBackgrounds(selector, params) {
            this.elements = selector;

            if (typeof selector === "string") {
                this.elements = document.querySelectorAll(selector);
            }

            this.index = {};
            this.re = {};
            this.re.YOUTUBE = /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/ ]{11})/i;

            this.__init__ = function () {
                for (var i = 0; i < this.elements.length; i++) {
                    var element = this.elements[i];

                    var link = element.getAttribute("data-youtube");
                    var ytid = this.getYTID(link);
                    var uid = this.generateUID(ytid);

                    var yb = new YoutubeBackground(element, params, ytid, uid);

                    if (!uid) {
                        continue;
                    }

                    this.index[uid] = yb;
                }

                var self = this;

                this.initYTPlayers(function () {
                    //TODO: FIX!
                    if (
                        params &&
                        (params.hasOwnProperty("activity_timeout") ||
                            params.hasOwnProperty("inactivity_timeout"))
                    ) {
                        this.activity_monitor = new ActivityMonitor(
                            function () {
                                self.playVideos();
                            },
                            function () {
                                self.pauseVideos();
                            },
                            params ? params.activity_timeout : null,
                            params ? params.inactivity_timeout : null,
                            ["mousemove", "scroll"]
                        );
                    }
                });
            };

            this.__init__();
        }

        VideoBackgrounds.prototype.getYTID = function (link) {
            if (link !== undefined && link !== null) {
                var pts = link.match(this.re.YOUTUBE);
                if (pts && pts.length) {
                    this.re.YOUTUBE.lastIndex = 0; //regex needs a reset in for loops, I always forget this
                    return pts[1];
                }
            }
            return null;
        };

        VideoBackgrounds.prototype.generateUID = function (pref) {
            //index the instance
            function getRandomIntInclusive(min, max) {
                min = Math.ceil(min);
                max = Math.floor(max);
                return Math.floor(Math.random() * (max - min + 1)) + min; //The maximum is inclusive and the minimum is inclusive
            }

            var uid = pref + "-" + getRandomIntInclusive(0, 9999);
            while (this.index.hasOwnProperty(uid)) {
                uid = pref + "-" + getRandomIntInclusive(0, 9999);
            }

            return uid;
        };

        VideoBackgrounds.prototype.pauseVideos = function () {
            for (var k in this.index) {
                this.index[k].pause();
            }
        };

        VideoBackgrounds.prototype.playVideos = function () {
            for (var k in this.index) {
                this.index[k].play();
            }
        };

        VideoBackgrounds.prototype.initYTPlayers = function (callback) {
            var self = this;

            function initPlayers() {
                for (var k in self.index) {
                    self.index[k].initYTPlayer();
                }

                if (callback) {
                    setTimeout(callback, 100);
                }
            }

            if (window.hasOwnProperty("YT") && window.YT.loaded) {
                initPlayers();
            } else {
                if (!window.youtubeReadyCallbacks) {
                    window.youtubeReadyCallbacks = [];
                    window.onYouTubeIframeAPIReady = function () {
                        for (var i = 0; i < window.youtubeReadyCallbacks.length; i++) {
                            window.youtubeReadyCallbacks[i]();
                        }
                    };
                }
                window.youtubeReadyCallbacks.push(initPlayers);
            }
        };

        if (window.hasOwnProperty("jQuery")) {
            (function ($) {
                $.fn.youtube_background = function (params) {
                    var $this = $(this);
                    new VideoBackgrounds(this, params);
                    return $this;
                };
            })(jQuery);
        }

        $(function () {
            $("[data-youtube]").youtube_background();
        });
    });
});
