/*
fore.st is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

fore.st is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with fore.st. If not, see < http://www.gnu.org/licenses/ >.
(C) 2022- by rainbownapkin, <ourforest@420blaze.it>
*/

//---Global Variables---
CURRENTFPANEL = null;

//---Global Functions---
function closeFPanel(cb){//close and null out fpanel, cb function to call when panel is closed
	$("#fpaneldiv").hide("slide", 250,function(){
		if(typeof CURRENTFPANEL.ccall === 'function'){
			CURRENTFPANEL.ccall();
		}
		$("#fpcontdiv").empty();
		$("#fptitle").html("null Panel");
		$("#closefpanel").prop("title", "Close null panel.");
		CURRENTFPANEL = null;
		if(typeof cb === 'function'){
			cb();
		}
	});
}

function sizeFPDiv(){//set inner div height to fix overflow
	$("#fpaneldiv").outerWidth($("#chatwrap").outerWidth() * 0.7);
        $("#fpcontdiv").outerHeight($("#fpaneldiv").height() - $("#fptitlediv").outerHeight());
	if(CURRENTFPANEL != null){
		CURRENTFPANEL.size();
	}
}

function panelbtn(panel){
	if($("#fpaneldiv").is(":visible")){//if panel is visible
		difClose = CURRENTFPANEL != panel;//set difclose to if CURRENTPANEL is the same one attatched to the button we're clicking
		closeFPanel(function(){//closem panel
			if(difClose){//if
				panel.popMenu(panel.data);//pop da panel
			}
		});
	}else{//else
		panel.popMenu(panel.data);//pop that bitch son
	}
}

//---base panel---
function fpmenu(title, elm, data, ocall, ccall){//fpmenu constructor
	this.title = title;//title of menu
	this.elm = elm;//elements to insert (good for simple menus)
	this.data = data;//menu data (not used for all menus)
	this.ocall = ocall;//function to call upon menu opening (used for more advanced menus)
	this.ccall = ccall;//function to call upon menu closing
}

fpmenu.prototype.popMenu = function(idata){//POP goes the weasal!
	if(CURRENTFPANEL != null)
		if(typeof CURRENTFPANEL.ccall === 'function'){
				CURRENTFPANEL.ccall();
		}
	this.data = idata//set data
	$("#fpcontdiv").empty();//empty content div
	$("#fptitle").html(this.title + " Panel");//set panel tittle
	$("#closefpanel").prop("title", "Close " + this.title + " panel.");//set close button hover text
	$("#fpcontdiv").append(this.elm);//append element array
	this.ocall(this.data);//run open function
	CURRENTFPANEL = this;
	$("#fpaneldiv").show("slide", 250, function() {sizeFPDiv()});//show panel and correct size once open
}

fpmenu.prototype.size = function(){
};
//---base nested menu bar---
function nmenu(title,p,menus,elm){//nested menu constructor(title(defaults to formatted parent title), parent, menu object array,append element(defaults to #fpcontdiv)
	this.title = (title == null ? p.title.toLowerCase().replace(' ','-') + "-nested" : title);
	this.parent = p;
	this.menus = menus;
	this.elm = (elm == null ? $("#fpcontdiv") : elm);
}

nmenu.prototype.popMenu = function(){//instantiate nested menu, to be thrown at end of ocall
	melm = $("<div>").attr("id",this.title).addClass("nmenu");//create nmenu div
	par = this.parent;
	this.elm.append(melm.append(
		$("<button>").addClass("btn btn-sm btn-default nmenu-btn panelback").attr("id",this.parent.title.toLowerCase().replace(' ','-')+"-nested-btn").html(this.parent.title).click(function(ev){
			if(CURRENTFPANEL !== par){
				par.popMenu();
			}
		})
	));
	this.menus.map(function(menu){//for every menu in menus array
		melm.append(
			$("<button>").addClass("btn btn-sm btn-default nmenu-btn nmenu-border panelback").attr("id",menu.title.toLowerCase().replace(' ','-')+"-nested-btn").html(menu.title).click(function(){
				if(CURRENTFPANEL !== menu){
					menu.popMenu();
				}
			})
		);
	});
}

//---fpanel poll---
var fpoll = new fpmenu("Poll");//create new panel fpoll

fpoll.elm = [//fpoll element array
	$("<h3>").prop("id","polltitle").html("Null Poll Title")//poll title
]

fpoll.ocall = function(data){//fpoll open call function
	$("#polltitle").html("Poll: " + data.title);//set poll title
	if(hasPermission("pollctl")) {//if ur allowed to fuck wit da poll
            $("<button/>").addClass("btn btn-danger btn-sm pull-right").text("End Poll")//add end poll button
		.prop("id","endpollbtn")//set id
                .appendTo("#fpcontdiv")//append
                .click(function() {//click event
                    socket.emit("closePoll")//endem poll
                });
        }

	for(var i = 0; i < data.options.length; i++) {//fer all the options in the poll
            (function(i) {
            var callback = function () {//create callback function
                socket.emit("vote", {//send vote
                    option: i//use current option
                });
                $("#fpcontdiv").find(".option button").each(function() {//find currently selected button
                    $(this).removeClass("active");//unselect it
                    $(this).parent().removeClass("option-selected");
                });
                $(this).addClass("active");//set current option as actively selected
                $(this).parent().addClass("option-selected");
            }
            $("<button/>").addClass("btn btn-default btn-sm").text(data.options[i])//add button
                .prependTo($("<div/>").addClass("option").html('<p style="display: inline;">' + data.counts[i] + "</p>")//set cont labels
                        .appendTo("#fpcontdiv"))//append them to div
                .click(callback);//add click event to callback function
            })(i);
        }
}

fpoll.updatePoll = function(data){//updatem poll
	var poll = $("#pollwrap .active");
        var i = 0;
       $("#fpcontdiv").find(".option p").each(function() {//for every option
            $(this).html(data.counts[i]);//correct count labels
            i++;//increment counter
        });
}

fpoll.closePoll =  function(data){//close poll
        tmpttl = $("#polltitle").html();//grab poll title
	$("#polltitle").html(tmpttl + " (Poll Closed)");//add closed label
	$("#pollopenbtn").hide("blinds");//hide poll button

	$("#fpcontdiv").find(".option button").each(function() {//disable poll buttons
		$(this).prop("disabled", true);
	});

	$("#fpcontdiv").find(".btn-danger").each(function() {//remove end poll button 
		$(this).remove()
	});
}

//---emote panel---
var fpemote = new fpmenu("Emote");//create fpemote new fpanel obj

fpemote.isAlpha = true;//isAlpha to true because this emote panel is a fucking chad

