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 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 {
            Helper.removeClass("#player_overlay", "hide");
            Helper.css("#player_overlay", "display", "block");
            Helper.css("#player_overlay", "background", "url(https://img.ytimg.com/vi/" + video_id + "/hqdefault.jpg)");
            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.La.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(localStorage.getItem("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();
                }
                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)
            }
            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 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 updateChromecastMetadata() {
    if(!chromecastAvailable) return;
    var image = 'https://img.youtube.com/vi/'+video_id+'/mqdefault.jpg';
    if(Player.np.thumbnail) image = Player.np.thumbnail;
    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("#fullscreen", "display", "none");
            Helper.css("#playlist", "backgroundColor", "inherit");
            Helper.css("#main-row", "backgroundColor", "inherit");
            Helper.css(".main", "backgroundColor", "inherit");
            hostMode = enabled;
            document.addEventListener('webkitfullscreenchange', exitHandler, false);
            document.addEventListener('mozfullscreenchange', exitHandler, false);
            document.addEventListener('fullscreenchange', exitHandler, false);
            document.addEventListener('MSFullscreenChange', exitHandler, false);
        }
    } else {
        Helper.removeClass("#main-row", "host-mode-height");
        Helper.removeClass("#main-row", "host-mode-width");
        Helper.removeClass(".main", "host-mode-height");
        Helper.removeClass(".main", "host-mode-width");
        Helper.removeClass("#video-container", "host-mode-height");
        Helper.removeClass("#playlist", "host-mode-height");
        Helper.css(".playlist-tabs-loggedIn", "display", "flex");
        Helper.addClass("#wrapper", "tabs_height");
        Helper.removeClass("#wrapper", "host-mode-wrapper");
        Helper.css(".skip", "display", "block");
        var removeElements = document.querySelectorAll(".list-remove");
        for(var i = 0; i < removeElements.length; i++) {
        	removeElements[i].style.display = "block";
        }
        Helper.css("#fullscreen", "display", "block");
        hostMode = false;
    }
}
function get_list_listener(){
    socket.on("get_list", function(){
        var add = "";
        socket_connected = true;
        //if(private_channel) add = Crypt.getCookie("_uI") + "_";
        /*var p = Crypt.crypt_pass(Crypt.get_userpass(chan.toLowerCase()), true);
        if(p == undefined) p = "";*/
        socket.emit("list", { offline: offline, version: parseInt(localStorage.getItem("VERSION")), channel: add + chan.toLowerCase()});
    });
    socket.on("id_chromecast", function(msg) {
        chromecast_specs_sent = true;
        castSession.sendMessage("urn:x-cast:zoff.me", {type: "mobilespecs", guid: msg.guid, socketid: msg.cookie_id, channel: chan.toLowerCase()})
    })
}
function setup_suggested_listener(){
    if(client) return;
    socket.on("suggested", function(params){
        var single = true;
        if(params.id === undefined)
        single = false;
        Suggestions.catchUserSuggests(params, single);
    });
}
function setup_viewers_listener(){
    socket.on("viewers", function(view){
        viewers = view;
        var outPutWord    = "visibility"//v > 1 ? "viewers" : "viewer";
        Helper.setHtml("#viewers", outPutWord + " " + view);
        if(song_title !== undefined)
        Player.getTitle(song_title, viewers);
    });
}
function setup_admin_listener(){
    socket.on("toast", toast);
    socket.on("pw", Admin.pw);
    socket.on("conf", Admin.conf);
}
function setup_chat_listener(){
    socket.on("chat_history", function(msg) {
        var data = msg.data;
        for(var i = 0; i < data.length; i++) {
            if(msg.all) {
                Chat.allchat(data[i], data[i].createdAt, true);
                document.getElementById("chatall").scrollTop = document.getElementById("chatall").scrollHeight;
            } else {
                Chat.channelchat(data[i], data[i].createdAt, true);
                document.getElementById("chatchannel").scrollTop = document.getElementById("chatchannel").scrollHeight;
            }
        }
    });
    socket.on("chat.all", Chat.allchat);
    socket.on("chat", Chat.channelchat);
}
function setup_list_listener(){
    if(!offline) {
        socket.on("color", Player.setBGimage);
    }
    socket.on("channel", List.channel_function);
}
function setup_playlist_listener(){
    Helper.log(["Setting up playlist_listener"]);
    socket.on('playlists', Frontpage.frontpage_function);
}
function setup_host_initialization(){
    if(!client) {
        Helper.log(["Setting up host initialization listener"]);
        socket.on("id", Hostcontroller.host_listener);
    }
}
function setup_host_listener(id){
    if(!client) {
        Helper.log(["Setting up host action listener"]);
        socket.on(id, Hostcontroller.host_on_action);
    }
}
function enable_debug(){
    localStorage.debug = true;
}
function disable_debug(){
    localStorage.debug = false;
}
function embed_code(autoplay, width, height, color, embed_code){
    var autoplay_add = "";
    if(autoplay == "&autoplay") autoplay_add = 'allow="autoplay"';
    return '';
}
function change_offline(enabled, already_offline){
    if(client) {
        offline = false;
        return;
    }
    Crypt.set_offline(enabled);
    offline = enabled;
    ga('send', 'event', "button-click", "offline", "", offline ? 1 : 0);
    socket.emit("offline", {status: enabled, channel: chan != undefined ? chan.toLowerCase() : ""});
    if(!Helper.mobilecheck()) {
        if(document.querySelectorAll("#offline-mode").length == 1 && M.Tooltip.getInstance(document.getElementById("offline-mode"))) {
            Helper.tooltip("#offline-mode", 'destroy');
        }
    }
    var mouseEnter = function(e){
        Helper.removeClass("#seekToDuration", "hide");
    };
    var mouseLeave = function(e){
        dragging = false;
        Helper.addClass("#seekToDuration", "hide");
    };
    var mouseDown = function(e) {
        var acceptable = ["bar", "controls", "duration"];
        if(acceptable.indexOf(e.target.id) >= 0) {
            dragging = true;
        }
    };
    var mouseUp = function(e) {
        dragging = false;
    };
    if(enabled){
        /*if(list_html == undefined){
            var tempOuter = document.createElement("div");
            list_html.innerHTML = list_html;
            //list_html.find(".list-remove").removeClass("hide");
            list_html = list_html.innerHTML;
        }*/
        //$(".list-remove").removeClass("hide");
        Helper.addClass("#viewers", "hide");
        Helper.removeClass(".margin-playbar", "margin-playbar");
        Helper.addClass(".prev playbar", "margin-playbar");
        Helper.removeClass(".prev playbar", "hide");
        Helper.removeClass("#offline-mode", "waves-cyan");
        Helper.addClass("#offline-mode", "cyan");
        Helper.removeClass(".delete-context-menu", "context-menu-disabled");
        if(!Helper.mobilecheck()) {
            Helper.tooltip("#offline-mode", {
                delay: 5,
                position: "bottom",
                html: "Disable local mode"
            });
        }
        if(window.location.pathname != "/"){
            socket.removeEventListener("color");
            document.getElementById("controls").addEventListener("mouseenter", mouseEnter, false);
            document.getElementById("controls").addEventListener("mouseleave", mouseLeave, false);
            document.getElementById("controls").addEventListener("mousedown", mouseDown, false);
            document.getElementById("controls").addEventListener("mouseup", mouseUp, false);
            document.getElementById("controls").addEventListener("mousemove", Channel.seekToMove);
            document.getElementById("controls").addEventListener("click", Channel.seekToClick);
            document.querySelector("#main_components").insertAdjacentHTML("beforeend", "