function removeAllListeners() {
    Helper.log(["Removing all listeners"]);
    socket.removeEventListener("chat.all");
    socket.removeEventListener("chat");
    socket.removeEventListener("conf");
    socket.removeEventListener("pw");
    socket.removeEventListener("toast");
    socket.removeEventListener("id");
    socket.removeEventListener("channel");
    socket.removeEventListener("np");
    socket.removeEventListener("get_list");
    //socket.removeEventListener("self_ping");
    socket.removeEventListener("viewers");
    socket.removeEventListener("auth_required");
    socket.removeEventListener("auth_accepted");
    socket.removeEventListener("suggested");
    socket.removeEventListener("color");
    socket.removeEventListener("chat_history");
    //socket.removeEventListener("name");
    socket.removeEventListener(id);
}
function resizeFunction() {
    if(chan && !Helper.mobilecheck()){
        if(document.querySelector("#wrapper") == null) return;
        if(!client && !embed) document.querySelector("#hide-playlist").style.left = (document.querySelector("#video-container").offsetWidth - document.querySelector("#hide-playlist").offsetWidth) + "px";
        if(window.innerWidth > 600 && document.querySelector("#wrapper").style.height != "") {
            document.querySelector("#wrapper").style.height = "";
            document.querySelector("#chat-bar").style.height = "";
            document.querySelector("#channelchat").style.height = "";
            document.querySelector("#all_chat").style.height = "";
            document.querySelector("#chat-container").style.height = "";
        } else if(window.innerWidth < 601) {
            if(!client && !embed) {
                var scPlaying = false;
                var ytPlaying = false;
                try {
                    ytPlaying = Player.player.getPlayerState() == YT.PlayerState.PLAYING || Player.player.getPlayerState() == YT.PlayerState.BUFFERING;
                } catch(e) {}
                try {
                    scPlaying = Player.soundcloud_player.isPlaying();
                } catch(e){}
                resizePlaylistPlaying(ytPlaying || scPlaying);
                return;
            }
        }
        var temp_fit;
        if(!embed && !client){
            temp_fit = Math.round(Helper.computedStyle("#wrapper", "height") / 71);
            List.element_height = (Helper.computedStyle("#wrapper", "height") / temp_fit)-5.3;
        } else if(embed) {
            temp_fit = Math.round(Helper.computedStyle("#wrapper", "height") / 91) + 1;
            List.element_height = (Helper.computedStyle("#wrapper", "height") / temp_fit)-4;
        } else if(!client){
            temp_fit = Math.round((Helper.computedStyle(".tabs", "height") - Helper.computedStyle("header", "height") - 64 - 40) / 71)+1;
            List.element_height = ((window.innerHeight - Helper.computedStyle(".tabs", "height") - Helper.computedStyle("header", "height") - 64 - 40) / temp_fit)-5;
        } else {
            temp_fit = Math.round(Helper.computedStyle("#wrapper", "height") / 71)+1;
            List.element_height = (Helper.computedStyle("#wrapper", "height") / temp_fit)-5.3;
        }
        if(List.element_height < 55.2 && !client){
            temp_fit = temp_fit - 1;
            List.element_height = 55.2;
            temp_fit = Math.round((window.innerHeight - Helper.computedStyle(".tabs", "height") - Helper.computedStyle("header", "height") - 64 - 40) / 71);
            List.element_height = ((window.innerHeight - Helper.computedStyle(".tabs", "height") - Helper.computedStyle("header", "height") - 64 - 40) / temp_fit)-5;
        }
        if(temp_fit > List.can_fit || temp_fit < List.can_fit){
            List.dynamicContentPage(-10);
        }
        if(List.can_fit < temp_fit){
            for(var i = 0; i < List.page + temp_fit; i++) {
                Helper.css(document.querySelector("#wrapper").children[i], "display", "inline-flex");
            }
        } else if(List.can_fit > temp_fit){
            Helper.css(document.querySelector("#wrapper").children[List.page + temp_fit], "display", "none");
            var elements = document.querySelector("#wrapper").children;
            for(var i = List.page + temp_fit; i < elements.length; i++) {
                Helper.css(document.querySelector("#wrapper").children[i], "display", "none");
            }
        }
        List.can_fit = temp_fit;
        //List.element_height = (Helper.computedStyle("#wrapper", "height") / List.can_fit)-5.3;
        Helper.css(".list-song", "height", List.element_height + "px");
        Channel.set_title_width();
        if(!client) {
            var controlsPosition = document.querySelector("#controls").offsetHeight - Helper.computedStyle("#controls", "height");
            if(document.querySelectorAll("#controls").length > 0 && !Helper.mobilecheck()) {
                Helper.css(document.querySelector("#seekToDuration"), "top", controlsPosition - 55);
            } else if(document.querySelectorAll("#controls").length > 0) {
                Helper.css(document.querySelector("#seekToDuration"), "top", controlsPosition - 20);
            }
            Channel.window_width_volume_slider();
        }
    }
}
function fullVideo(hide) {
    if(hide) {
        document.querySelector("#playlist").className += " show-only-mobile";
        document.querySelector("#video-container").classList.remove("m9");
        document.querySelector("#video-container").className += " m12";
        document.querySelector("main").style.maxWidth = "100%";
        document.querySelector("#hide-playlist").style.left = (document.querySelector("#video-container").offsetWidth - document.querySelector("#hide-playlist").offsetWidth) + "px";
        document.querySelector("#hide-playlist .material-icons").innerText = "keyboard_arrow_left";
    } else {
        document.querySelector("#playlist").classList.remove("show-only-mobile");
        document.querySelector("#video-container").classList.remove("m12");
        document.querySelector("#video-container").className += " m9";
        document.querySelector("main").style.maxWidth = "";
        document.querySelector("#hide-playlist").style.left = (document.querySelector("#video-container").offsetWidth - document.querySelector("#hide-playlist").offsetWidth) + "px";
        document.querySelector("#hide-playlist .material-icons").innerText = "keyboard_arrow_right";
    }
    hiddenPlaylist = hide;
}
function getColor(id) {
    Helper.ajax({
        method: "POST",
        url: "/api/color",
        headers: {"Content-Type": "application/json;charset=UTF-8"},
        data: JSON.stringify({
            id: id
        }),
        success: function(c) {
            c = JSON.parse(c);
            if(typeof(c) == "object") {
                Player.setBGimage({color:c, only:true});
            }
        },
    });
}
function hide_native(way) {
    if(way == 1){
        Helper.addClass('.castButton', 'castButton-white-active');
        if(!Helper.mobilecheck()) {
            if(M.Tooltip.getInstance(document.getElementsByClassName("castButton")[0])) {
                Helper.tooltip('.castButton', 'destroy');
            }
            Helper.tooltip('.castButton', {
                delay: 5,
                position: "top",
                html: "Stop casting"
            });
        }
        Helper.toggleClass("#duration", "hide");
        Helper.toggleClass("#fullscreen", "hide");
        try{
            if(videoSource == "youtube") {
                Player.player.stopVideo();
            } else if(videoSource == "soundcloud") {
                Player.soundcloud_player.pause();
            }
        } catch(e){}
        Player.stopInterval = true;
        if(Helper.mobilecheck()){
            if(document.querySelector("#pause").classList.contains("hide")){
                Helper.toggleClass("#play", "hide");
                Helper.toggleClass("#pause", "hide");
            } else if(document.querySelector("#play").classList.contains("hide")){
                Helper.toggleClass("#play", "hide");
                Helper.toggleClass("#pause", "hide");
            }
        } else {
            Playercontrols.visualVolume(100);
        }
        if(Helper.mobilecheck()) {
            Helper.addClass("#player_overlay", "hide")
            Helper.css("#player_overlay", "display", "none");
            Helper.css("#playing_on", "display", "none");
        } else {
            var thisThumbnail;
            if(Player.np.thumbnail == undefined) thisThumbnail = "https://img.youtube.com/vi/" + video_id + "/hqdefault.jpg";
            else thisThumbnail = Player.np.thumbnail;
            Helper.removeClass("#player_overlay", "hide");
            Helper.css("#player_overlay", "display", "block");
            Helper.css("#player_overlay", "background", "url(" + thisThumbnail + ")");
            Helper.css("#player_overlay", "background-position", "center");
            Helper.css("#player_overlay", "background-size", "100%");
            Helper.css("#player_overlay", "background-color", "black");
            Helper.css("#player_overlay", "background-repeat", "no-repeat");
            Helper.css("#playing_on", "display", "flex");
            Helper.setHtml("#chromecast_text", "Playing on
" + castSession.getCastDevice().friendlyName);
        }
        Player.player.setVolume(100);
        Player.soundcloud_player.setVolume(1);
        Helper.addClass("#player_overlay_text", "hide");
    } else if(way == 0){
        if(!Helper.mobilecheck()) {
            if(M.Tooltip.getInstance(document.getElementsByClassName("castButton")[0])) {
                Helper.tooltip('.castButton', 'destroy');
            }
            Helper.tooltip('.castButton', {
                delay: 5,
                position: "top",
                html: "Cast Zoff to TV"
            });
        }
        Helper.removeClass('.castButton', 'castButton-white-active');
        Helper.toggleClass("#duration", "hide");
        Helper.toggleClass("#fullscreen", "hide");
        if(videoSource == "youtube") {
            Player.player.playVideo();
        } else if(videoSource == "soundcloud") {
            Player.soundcloud_player.play();
        }
        Player.stopInterval = false;
        duration = Player.player.getDuration();
        Player.durationSetter();
        if(!Helper.mobilecheck()){
            Player.player.setVolume(Crypt.get_volume());
            Playercontrols.visualVolume(Crypt.get_volume());
            Player.soundcloud_player.setVolume(embed ? 1 : Crypt.get_volume() / 100);
        }
        Helper.addClass("#player_overlay", "hide");
        Helper.removeClass("#player_overlay_text", "hide");
        Helper.setHtml("#chromecast_text", "");
        Helper.css("#playing_on", "display", "none");
        if(!offline){
            socket.emit('pos', {channel: chan.toLowerCase()});
        } else {
            Player.loadVideoById(video_id);
        }
    }
}
function chromecastListener(evt, data) {
    var json_parsed = JSON.parse(data);
    switch(json_parsed.type){
        case -1:
        if(offline){
            Player.playNext();
        } else {
            socket.emit("end", {id: json_parsed.videoId, channel: chan.toLowerCase()});
        }
        break;
        case 0:
        if(offline){
            Player.playNext();
        } else {
            emit("skip", {error: json_parsed.data_code, id: json_parsed.videoId, channel: chan.toLowerCase()});
        }
        break;
        case 1:
        Helper.addClass("#play", "hide");
        Helper.removeClass("#pause", "hide");
        break;
        case 2:
        Helper.addClass("#pause", "hide");
        Helper.removeClass("#play", "hide");
        break;
    }
}
function start_auth() {
    if(!user_auth_started) {
        user_auth_started = true;
        Helper.removeClass("#player_overlay", "hide");
        Helper.css("#player_overlay", "display", "block");
        M.Modal.getInstance(document.getElementById("user_password")).open();
        document.querySelector("#user-pass-input").focus();
        //Crypt.remove_userpass(chan.toLowerCase());
        before_toast();
        M.toast({html: "That is not the correct password, try again..", displayLength: 4000});
    }
}
function emit_list() {
    var add = "";
    //if(private_channel) add = Crypt.getCookie("_uI") + "_";
    /*var p = Crypt.crypt_pass(Crypt.get_userpass(chan.toLowerCase()), true);
    if(p == undefined) p = "";*/
    if(socket.id) {
        socket.emit("list", {version: parseInt(_VERSION), channel: add + chan.toLowerCase()});
    } else {
        setTimeout(function(){
            emit_list();
        }, 50);
    }
}
function get_list_ajax() {
    //var c = Crypt.get_userpass(chan.toLowerCase());
    Helper.ajax({
        type: "POST",
        data: {
            userpass: "",
            token: zoff_api_token,
        },
        headers: {"Content-Type": "application/json;charset=UTF-8"},
        url: "/api/list/" + Helper.encodeChannelName(chan.toLowerCase()),
        success: function(response) {
            response = JSON.parse(response);
            if(response.results.length > 0) {
                if(response.status == 403) {
                    start_auth();
                } else if(response.status == 404) return;
                if(client) {
                    Helper.removeElement("#channel-load");
                }
                List.populate_list(response.results);
            }
        },
        error: function(response) {
            //response = JSON.parse(response);
            if(response.status == 403) {
                start_auth();
            } else if(response.status == 429) {
                setTimeout(function() {
                    get_list_ajax();
                }, xmlhttp.getResponseHeader("Retry-After") * 1000)
            } else if(response.status == 404) return;
            if(client) {
                Helper.removeElement("#channel-load");
            }
            //List.populate_list(response.responseJSON.results);
        }
    });
}
function contextListener(that, event) {
    var parent = that.parentElement;
    var suggested = false;
    if(parent.id.indexOf("suggested-") > -1) suggested = true;
    document.getElementsByClassName("context-menu-root")[0].setAttribute("data-suggested", suggested);
    document.getElementsByClassName("context-menu-root")[0].setAttribute("data-id", parent.getAttribute("id").replace("suggested-", ""));
    Helper.removeClass("#context-menu-overlay", "hide");
    var left = event.pageX - document.querySelector(".context-menu-root").offsetWidth / 2;
    var top = event.pageY;
    if(left + 200 > window.innerWidth) {
        left = window.innerWidth - 200 - 15;
    } else if (left < 0) {
        left = 11;
    }
    if(top + 96 > window.innerHeight) {
        top = window.innerHeight - 96 - 15;
    } else if(top < 0) {
        top = 15;
    }
    if(parent.getAttribute("data-video-source") == "soundcloud") {
        Helper.addClass(".find-context-menu", "context-menu-disabled");
    } else {
        Helper.removeClass(".find-context-menu", "context-menu-disabled");
    }
    Helper.css(".context-menu-root", "left", left + "px");
    Helper.css(".context-menu-root", "top", top + "px");
    Helper.removeClass(".context-menu-root","hide");
    if(!Helper.mobilecheck()) {
        mouseContext(left, top);
    }
}
function inIframe () {
    try {
        return window.self !== window.top;
    } catch (e) {
        return true;
    }
}
function mouseContext(left, top) {
    var moveFunction = function( event ) {
        if(event.pageX < left - 60 || event.pageX > left + document.querySelector(".context-menu-root").offsetWidth + 60 ||
        event.pageY < top - 60 || event.pageY > top + document.querySelector(".context-menu-root").offsetHeight + 60) {
            Helper.addClass(".context-menu-root", "hide");
            Helper.addClass("#context-menu-overlay", "hide");
            document.removeEventListener("mousemove", moveFunction);
        }
    };
    try {
        document.removeEventListener("mousemove", moveFunction);
    } catch(e) {}
    document.addEventListener("mousemove", moveFunction, false);
}
function get_np_ajax() {
    /*var c = Crypt.get_userpass(chan.toLowerCase());
    if(c == undefined) c = "";*/
    Helper.ajax({
        type: "POST",
        data: {
            userpass: "",
            fetch_song: true,
            token: zoff_api_token
        },
        headers: {"Content-Type": "application/json;charset=UTF-8"},
        url: "/api/list/" + Helper.encodeChannelName(chan.toLowerCase()) + "/__np__",
        success: function(response) {
            response = JSON.parse(response);
            Player.getTitle(response.results[0].title, 1);
        },
        error: function(response, xmlhttp) {
            //response = JSON.parse(response);
            if(response.status == 403) {
                start_auth();
            } else if(response.status == 429) {
                setTimeout(function() {
                    get_np_ajax();
                }, xmlhttp.getResponseHeader("Retry-After") * 1000)
            }
        }
    })
}
function del_ajax(id) {
    /*var a = Crypt.get_pass(chan.toLowerCase());
    var u = Crypt.get_userpass(chan.toLowerCase());
    if(a == undefined) a = "";
    if(u == undefined) u = "";*/
    Helper.ajax({
        type: "DELETE",
        data: {
            adminpass: "",
            userpass: "",
            token: zoff_api_token
        },
        headers: {"Content-Type": "application/json;charset=UTF-8"},
        url: "/api/list/" + Helper.encodeChannelName(chan.toLowerCase()) + "/" + id,
        success: function(response) {
            toast("deletesong");
            get_list_ajax();
        },
        error: function(response, xmlhttp) {
            //response = JSON.parse(response);
            if(response.status == 403) {
                toast("listhaspass");
            } else if(response.status == 429) {
                setTimeout(function() {
                    del_ajax(id);
                }, xmlhttp.getResponseHeader("Retry-After") * 1000);
            }
        }
    })
}
function add_ajax(id, title, duration, playlist, num, full_num, start, end, source, thumbnail) {
    /*var a = Crypt.get_pass(chan.toLowerCase());
    var u = Crypt.get_userpass(chan.toLowerCase());
    if(a == undefined) a = "";
    if(u == undefined) u = "";*/
    Helper.ajax({
        type: "POST",
        data: {
            adminpass: "",
            userpass: "",
            title: title,
            duration: duration,
            end_time: end,
            start_time: start,
            thumbnail: thumbnail,
            source: source,
            token: zoff_api_token
        },
        headers: {"Content-Type": "application/json;charset=UTF-8"},
        url: "/api/list/" + Helper.encodeChannelName(chan.toLowerCase()) + "/" + id,
        success: function(response) {
            toast("addedsong");
            get_list_ajax();
        },
        error: function(response, xmlhttp) {
            //response = JSON.parse(response);
            if(response.status == 403) {
                toast("listhaspass");
            } else if(response.status == 409) {
                vote_ajax(id);
            } else if(response.status == 429) {
                setTimeout(function() {
                    add_ajax(id, title, duration, playlist, num, full_num, start, end);
                }, xmlhttp.getResponseHeader("Retry-After") * 1000);
            }
        }
    });
}
function vote_ajax(id) {
    /*var a = Crypt.get_pass(chan.toLowerCase());
    var u = Crypt.get_userpass(chan.toLowerCase());
    if(a == undefined) a = "";
    if(u == undefined) u = "";*/
    Helper.ajax({
        type: "PUT",
        data: {
            adminpass: "",
            userpass: "",
            token: zoff_api_token
        },
        headers: {"Content-Type": "application/json;charset=UTF-8"},
        url: "/api/list/" + Helper.encodeChannelName(chan.toLowerCase()) + "/" + id,
        success: function(response) {
            toast("voted");
            get_list_ajax();
        },
        error: function(response, xmlhttp) {
            //response = JSON.parse(response);
            if(response.status == 403) {
                toast("listhaspass");
            } else if(response.status == 429) {
                setTimeout(function() {
                    vote_ajax(id);
                }, xmlhttp.getResponseHeader("Retry-After") * 1000);
            }
        }
    })
}
function setup_auth_listener() {
    socket.on('auth_required', function() {
        start_auth();
    });
    socket.on('auth_accepted', function(msg) {
        if(msg.hasOwnProperty("value") && msg.value) {
            if(temp_user_pass != "") {
                userpass = temp_user_pass;
                //Crypt.set_userpass(chan.toLowerCase(), userpass);
            }
        }
    });
}
function setup_no_connection_listener(){
    socket.on('connect_failed', function(){
        Helper.log(['Connection Failed']);
        if(!connect_error){
            connect_error = true;
            M.toast({html: "Error connecting to server, please wait..", displayLength: 100000000, classes: "red lighten connect_error"});
        }
    });
    socket.on("connect_error", function(){
        Helper.log(["Connection Failed."]);
        if(!connect_error){
            connect_error = true;
            M.toast({html: "Error connecting to server, please wait..", displayLength: 100000000, classes: "red lighten connect_error"});
        }
    });
}
function loadChromecastVideo() {
    castSession = cast.framework.CastContext.getInstance().getCurrentSession();
    var _seekTo;
    try{
        if(videoSource == "youtube") {
            _seekTo = Player.player.getCurrentTime();
        } else if(videoSource == "soundcloud") {
            _seekTo = Player.soundcloud_player.currentTime() / 1000;
        }
    } catch(event){
        _seekTo = seekTo;
    }
    var mediaInfo = new chrome.cast.media.MediaInfo(video_id, "video");
    var image = {url:'https://img.youtube.com/vi/'+video_id+'/mqdefault.jpg', heigth: 180, width: 320};
    if(Player.np.thumbnail) image.url = Player.np.thumbnail;
    mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata();
    mediaInfo.metadata.title = Player.np.title;
    mediaInfo.metadata.image = image;
    mediaInfo.metadata.images = [image];
    var request = new chrome.cast.media.LoadRequest(mediaInfo);
    request.media.customData = {
        start: Player.np.start,
        end: Player.np.end,
        seekTo: _seekTo,
        channel: chan.toLowerCase(),
        source: videoSource,
        thumbnail: Player.np.thumbnail != undefined ? Player.np.thumbnail : 'https://img.youtube.com/vi/'+video_id+'/mqdefault.jpg',
    };
    castSession.loadMedia(request).then(function() {
        console.log("Loaded chromecast-video. Don't look here, look at your TV!");
    },
    function(errorCode) {
        console.log('Error code: ' + errorCode);
    });
}
function updateChromecastMetadata() {
    if(!chromecastAvailable) return;
    var image = {url:'https://img.youtube.com/vi/'+video_id+'/mqdefault.jpg', heigth: 180, width: 320};
    if(Player.np.thumbnail) image.url = Player.np.thumbnail;
    chrome.cast.media.GenericMediaMetadata({metadataType: 0, title:Player.np.title, image: image, images: [image]});
    return new chrome.cast.media.GenericMediaMetadata({metadataType: 0, title:Player.np.title, image: image, images: [image]});
}
function setup_now_playing_listener(){
    socket.on("np", Player.now_playing_listener);
}
function exitHandler(event) {
    if (document.webkitIsFullScreen || document.mozFullScreen || document.msFullscreenElement !== null) {
        if(!document.getElementById("main-row").classList.contains("fullscreened")) {
            Helper.addClass("#main-row", "fullscreened");
        } else {
            Helper.removeClass("#main-row", "fullscreened");
            document.querySelector(".host_switch_class").checked = false
            enable_host_mode(false);
        }
    }
}
function enable_host_mode(enabled) {
    if(!hostMode) {
        var playerElement = document.querySelector("main");
        var requestFullScreen = playerElement.requestFullScreen || playerElement.mozRequestFullScreen || playerElement.webkitRequestFullScreen;
        if (requestFullScreen) {
            requestFullScreen.bind(playerElement)();
            M.Tabs.getInstance(document.querySelector('.playlist-tabs-loggedIn')).select("wrapper");
            Helper.addClass("#main-row", "host-mode-height");
            Helper.addClass("#main-row", "host-mode-width");
            Helper.addClass("main", "host-mode-height");
            Helper.addClass("main", "host-mode-width");
            Helper.addClass("#video-container", "host-mode-height");
            Helper.addClass("#playlist", "host-mode-height");
            Helper.css(".playlist-tabs-loggedIn", "display", "none");
            Helper.removeClass("#wrapper", "tabs_height");
            Helper.addClass("#wrapper", "host-mode-wrapper");
            Helper.css(".skip", "display", "none");
            var removeElements = document.querySelectorAll(".list-remove");
            for(var i = 0; i < removeElements.length; i++) {
                removeElements[i].style.display = "none";
            }
            Helper.css(".prev", "display", "none");
            Helper.css("#fullscreen", "display", "none");
            Helper.css("#playlist", "backgroundColor", "inherit");
            Helper.css("#main-row", "backgroundColor", "inherit");
            Helper.css(".main", "backgroundColor", "inherit");
            Helper.removeClass("#host-title", "hide");
            Helper.css("#soundcloud_info_container", "display", "none");
            Helper.css("#player", "pointer-events", "none");
            hostMode = enabled;
            document.querySelector("#playlist").insertAdjacentHTML("beforeend", "