fpemote.ocall = function(data){//fpemote open function
	let symask = /["!#$%&'()*+,-./:;<=>?@[\]^_`{|}~]/g;//symbol mask

	$("<form>").prop("action","javascript:void(0)").prop("id","emotecont").append([//top inputs
		$("<input>").prop("placeholder","Search Emotes").prop("type","text").prop("id", "esearchbar").addClass("form-control").keyup(function(ev){//emote search bar
			fpemote.searchEmote($("#esearchbar").val());//search for emotes when key as users finger lifts up
		}),
		$("<span>").prop("id","anumspan").append([//alphanumspan
			$("<input>").prop("id","emotealphabox").prop("type", "checkbox").prop("checked", fpemote.isAlpha).click(function(){//alphanum sort checkbox
				fpemote.alphaPop($("#emotealphabox").prop("checked"));//pop alphanum sort
			}),
			$("<label>").prop("for", "emotealphabox").addClass("glyphicon glyphicon-sort-by-alphabet")//alphanum sort label
		])
	]).appendTo("#fpcontdiv");//add search bar, adding this in elm causes strange behavior

	$("<div>").addClass("emotecontdiv").appendTo("#fpcontdiv");//add emote container div, creating this in elm causes obnoxious behaviour

	fpemote.alpha = window.CHANNEL.emotes.slice(0);//create second emote array
	fpemote.alpha.sort((a, b) => a.name.replace(symask, '').toLowerCase().localeCompare(b.name.replace(symask, '').toLowerCase()));//sort it by alphabetical


	earray = fpemote.isAlpha ? fpemote.alpha : window.CHANNEL.emotes//use the alphanum sorted array if alphanum sort is enabled

	earray.forEach(function(value){//for every emote
		fpemote.popEmote(value);//poulate emotes
	});
}

fpemote.popEmote = function(emote){
	$("<div>").addClass("emotediv").append([//add new div for every emote
		$("<span>").prop("id","emspan").append($("<img>").prop("src", emote.image)),//insert emote thumbnails
		$("<p>").html(emote.name),//insert emote name labels
	]).click(function(){//find current emote and add onclick function
		chatpaste(emote.name);//paste emote name
		closeFPanel();//close fpanel
	}).appendTo(".emotecontdiv");//append to emote container div
}

fpemote.searchEmote = function(sstring){
	i = 0;
	$(".emotecontdiv").empty();
	earray = fpemote.isAlpha ? fpemote.alpha : window.CHANNEL.emotes
	earray.forEach(function(value){
		if(value.name.toLowerCase().includes(sstring.toLowerCase()) || (sstring == null || sstring == "")){
			i++;
			fpemote.popEmote(value);
		}
	});

	if(i <= 2){
		$(".emotecontdiv").prop("style", "grid-template-columns: auto");
	}else{
		$(".emotecontdiv").prop("style", "");
	}
}

fpemote.alphaPop = function(setalpha){
	$(".emotecontdiv").empty();
	if(setalpha == null){
		fpemote.isAlpha = !fpemote.isAlpha;
	}else{
		fpemote.isAlpha = setalpha
	}
	earray = fpemote.isAlpha ? fpemote.alpha : window.CHANNEL.emotes
	if($("#esearchbar").val() != ""){
				fpemote.searchEmote($("#esearchbar").val());
	}else{
		earray.forEach(function(value){//for every emote
			fpemote.popEmote(value);//poulate emotes
		});
	}
}

//---Quick Settings Panel---
var fpset = new fpmenu("Quick Settings");

fpset.ocall = function(){
	$("#fpcontdiv").append(spanel = $("<div>").prop("id","fpsetdiv"));

	spanel.append([
		$("<h4>").html("General Preferences"),

		$("<form>").append(
			$("<label>").prop("for","qs-theme").html("Theme: "),
			$("<select>").prop("id","qs-theme").addClass("qs-form").change(function() {
    				USEROPTS.theme = $("#qs-theme").val();
				processOpts();
			}),
		),
		$("<form>").append(
			$("<label>").prop("for","qs-chat-min").html("Min Chat Width (Locked to Aspect only): "),
			$("<input>").prop("id","qs-chat-min").prop("type","text").addClass("qs-form").change(function() {
				USEROPTS.chat_min = ($("#qs-chat-min").val() >= 80 ? 80 : $("#qs-chat-min").val());
				$("#qs-chat-min").val(USEROPTS.chat_min)
				processOpts();
			}).keydown(function(ev){if(ev.keyCode === 13){$(this).change();return false;}}),
		),

		$("<h4>").html("Playback Preferences"),

		$("<p>").html("Video Orientation: "),
		$("<span>").prop("id","flipx-video").addClass("qsbtn glyphicon glyphicon-resize-horizontal pointer").prop("title", "Flip Player Horizontally").attr("onclick",'javascript:$("#ytapiplayer").toggleClass("mirx")'),
		$("<span>").prop("id","flipy-video").addClass("qsbtn glyphicon glyphicon-resize-vertical pointer").prop("title", "Flip Player Vertically").attr("onclick",'javascript:$("#ytapiplayer").toggleClass("miry")'),

		$("<form>").append(
			$("<label>").prop("for","qs-orient-buttons").html("Video Orientation Buttons on Titlebar: "),
			$("<input>").prop("id","qs-orient-buttons").prop("type","checkbox").addClass("qs-form").change(function() {
				USEROPTS.show_orientation = $("#qs-orient-buttons").prop("checked");
				processOpts();
			}),
		),

		$("<form>").append(
			$("<label>").prop("for","qs-sync-threshold").html("Sync Threshold(seconds): "),
			$("<input>").prop("id","qs-sync-threshold").prop("type","text").addClass("qs-form").change(function() {
				USEROPTS.sync_accuracy = parseFloat($("#qs-sync-threshold").val()) || 2;
				processOpts();
			}).keydown(function(ev){return !(ev.keyCode === 13)}),
		),

		$("<form>").append(
			$("<label>").prop("for","qs-yt-source").html("Youtube Source: "),
			$("<select>").prop("id","qs-yt-source").addClass("qs-form").change(function(){
				USEROPTS.yt_source = $("#qs-yt-source").val();
				processOpts();
			}),
		),


		$("<h4>").html("Chat Preferences"),
		$("<form>").append(
			$("<label>").prop("for","qs-legacy-emote").html("Use legacy cytube emote menu: "),
			$("<input>").prop("id","qs-legacy-emote").prop("type","checkbox").addClass("qs-form").change(function() {
				USEROPTS.legacy_emote = $("#qs-legacy-emote").prop("checked");
				processOpts();
			}),
		),

		$("<form>").append(
			$("<label>").prop("for","qs-blink-title").html("Blink page title on new messages: "),
			$("<select>").prop("id","qs-blink-title").addClass("qs-form").change(function() {
				USEROPTS.blink_title = $("#qs-blink-title").val();
				processOpts();
			}),
		),

		$("<form>").append(
			$("<label>").prop("for","qs-boop").html("Beep on new message: "),
			$("<select>").prop("id","qs-boop").addClass("qs-form").change(function() {
				USEROPTS.boop = $("#qs-boop").val();
				processOpts();
			}),
		),

                $("<form>").append(
			$("<label>").prop("for","qs-notifications").html("Browser Notification on new message: "),
			$("<select>").prop("id","qs-notifications").addClass("qs-form").change(function() {
				USEROPTS.notifications = $("#qs-notifications").val();
				processOpts();
			}),
		),

		$("<form>").append(
			$("<label>").prop("for","qs-show-timestamp").html("Show Timestamps (reqs refresh on enable): "),
			$("<input>").prop("id","qs-show-timestamp").prop("type","checkbox").addClass("qs-form").change(function() {
				USEROPTS.show_timestamps = $("#qs-show-timestamps").prop("checked");
				processOpts();
			}),
		),

		$("<form>").append(
			$("<label>").prop("for","qs-timestamp-second").html("Show Seconds on Timestamps: "),
			$("<input>").prop("id","qs-timestamp-second").prop("type","checkbox").addClass("qs-form").change(function() {
				USEROPTS.show_seconds = $("#qs-timestamp-second").prop("checked");
				processOpts();
			}),
		),
		$("<form>").append(
			$("<label>").prop("for","qs-toke-pm").html("Legacy Toke Notification: "),
			$("<input>").prop("id","qs-toke-pm").prop("type","checkbox").addClass("qs-form").change(function() {
				USEROPTS.toke_pm = $("#qs-toke-pm").prop("checked");
				processOpts();
			}),
		),
	])
	this.loadSettings();
}

fpset.loadSettings = function(){
	$("#us-theme").children().clone().appendTo($("#qs-theme"));
	$("#qs-chat-min").val(USEROPTS.chat_min);
	$("#us-yt-source").children().clone().appendTo($("#qs-yt-source"));
	$("#qs-theme").val(USEROPTS.theme);
	$("#qs-orient-buttons").prop("checked", USEROPTS.show_orientation);
	$("#qs-sync-threshold").val(USEROPTS.sync_accuracy);
	$("#qs-yt-source").val(USEROPTS.yt_source);
	$("#qs-legacy-emote").prop("checked", USEROPTS.legacy_emote);
	$("#us-blink-title").children().clone().appendTo($("#qs-blink-title"));
	$("#qs-blink-title").val(USEROPTS.blink_title);
	$("#us-ping-sound").children().clone().appendTo($("#qs-boop"));
	$("#qs-boop").val(USEROPTS.boop);
	$("#us-notifications").children().clone().appendTo($("#qs-notifications"));
	$("#qs-notifications").val(USEROPTS.notifications);
	$("#qs-show-timestamp").prop("checked", USEROPTS.show_timestamps);
	$("#qs-timestamp-second").parent().toggle(USEROPTS.show_timestamps);
	$("#qs-timestamp-second").prop("checked", USEROPTS.show_seconds);
	$("#qs-toke-pm").prop("checked", USEROPTS.toke_pm);
}


//---admin/mod panel---
var fpmod = new fpmenu("Mod");//create new panel fpmod

fpmod.elm = [//fpmod element array
]

fpmod.ocall = function(){
	//---Local Functions---
	//---Poll Creation---
	function addOpt(){
		i = $("#opts").children().length;
		$("#opts").append(
			$("<input>").addClass("npoll-opt qs-form").prop("type","text").attr("placeholder","Option " + i)
		);
	}
	function rmOpt(){
		if($("#opts").children().length > 2){
			$("#opts").children()[$("#opts").children().length - 1].remove();
		}
	}
	//Mod Message
	function modMsg(){
		var names = [];
		var msg = $("#qt-modmsg").val().toString();
		$("#userlist").children().map(function(i, usr){
			cn = usr.children[1].className;
			if((cn === "userlist_siteadmin" || cn === "userlist_owner" || cn === "userlist_op") && usr.children[1].innerHTML !== CLIENT.name){//for all mods
				var meta = {};//sendem msg
				if (msg.trim() === "") {
					return;
				}

				if (USEROPTS.modhat && CLIENT.rank >= Rank.Moderator) {
					meta.modflair = CLIENT.rank;
				}

				if (CLIENT.rank >= 2 && msg.indexOf("/m ") === 0) {
					meta.modflair = CLIENT.rank;
					msg = msg.substring(3);
				}


				socket.emit("pm", {
					to: usr.children[1].innerHTML,
					msg: msg,
					meta: meta
				});
			}
		});
		$("#qt-modmsg").val("");
	}

	//---Main Append---
	$("#fpcontdiv").append(//main append
		$("<h4>").html("Poll Creation"),
		$("<form>").append(
			$("<input>").prop("id","npoll-title").prop("type","text").addClass("qs-form").attr("placeholder","Poll Title"),
			$("<input>").prop("id","npoll-timeout").prop("type","text").addClass("qs-form").attr("placeholder","Timer"),
			$("<button/>").addClass("btn btn-primary btn-ln").text("Create Poll").prop("type","button").click(function(){
				var menu = $("#fpcontdiv");
				var title = $("#npoll-title");
				var timeout = $("#npoll-timeout");
				var hidden = $("#npoll-hide-result");
				var retainVotes = $("#npoll-keep-vote");
				var t = timeout.val().trim();
					    if (t) {
						try {
						    t = parseTimeout(t);
						} catch (e) {
						    if (timeoutError) {
							timeoutError.remove();
						    }
						    timeoutError = $("<p/>").addClass("text-danger").text(e.message);
						    timeoutError.insertAfter(timeout);
						    timeout.focus();
						    return;
						}
					    } else {
						t = undefined;
					    }
					    var opts = [];
					    menu.find(".npoll-opt").each(function() {
						if($(this).val() != "")
						    opts.push($(this).val());
					    });
					    socket.emit("newPoll", {
						title: title.val(),
						opts: opts,
						obscured: hidden.prop("checked"),
						retainVotes: retainVotes.prop("checked"),
						timeout: t
					    }, function ack(result) {
						if (result.error) {
						    modalAlert({
							title: 'Error creating poll',
							textContent: result.error.message
						    });
						}
					    });
			}),
		),
		$("<form>").append(
			$("<label>").prop("for","npoll-hide-result").html("Hide result until poll closes: "),
			$("<input>").prop("id","npoll-hide-result").prop("type","checkbox").addClass("qs-form")
		),
		$("<form>").append(
			$("<label>").prop("for","npoll-keep-vote").html("Keep user's vote after disconnect: "),
			$("<input>").prop("id","npoll-keep-vote").prop("type","checkbox").addClass("qs-form")
		),
		$("<span>").append(
			$("<button/>").addClass("btn btn-primary btn-ln").text("-").prop("type","button").click(rmOpt),
			$("<p>").html(" Poll Opts "),
			$("<button/>").addClass("btn btn-primary btn-ln").text("+").prop("type","button").click(addOpt)
		).attr("id","npopt"),
		$("<form>").attr("id", "opts"),
		//---Quick Tools---
		$("<h4>").html("Quick Tools"),
		$("<form>").addClass("qt").append(
			$("<button/>").addClass("btn btn-primary btn-ln").attr("id","qt-announcebtn").text("!announce").prop("type","button").click(function(){
				chatsmack("!announce " + $("#qt-announce").val());
			}),
			$("<input>").prop("id","qt-announce").prop("type","text").addClass("qs-form").attr("placeholder","Announce text.").keydown(function(ev){
				if(ev.keyCode==13){
					chatsmack("!announce " + $("#qt-announce").val());
					return false;
				}
			})
		),
		$("<form>").addClass("qt").append(
			$("<button/>").addClass("btn btn-primary btn-ln").attr("id","qt-clearbtn").text("!clear").prop("type","button").click(function(){
				chatsmack("!clear " + $("#qt-clearuser").val());
			}),
			$("<select>").prop("id","qt-clearuser").addClass("qs-form").append($('<option value=""></option>'))
		),
		$("<form>").addClass("qt").append(
			$("<input>").prop("id","qt-modmsg").prop("type","text").addClass("qs-form").attr("placeholder","Mod Message").keydown(function(ev){
				if(ev.keyCode==13){
					modMsg();
					return false;
				}
			}),
			$("<button/>").addClass("btn btn-primary btn-ln").text("Send Mod Msg").prop("type","button").click(modMsg)
		),
		//---Preferences---
		$("<h4>").html("Quick Settings"),
		$("<span>").addClass("qt").attr("id","qt-modflair").addClass($("#modflair").attr("class")).html("Modflair").click(modflair),
		$("<form>").append(
			$("<label>").prop("for","mp-show-ip-in-tooltip").html("Show IP in profile tooltips: "),
			$("<input>").prop("id","mp-show-ip-in-tooltip").prop("type","checkbox").addClass("qs-form").prop("checked",USEROPTS.show_ip_in_tooltip).change(function() {
				USEROPTS.show_ip_in_tooltip = $("#mp-show-ip-in-tooltip").prop("checked");
				processOpts();
			}),
		),
		$("<form>").append(
			$("<label>").prop("for","mp-shadowchat").html("Show Shadowmuted Messages: "),
			$("<input>").prop("id","mp-shadowchat").prop("type","checkbox").addClass("qs-form").prop("checked",USEROPTS.show_shadowchat).change(function() {
				USEROPTS.show_shadowchat = $("#mp-shadowchat").prop("checked");
				processOpts();
			}),
		),
		$("<form>").append(
			$("<label>").prop("for","mp-show-playlist").html("Legacy Playlist: "),
			$("<input>").prop("id","mp-show-playlist").prop("type","checkbox").addClass("qs-form").prop("checked",USEROPTS.show_playlist).change(function() {
				USEROPTS.show_playlist = $("#mp-show-playlist").prop("checked");
				processOpts();
			}),
		),
		$("<form>").append(
			$("<label>").prop("for","mp-scroll-playlist").html("Scroll playlist on change: "),
			$("<input>").prop("id","mp-scroll-playlist").prop("type","checkbox").addClass("qs-form").prop("checked",USEROPTS.scroll_list).change(function() {
				USEROPTS.scroll_list = $("#mp-scroll-playlist").prop("checked");
				processOpts();
			}),
		),
		$("<form>").append(
			$("<label>").prop("for","mp-add-invid").html("Queue Invidious URLs as Youtube: "),
			$("<input>").prop("id","mp-add-invid").prop("type","checkbox").addClass("qs-form").prop("checked",USEROPTS.add_invid).change(function() {
				USEROPTS.add_invid = $("#mp-add-invid").prop("checked");
				processOpts();
			}),
		),

	);

	//after-append
	//---Poll Creation---
	addOpt();
	addOpt();
	//---Quick Tools---
	usrColors[0].map(function(u){
		if(u !== "tokebot"){
			$("#qt-clearuser").append($('<option value="' + u + '">' + u + "</option>"));
		}
	});
	modNested.popMenu();
}
//---Mod Panel Nested Panels---
//---Playlist---
var fpplaylist = new fpmenu("Playlist");//create new panel fpmod

fpplaylist.elm = [//fpmod element array
]

fpplaylist.ocall = function(){
	modNested.popMenu();
	if(!USEROPTS.show_playlist){
		prow = $("#playlistrow").show().appendTo("#fpcontdiv");
		prow.find("#rightcontrols").show().addClass("floatcont").prependTo("#fpcontdiv");
		$("#rightpane").css("background-color","rgba(0,0,0,0)");

		this.size();
		scrollQueue(true);
	}else{
		$("<h4>").html("Please disable the Legacy Playlist setting to use this tab.").appendTo("#fpcontdiv");
	}


}

fpplaylist.size = function(){
		nesth = $("#mod-nested").outerHeight();
		panlh = $("#fpcontdiv").outerHeight();

		scont = $("#searchcontrol").is(":visible") ? $("#searchcontrol").outerHeight() : 0;
		aurl = $("#addfromurl").is(":visible") ? $("#addfromurl").outerHeight() : 0;
		cembed = $("#customembed").is(":visible") ? $("#customembed").outerHeight() : 0;
		pman = $("#playlistmanager").is(":visible") ? $("#playlistmanager").outerHeight() : 0;
		qfail = $("#queuefail").is(":visible") ? $("#queuefail").outerHeight() : 0;
		conth = $("#rightcontrols").outerHeight() - (scont + aurl + cembed + pman + qfail);
		prow.find("#queue").css("max-height", panlh - conth - nesth + "px").css("margin-top",conth + "px").css("margin-bottom", nesth + "px");
}

fpplaylist.ccall = function(){
	if(!USEROPTS.show_playlist){
		$("#rightcontrols").hide().removeClass("floatcont").prependTo("#rightpane-inner");
		$("#playlistrow").hide().appendTo($(".container")[0]);
		$("#queue").css("max-height","500px").css("margin-top","0px").css("margin-bottom","0px");
		$("#rightpane").css("background-color","");
	}
}

//---Autobump---
var fpbump = new fpmenu("Auto Bump");//create new panel fpmod

fpbump.elm = [//fpmod element array
]

fpbump.ocall = function(){
	modNested.popMenu();

	var ladd = $("<form>").addClass("ab-newlist-form").append(
				$("<input>").prop("id","ab-newlist-name").prop("type","text").addClass("qs-form").attr("placeholder", "New Bumplist Title").keydown(function(ev){if(ev.keyCode === 13){$("#ab-newlist-newbtn").click();}}),
				//$("<button/>").addClass("btn btn-primary btn-ln").text("Add List").prop("type","button").click(function(){
				$("<span>").addClass("ab-bumparray-edit qsbtn glyphicon glyphicon-plus-sign pointer").attr("title","Create New Bumplist").attr("id","ab-newlist-newbtn").click(function(){
					var nlname = $("#ab-newlist-name").val()
					if(nlname != null && nlname !== ""){
						socket.emit("newBumplist",nlname);
						$("#ab-newlist-name").val("");
						$(this).parent().after(laddbtn.clone(true));
						$(".ab-newlist-form").remove();
					}

				}),
				$("<span>").addClass("qsbtn glyphicon glyphicon-import pointer").attr("title","Clone Bumplist from Queue").attr("id","ab-newlist-clonebtn").click(function(){
					var nlname = $("#ab-newlist-name").val()
					if(nlname != null && nlname !== ""){
						socket.emit("cloneBumplist",nlname);
						$("#ab-newlist-name").val("");
						$(this).parent().after(laddbtn.clone(true));
						$(".ab-newlist-form").remove();
					}

				}),
				$("<span>").addClass("ab-bumparray-edit qsbtn glyphicon glyphicon-ban-circle pointer").attr("title","Cancel").click(function(){
					$(this).parent().after(laddbtn.clone(true));
					$(".ab-newlist-form").remove();
				}),
	);

	var laddbtn = $("<span>").prop("id","ab-newlist-btn").addClass("ab-bumparray-edit qsbtn glyphicon glyphicon-plus-sign pointer").attr("title","Add Bumplist").click(function(){
			$(this).replaceWith(ladd.clone(true));
	});

	var alists = [];
	CHANNEL.bumpdata.active.forEach(function(bname){
		CHANNEL.bumpdata.lists.forEach(function(list){
			if(list.lowername === bname)
				alists.push(list);
		});
	});

	$("#fpcontdiv").append(
		$("<div>").attr("id","abumpdiv").append(
		$("<h4>").html("General Config"),
		$("<form>").append(
			$("<label>").prop("for","ab-agro").html("Agression Level: "),
			$("<select>").prop("id","ab-agro").prop("type","text").addClass("qs-form").change(function() {
				  socket.emit("setAgro", parseInt($("#ab-agro").val()));
			}).append(
				$("<option>").val(0).html("0"),
				$("<option>").val(1).html("1"),
				$("<option>").val(2).html("2"),
				$("<option>").val(3).html("3")
			),
		),
		$("<form>").append(
			$("<label>").prop("for","ab-freq-min").html("Bump Frequency: "),
			$("<input>").prop("id","ab-freq-min").prop("type","text").addClass("qs-form").change(function() {
				  socket.emit("setBumpFreq", {min: parseInt($("#ab-freq-min").val()), max: parseInt($("#ab-freq-max").val())});
			}),
			$("<input>").prop("id","ab-freq-max").prop("type","text").addClass("qs-form").change(function() {
				  socket.emit("setBumpFreq", {min: parseInt($("#ab-freq-min").val()), max: parseInt($("#ab-freq-max").val())});
			}),
		),
		$("<form>").append(
			$("<label>").prop("for","ab-dur-min").html("Duration Minimum (seconds): "),
			$("<input>").prop("id","ab-dur-min").prop("type","text").addClass("qs-form").change(function() {
				  socket.emit("setMinBump",  parseInt($("#ab-dur-min").val()));
			}).keydown(function(ev){return !(ev.keyCode === 13)})
		),
		$("<form>").append(
			$("<label>").prop("for","ab-bsel").html("Bump Selection Method: "),
			$("<select>").prop("id","ab-bsel").prop("type","text").addClass("qs-form").change(function() {
				  socket.emit("setSelect", {bump: parseInt($("#ab-bsel").val()), list: parseInt($("#ab-lsel").val())});
			}).append(
				$("<option>").val(0).html("Last Half Random"),
				$("<option>").val(1).html("Queue Random"),
				$("<option>").val(2).html("Round Robin")
			),
		),
		$("<form>").append(
			$("<label>").prop("for","ab-lsel").html("List Selection Method: "),
			$("<select>").prop("id","ab-lsel").prop("type","text").addClass("qs-form").change(function() {
				  socket.emit("setSelect", {bump: parseInt($("#ab-bsel").val()), list: parseInt($("#ab-lsel").val())});
			}).append(
				$("<option>").val(0).html("Random List"),
				$("<option>").val(1).html("Smash List"),
			),
		),
		/*$("<form>").append(
			$("<label>").prop("for","qs-theme").html("Bump Selection: "),
				$("<select>").prop("id","qs-theme").addClass("qs-form").change(function() {
    				USEROPTS.theme = $("#qs-theme").val();
				processOpts();
			}),
		),*/
		$("<h4>").html("Bump Lists").addClass("ab-bumplist-lbl"),
		laddbtn.clone(true),
		$("<br>"),
		$("<span>").prop("id","ab-activebumplists-exp").addClass("qsbtn glyphicon  glyphicon-chevron-down pointer").click(function(){
			if($(".ab-activebumplists-div").is(":visible")){
				$(".ab-activebumplists-div").hide("blind"),
				$(this).attr("style", "rotate: 270deg;");
			}else{
				$(".ab-activebumplists-div").show("blind"),
				$(this).attr("style", "rotate: 0;");
			}
		}),
		$("<h5>").addClass("ab-activebumplists-lbl ab-bumplists-ltype").html("Active Lists (" + CHANNEL.bumpdata.active.length + ")").click(function(){$("#ab-activebumplists-exp").click()}),
		$("<div>").addClass("ab-activebumplists-div").append(
			this.showLists(alists),
		),
		$("<br>"),
		$("<span>").prop("id","ab-allbumplists-exp").addClass("qsbtn glyphicon  glyphicon-chevron-down pointer").click(function(){
			if($(".ab-allbumplists-div").is(":visible")){
				$(".ab-allbumplists-div").hide("blind"),
				$(this).attr("style", "rotate: 270deg;");
			}else{
				$(".ab-allbumplists-div").show("blind"),
				$(this).attr("style", "rotate: 0;");
			}
		}),
		$("<h5>").addClass("ab-allbumplists-lbl ab-bumplists-ltype").html("All Lists (" + CHANNEL.bumpdata.lists.length + ")").click(function(){$("#ab-allbumplists-exp").click()}),
		$("<br>"),
		$("<div>").addClass("ab-allbumplists-div").append(
			this.showLists(),
		),
		$("<span>").prop("id","ab-bumphist-exp").addClass("qsbtn glyphicon  glyphicon-chevron-down pointer").click(function(){
			if($("#ab-bumphist-div").is(":visible")){
				$("#ab-bumphist-div").hide("blind"),
				$(this).attr("style", "rotate: 270deg;");
			}else{
				$("#ab-bumphist-div").show("blind"),
				$(this).attr("style", "rotate: 0;");
			}
		}),
		$("<h5>").html("Bump History (" + this.getHist().length + ")").attr("style", "display: inline").addClass("ab-bumphist-lbl").click(function(){$("#ab-bumphist-exp").click()}),
		$("<div>").prop("id", "ab-bumphist-div").append(this.showBumps(this.getHist())),
		)
	);
	this.loadSettings();
}

fpbump.loadSettings = function(){
	if(CHANNEL.bumpdata.agro == null || CHANNEL.bumpdata.freq == null){
		console.error("null autobump settings, re-fetching from server");
		socket.emit("getBumplists");
		return;
	}
	$("#ab-agro")[0].value = CHANNEL.bumpdata.agro;
	$("#ab-freq-min").val(CHANNEL.bumpdata.freq[0]);
	$("#ab-freq-max").val(CHANNEL.bumpdata.freq[1]);
	$("#ab-dur-min").val(CHANNEL.bumpdata.minBump);
	if(CHANNEL.bumpdata.bsort === "queueRandom"){
		$("#ab-bsel")[0].value = 1;
	}else if(CHANNEL.bumpdata.bsort === "roundRobin"){
		$("#ab-bsel")[0].value = 2;
	}else{
		$("#ab-bsel")[0].value = 0;
	}
	$("#ab-lsel")[0].value = CHANNEL.bumpdata.lsort === "smashList" ? 1 : 0;
	CHANNEL.bumpdata.lists.forEach(function(blist){
		$("#ab-newbump-list").append($("<option>").val(blist.lowername).html(blist.name));
	});
}

fpbump.reloadPanel = function(){
	var activec = [];
	var allc = [];
	var alists = [];

	this.loadSettings();

	CHANNEL.bumpdata.active.forEach(function(bname){
		CHANNEL.bumpdata.lists.forEach(function(list){
			if(list.lowername === bname)
				alists.push(list);
		});
	});

	$(".ab-activebumplists-div").children().each(function(i,item){
		if($(item.children[1]).attr("style") == "rotate: 0;"){
			var tar = [item.id.replace("ab-bumplist-",'') ,$($(item).children()[6]).scrollTop()] 
			activec.push(tar);
		}
	});

	$(".ab-allbumplists-div").children().each(function(i,item){
		if($(item.children[1]).attr("style") == "rotate: 0;"){
			var tar = [item.id.replace("ab-bumplist-",'') ,$($(item).children()[6]).scrollTop()] 
			allc.push(tar);
		}
	});

	$(".ab-activebumplists-lbl").html("Active Lists (" + CHANNEL.bumpdata.active.length + ")");
	$(".ab-allbumplists-lbl").html("All Lists (" + CHANNEL.bumpdata.lists.length + ")");
	$(".ab-bumphist-lbl").html("Bump History (" + this.getHist().length + ")");

	$(".ab-activebumplists-div").html(this.showLists(alists, activec));
	$(".ab-allbumplists-div").html(this.showLists(null, allc));
	$("#ab-bumphist-div").html(this.showBumps(this.getHist()));

	$(".ab-bumplist-bumps").each(function(i,item){
	  if(item.scrollb != null){
	    item.scrollb();
	  }
	});

}

fpbump.getHist = function(){
	var fHist = [];
	CHANNEL.bumpdata.history.forEach(function(bdata){
		CHANNEL.bumpdata.lists.forEach(function(list){
			if(list.lowername === bdata[0]){
				fHist.push(list.bumps[bdata[1]]);
			}
		});
	});
	return fHist;
}

fpbump.showLists = function(lists, exp){
	var lDivs = [];
	var _this = this;
	if(lists == null){
		lists = CHANNEL.bumpdata.lists;
	}

	function badd(list, ob){
		return [$("<br>"),
			$("<form>").addClass("ab-newbump-form").append(
			$("<input>").prop("id","ab-newbump-url").prop("type","text").addClass("qs-form").attr("placeholder","URL"),
			$("<input>").prop("id","ab-newbump-title").prop("type","text").addClass("qs-form").attr("placeholder","Title"),
			$("<input>").prop("id","ab-newbump-user").prop("type","text").addClass("qs-form").attr("placeholder","Bump Creator"),
			$("<br>"),
			$("<label>").prop("for","ab-newbump-rtoke").html("Toke Bump: "),
			$("<input>").prop("id","ab-newbump-rtoke").prop("type","checkbox").addClass("qs-form"),
			$("<label>").prop("for","ab-newbump-noauto").html("Manual Only: "),
			$("<input>").prop("id","ab-newbump-noauto").prop("type","checkbox").addClass("qs-form"),
			$("<span>").addClass("qsbtn glyphicon glyphicon-plus-sign pointer").attr("title","Add Bump").attr("id","ab-newlist-newbtn").click(function(){
				if($("#ab-newbump-url").val() !== ""){
					var mdata = parseMediaLink($("#ab-newbump-url").val());

					var bumpObj = {
						id: mdata.id,
						type: mdata.type,
						name: $("#ab-newbump-title").val(),
						user: $("#ab-newbump-user").val(),
						rtoke: $("#ab-newbump-rtoke").prop("checked"),
						bumplist: list,
						noauto: $("#ab-newbump-noauto").prop("checked")
					}

					socket.emit("newBump", bumpObj);
					$("#ab-newbump-url").val("");
					$("#ab-newbump-title").val("");
					$("#ab-newbump-user").val("");
					$("#ab-newbump-cancel").click();
				}
			}),
		).clone(true),
		$("<span>").prop("id","ab-newbump-cancel").addClass("qsbtn glyphicon glyphicon-ban-circle pointer").click(function(){
			$(this).prev().prev().remove();//gotta take out that br...
			$(this).prev().remove();
			$(this).replaceWith(ob);
		})];
	}

	lists.forEach(function(list){
		var blist = $("<div>").addClass("ab-bumplist-bumps").append(_this.showBumps(list.bumps, true));
		var active = CHANNEL.bumpdata.active.includes(list.lowername);
		var ex = false;
		
		if(exp != null){
			exp.forEach(function(item){
				if(item[0] === list.lowername){
					ex = item;
				}
			});
		}

		var bcount = 0;
		list.bumps.forEach(function(item){
			bcount += (item == null ? 0 : 1);
		});
		lDivs.push(
			$("<div>").addClass("ab-bumplist-list").attr("id", "ab-bumplist-" + list.lowername).append(
				$("<span>").addClass("ab-bumplist-setactive" + (active ? "-active " : " ") + "qsbtn glyphicon glyphicon-ok pointer").attr("title",(active ? "Set List Inactive" : "Set List Active")).click(function(){
				socket.emit((active ? "remove" : "set") + "Active", list.lowername);
				}),
				$("<span>").prop("id","ab-bumplist-bumps-exp").addClass("qsbtn glyphicon glyphicon-chevron-down pointer").attr("style",(ex ? "rotate: 0;" : "rotate: 270deg")).click(function(){
					if(blist.is(":visible")){
						blist.hide("blind"),
						$(this).attr("style", "rotate: 270deg;");
					}else{
						blist.show("blind"),
						$(this).attr("style", "rotate: 0;");
					}
				}),
				$("<h6>").html(list.name + " (" + bcount + ")").addClass("ab-bumplist-listname").click(function(){$(this).prev().click()}),
				$("<span>").prop("id","ab-bumplist-rename").addClass("qsbtn glyphicon  glyphicon-pencil pointer").click(function(){
					var link = $(this).prev().clone(true); 
					var ebtn = $(this).clone(true);

					$(this).prev().replaceWith($("<form>").append(
						$("<input>").prop("type","text").attr("id", "ab-bumparray-reuserf").addClass("qs-form").attr("placeholder", list.name).keydown(function(ev) {
							// Enter/return
							if(ev.keyCode == 13) {
								socket.emit("renameBumplist", {oldname: list.lowername, newname: this.value});
								$(this).parent().next().replaceWith(ebtn);
								$(this).parent().replaceWith(link);
							}
							
						})
					).attr("style", "display: inline"));

					$(this).replaceWith(
						$("<span>").prop("id","ab-bumparray-reuser").addClass("ab-bumparray-edit qsbtn glyphicon glyphicon-ban-circle pointer").click(function(){
							$(this).prev().replaceWith(link);
							$(this).replaceWith(ebtn);
						})
					);
				}),
				$("<span>").addClass("qsbtn glyphicon glyphicon-plus-sign pointer").attr("title","Add Bump").attr("id","ab-newlist-newbtn").click(function(){
					var abtn = $(this).clone(true);
					$(this).replaceWith(badd(list.lowername, abtn));
				}),
				$("<span>").addClass("ab-bumplist-delete qsbtn glyphicon pointer glyphicon-trash").attr("title","Delete List").click(function(){
					if(window.confirm("Fuck me, you sure you wanna do that? You're about to nuke " + list.name + " off the face of the planet.")){
						socket.emit("delBumplist",list.lowername);
					}
				}),
				blist,
			),
		);
		if(!ex){
			blist[0].scrollb = null;
			blist.hide();
		}else{
			blist[0].scrollb = function (){//annoyingly this shit cant just be called since this hasnt been placed yet, will be called be refresh function :P
				blist.scrollTop(ex[1]);
			};
		}
	});

	return lDivs;
}

fpbump.showBumps = function(bumps, controls){
	var bDivs = [];	
	var bSpan = []
	bumps.forEach(function(bump){
		if(bump != null){
			var bCreator = $("<span>").append(
				$("<p>Creator: " + (bump.user == null ? "N/A" : bump.user) + "</p>").addClass("ab-bumparray-creator"),
				(controls ? $("<span>").prop("id","ab-bumparray-reuser").addClass("ab-bumparray-edit qsbtn glyphicon  glyphicon-pencil pointer").click(function(){
					var link = $(this).prev().clone(true); 
					var ebtn = $(this).clone(true);

					$(this).prev().replaceWith($("<form>").append(
						$("<label>").prop("for", "ab-bumparray-reuserf").attr("id", "ab-bumparray-reuserfl").html("Creator: "),//alphanum sort label
						$("<input>").prop("type","text").attr("id", "ab-bumparray-reuserf").addClass("qs-form").attr("placeholder", (bump.user == null ? "N/A" : bump.user)).keydown(function(ev) {
							// Enter/return
							if(ev.keyCode == 13) {
								socket.emit("changeCreator", {bl: bump.listname, id: bump.id, name: this.value});
								$(this).parent().next().replaceWith(ebtn);
								$(this).parent().replaceWith(link);
							}
							
						})
					).attr("style", "display: inline"));

					$(this).replaceWith(
						$("<span>").prop("id","ab-bumparray-reuser").addClass("ab-bumparray-edit qsbtn glyphicon glyphicon-ban-circle pointer").click(function(){
							$(this).prev().replaceWith(link);
							$(this).replaceWith(ebtn);
						})
					);
				}):undefined),
			);

			var bSpan = $("<span>").addClass("ab-bumparray-span").append(
				$("<span>").append(
					$('<a href="' + formatURL(bump.media) + '">' + bump.name + "</a>"), 
					(controls ? $("<span>").prop("id","ab-bumparray-rename").addClass("ab-bumparray-edit qsbtn glyphicon  glyphicon-pencil pointer").click(function(){
						var link = $(this).prev().clone(true); 
						var ebtn = $(this).clone(true);

						$(this).prev().replaceWith($("<form>").append(
							$("<input>").prop("type","text").addClass("qs-form").attr("placeholder", bump.name).keydown(function(ev) {
								// Enter/return
								if(ev.keyCode == 13) {
									socket.emit("renameBump", {bl: bump.listname, id: bump.id, name: this.value});
									$(this).parent().next().replaceWith(ebtn);
									$(this).parent().replaceWith(link);
								}
								
							})
						).attr("style", "display: inline"));

						$(this).replaceWith(
							$("<span>").prop("id","ab-bumparray-rename").addClass("ab-bumparray-edit qsbtn glyphicon glyphicon-ban-circle pointer").click(function(){
								$(this).prev().replaceWith(link);
								$(this).replaceWith(ebtn);
							})
						);
					}):undefined),
				),
				$("<p>" + bump.media.title + "</p>"),

				(controls ? [
					$('<p>Manual Only: <a class="pointer">' + (bump.noauto ? "Y" : "N") + "</a></p>").click(function(){socket.emit("toggleNoauto", {bl: bump.listname, id: bump.id})}),
					$('<p>Toke Bump: <a class="pointer">' + (bump.rtoke ? "Y" : "N") + "</a></p>").click(function(){socket.emit("toggleRtoke", {bl: bump.listname, id: bump.id})}),
				] : [
					$("<p>Manual Only: " + (bump.noauto ? "Y" : "N") + "</p>"),
					$("<p>Toke Bump: " + (bump.rtoke ? "Y" : "N") + "</p>"),
				]),

				$("<p>Dur: " + bump.media.duration + "</p>"),	
			);


			var bDiv = $("<div>").addClass("ab-bumparray-bump").attr("id", "ab-bumparray-" + bump.listname + "-" + bump.id).append(bSpan);

			if(controls){
				bDiv.append(
					$("<span>").append(
						$("<button/>").addClass("btn btn-xs btn-default abbtn-next").html("<span class='glyphicon glyphicon-share-alt'></span>Queue Next").click(function() {
							socket.emit("queueBump",{bl: bump.listname, id: bump.id});
						}),
						$("<button/>").addClass("btn btn-xs btn-default abbtn-next").html("<span class='glyphicon glyphicon-trash'></span>Delete").click(function() {
							socket.emit("deleteBump",{bl: bump.listname, id: bump.id});
						})
					),
					$("<span>").addClass("ab-bumparray-cspan").append(
						bCreator,
					)
				);
			}else{
				bDiv.append(bCreator);
			}

			bDivs.push(bDiv);
		}
	});
	return bDivs;
}

fpbump.size = function(){
	$("#abumpdiv").outerHeight($("#fpcontdiv").outerHeight() - $("#mod-nested").outerHeight());
}

//---Tokebot---
var fptoke = new fpmenu("Tokebot");//create new panel fpmod

fptoke.elm = [//fpmod element array
]

fptoke.ocall = function(){
	$("#fpcontdiv").append(
		$("<h4>").html("Tokebot Control"),
		$("<form>").addClass("qt").append( 
			$("<button/>").addClass("btn btn-primary btn-ln").attr("id","tb-resetcd").text("Reset Toke Cooldown").prop("type","button").click(function(){
				chatsmack("!resettoke");
			}),
		),
	);

	if(window.CLIENT.rank <= 256){
		$("#fpcontdiv").append(	
			$("<form>").addClass("qt").append( 
				$("<button/>").addClass("btn btn-primary btn-ln").attr("id","tb-resetcd").text("Reload Tokes File").prop("type","button").click(function(){
					chatsmack("!reloadtokes");
				}),
			),
			$("<form>").addClass("qt").append( 
				$("<button/>").addClass("btn btn-primary btn-ln").attr("id","tb-whisperbtn").text("Toke Whisper: ").prop("type","button").click(function(){
					chatsmack("!tokewhisper " + $("#tb-whisper").val());
				}),
				$("<input>").prop("id","tb-whisper").prop("type","text").addClass("qs-form").attr("placeholder","Whisper text.").keydown(function(ev){
					if(ev.keyCode==13){
						chatsmack("!tokewhisper " + $("#tb-whisper").val());
						return false;
					}
				})
			),
			$("<form>").addClass("qt").append( 
				$("<button/>").addClass("btn btn-primary btn-ln").attr("id","tb-saybtn").text("Toke Say: ").prop("type","button").click(function(){
					chatsmack("!tokesay " + $("#tb-say").val());
				}),
				$("<input>").prop("id","tb-say").prop("type","text").addClass("qs-form").attr("placeholder","Chat text.").keydown(function(ev){
					if(ev.keyCode==13){
						chatsmack("!tokesay " + $("#tb-say").val());
						return false;
					}
				})
			),
			$("<form>").addClass("qt").append( 
				$("<button/>").addClass("btn btn-primary btn-ln").attr("id","tb-yellbtn").text("Toke Announce: ").prop("type","button").click(function(){
					chatsmack("!tokeyell " + $("#tb-yell").val());
				}),
				$("<input>").prop("id","tb-yell").prop("type","text").addClass("qs-form").attr("placeholder","Announce text.").keydown(function(ev){
					if(ev.keyCode==13){
						chatsmack("!tokeyell " + $("#tb-yell").val());
						return false;
					}
				})
			)
		);
	}

	modNested.popMenu();
}

//---Export Playlist---
var fpexport = new fpmenu("Export Queue");

fpexport.ocall = function(data){
        var list = [];
        for(var i = 0; i < data.length; i++) {
            var entry = [data[i].media.title, formatURL(data[i].media)];
            list.push(entry);
        }

	$("#fpcontdiv").append(
		$("<h4>").attr("id","ex-lbl").html("Export Queue"),
		$("<form>").addClass("qt").attr("id","ex-form").append( 
			$("<button/>").addClass("btn btn-primary btn-ln").attr("id","ex-hmn-btn").text("Export as Human Readable").prop("type","button").click(function(){
				$("#ex-txt-area").val("");
				list.forEach(function(item, i){
					$("#ex-txt-area").val($("#ex-txt-area").val() + i + ': "' + item[0] + '" - [' + item[1] + "]\n");
				});
			}),

			$("<button/>").addClass("btn btn-primary btn-ln").attr("id","ex-json-btn").text("Export as JSON").prop("type","button").click(function(){
				$("#ex-txt-area").val(JSON.stringify(list));
			}),
			$("<button/>").addClass("btn btn-primary btn-ln").attr("id","ex-csv-btn").text("Export as CSV").prop("type","button").click(function(){
				$("#ex-txt-area").val("");
				list.forEach(function(item){
					$("#ex-txt-area").val($("#ex-txt-area").val() + item[0] + "," + item[1] + "\n");
				});
			}),
			$("<button/>").addClass("btn btn-primary btn-ln").attr("id","ex-db-btn").text("Export as DB Format").prop("type","button").click(function(){

				var out = [];
				list.forEach(function(item, i){
					re1=new RegExp('\\\\', 'g');
					re2=new RegExp('\'', 'g');

					title=item[0].replace(re1, '\\\\').replace(re2, '\\\'');

					out.push('[\''+item[1]+'\', \''+title+'\'],');
				});
				$("#ex-txt-area").val(out.join('\n'));
			}),
		),
		$("<textarea>").attr("id","ex-txt-area").addClass("form-control").attr("style", "font-family: mono; width: 100%;"),

	);
	$("#ex-hmn-btn").click();
	modNested.popMenu();
}

fpexport.size = function(){
	$("#ex-txt-area").outerHeight($("#fpcontdiv").outerHeight() - ($("#mod-nested").outerHeight() + $("#ex-form").outerHeight(true) + $("#ex-lbl").outerHeight(true)));
}

//---Mod Panel Nested Menu---
modNested = new nmenu(null,fpmod,[fpplaylist,fpbump,fptoke]);
