﻿/*
	NLo	by Joseph Beeson -- email : joseph beeson at 'g' mail daught com
	
	This script allows for persistent, embeddable playlists on your website. Built using Niftyplayer and jQuery
	
	Version 1.0.14
		Forms now captured.  Forms submitted to out of scope URLs now opened in new browser tab.
		
	Version 1.0.13
		switched to using escape/unescape functions instead of base64 and LZW for better URL readability
		
	Version 1.0.12
		added appendTo beginning/end feature in configuration
		fixed varius issues
		
	version 1.0.11
		moved GetElementsByClass to DOMshortcuts to avoid namespace conflicts
		added jQuery.noConflict() to avoid mootools conflicts
	
	Version 1.0.10
		new feature stripWWW to remove the www subdomain, fixes a bug where external links with www can cause the user to be redirected to the main page rather than the page requested.
	
	Version 1.0.9
		IE6 fails gracefully
		JS now saved in UTF8 encoding
	
	Version 1.0.8
		fixed CSS glitches
		updated getplIUDClass() to be more consistent
		found whacky bug -- if the first line of iFrame_default.txt is our id, it gets ignored by NLo.jss .... no clue why.  Fix: card coded iframe.php to make id of default playlist be 'default'
	
	Version 1.0.7
		code cleanup
		ditched php-generated args introduced in 1.0.4, now pure javascript config
		new config file NLo_conf.js
		New DOMshortcuts version
		jquery 1.4.1
	
	Version 1.0.6
		playerbox now springs open and closed on hover, rather than fading in and out
		playerbox springs open on playlist append
		hitting spacebar toggles playback (not working in IE)
		
	Version 1.0.5
		stylesheets used for hover/unhover events for the player
		iforceFrame.js and NLo.js now consolidated in single file
		redirect now triggered on page load, user does not see page flicker beforehand
		
	Version 1.0.4
		forceiFrame can now be defined in the <script> tag			
						
*/ 


var NLo = {
	nowPlaying			: 0,
	n					: 0,
	textInputFocus		: 0,
	hash : parent.location.hash,

	next : function (obj){
		var n = NLo.nowPlaying.parentNode.nextSibling;
		if(obj) {
			n = obj;
		}
		if(n) {
			if(n.tagName == "SPAN") {
				NLo.skipTo(n.firstChild);
			} else {
				// next obj is a title, skip to next obj
				NLo.next(n.nextSibling)
			}
		} else {
			// no next obj, go to start
			var pl = d.ge("NLoPlaylist");
			var lis = pl.getElementsByTagName('span');
			NLo.next(lis[0]);
		}
	},
	
	prev : function(obj){
		var n = NLo.nowPlaying.parentNode.previousSibling;
		if(obj) {
			n = obj;
		}
		//alert(n.tagName);
		if(n.tagName == "SPAN"){
			NLo.skipTo(n.firstChild);
		} else if (n.previousSibling){
			// prev obj is a title, skip to prev obj again
			NLo.prev(n.previousSibling);
		} else {
			var pl = d.ge("NLoPlaylist");
			var lis = pl.getElementsByTagName('span');
			NLo.prev(lis[lis.length-1]);
		}
	},
	
	playToggle : function() {
		if(NLo.nowPlaying == 0) {
			NLo.skipToFirst();
			NLo.n.play();	
		} else {
			var i = parent.frames['mainIFrame'].document;
			var s = NLo.n.getPlayingState();
			if(s == "playing") {
				NLo.n.pause();
			} else {
				NLo.n.play();
			}
		}
		NLo.setPlayIcon();
	},
		
	setPlayIcon : function() {
		var i = parent.frames['mainIFrame'].document;
		var s = NLo.n.getPlayingState();
		try{
			var newId = NLo.nowPlaying.parentNode.id;
			
			if(s == "playing") {
				jQuery("#NLoplayToggle").css("background-image", "url(NLo/bigplay.png)");
				d.ge(newId).firstChild.className = "NLoNowPlaying";
				try{
					i.getElementById(newId).firstChild.className = "NLoNowPlaying";
				} catch(err) {};
			
			} else {
				jQuery("#NLoplayToggle").css("background-image", "url(NLo/bigpause.png)");
				d.ge(newId).firstChild.className = "NLoNowPaused";
				try{
					i.getElementById(newId).firstChild.className = "NLoNowPaused";
				} catch(err) {};
			}
		}catch(err){}
	},
	
	skipTo : function(newObj, play){
		var firstSong = 0;
		NLo.n = niftyplayer("NLoPlayer");
		try{
			NLo.n.registerEvent("onSongOver", "NLo.next()");
		}catch(err){}
		var i = parent.frames['mainIFrame'].document;
		
		// this can be called from the child or parent, append playlist to parent list if it doesn't already exist
		var plUIDClass = newObj.parentNode.className;
		var newId = newObj.parentNode.id;
		var pl = d.ge(plUIDClass);
		try{
			if(pl.id){}
		}catch(err){
			// show the playerbox
			//jQuery('#'+NLo_conf.playerBoxID).fadeTo(1, 1);
			
			// pop the playerbox open
			if(NLo_conf.playerActionOnAppend == 'bounce') {
				NLo_conf.playerBoxBounce();
			} else {
				NLo_conf.playerBoxOpen();
				window.setTimeout('NLo_conf.playerBoxClose()', 900);
			}
			NLo.playBoxOpenOnAppend = 1;
			
			// append new songs
			var pl = d.ge("NLoPlaylist");
			var els = d.gebc(plUIDClass, i);
			
			var f = els.shift();
			var n = f.cloneNode(true);	
			// add to DOM
			if(NLo_conf.appendTo == 'beginning'){
				if(firstSong == 0) {
					firstSong = pl.firstChild;
				}
				d.acb(firstSong,n);
			} else {
				d.ac(pl, n);
			}
			
			//redefine the onclick event handlers for the delete button
			jQuery(".NLodelPlaylist").click(function(){
				NLo.delPlaylist(this.parentNode.parentNode.className)
			});
			
			//redefine the onclick event handlers for the infolinks
			jQuery(".infoLink").click(function(){
				alert(this.href);
				//window.parent.frames['mainIFrame'].document.location.replace(this.href);
				return false;
			});
			
			// redefine the onclick event handlers for the playlist items
			for(var i in els) {
				var n = els[i].cloneNode(true);
				n.lastChild.onclick = function(){
					NLo.skipTo(this,2); return false;
				};
				if(NLo_conf.appendTo == 'beginning'){
					d.acb(firstSong,n);
				} else {
					d.ac(pl, n);
				}
			}			
		}
		newObj.blur();
		// redefine newObj to always refer to object in parent list, not child list
		newObj = d.ge(newId).firstChild;

		if(play == 2 & (newObj == NLo.nowPlaying)){
			// play = 2 means this event was triggered by the user
			NLo.playToggle();
			return;
		}
		
		var path = newObj.name;
		
		if(play == -1) {
			NLo.n.load(path);
		} else {
			NLo.n.loadAndPlay(path);
		}
		//remove play icon from previous song in parent and child
		jQuery('#mainIFrame').contents().find('.NLoNowPaused').addClass('NLoHasPlayed');
		jQuery('.NLoNowPaused').addClass('NLoHasPlayed');
		jQuery('#mainIFrame').contents().find('.NLoNowPlaying').addClass('NLoHasPlayed');
		jQuery('.NLoNowPlaying').addClass('NLoHasPlayed');
		jQuery('#mainIFrame').contents().find('.NLoNowPlaying').removeClass('NLoNowPlaying');
		jQuery('#mainIFrame').contents().find('.NLoNowPaused').removeClass('NLoNowPaused');
		jQuery('.NLoNowPlaying').removeClass('NLoNowPlaying');
		jQuery('.NLoNowPaused').removeClass('NLoNowPaused');

		//set play icon to new song in parent and child
		NLo.nowPlaying = newObj;
		NLo.setPlayIcon();
		d.ge("CurrentSongName").innerHTML = newObj.innerHTML;
	},
	
	skipToFirst : function() {
		//means this is the first playlist appended, queue first song
		
		var pl = d.ge("NLoPlaylist");
		var lis = pl.getElementsByTagName('span');
		NLo.skipTo(lis[0].firstChild, -1);
	},
	
	delPlaylist : function(classUID) {
		var i = parent.frames['mainIFrame'].document;

		jQuery("."+classUID).fadeOut(400, function(){
			jQuery("."+classUID).remove();
		});
		if(NLo.nowPlaying != 0) {
			var a = NLo.nowPlaying.parentNode;
			if(a.className == classUID){
				NLo.n.stop();
				NLo.nowPlaying = 0;
				d.ge("CurrentSongName").textContent = "";
				jQuery('#mainIFrame').contents().find('.NLoNowPaused').addClass('NLoHasPlayed');
				jQuery('.NLoNowPaused').addClass('NLoHasPlayed');
				jQuery('#mainIFrame').contents().find('.NLoNowPlaying').addClass('NLoHasPlayed');
				jQuery('.NLoNowPlaying').addClass('NLoHasPlayed');
				jQuery('#mainIFrame').contents().find('.NLoNowPlaying').removeClass('NLoNowPlaying');
				jQuery('#mainIFrame').contents().find('.NLoNowPaused').removeClass('NLoNowPaused');
				jQuery('.NLoNowPlaying').removeClass('NLoNowPlaying');
				jQuery('.NLoNowPaused').removeClass('NLoNowPaused');
			}
		}
		
		//jQuery('#NLoPlaylist').jScrollPane();

	},
	
	appendArray2DOMObj : function(appendArray) {
		//converts the appendArray object to a DOM object, returns a flat array containing the objects
		var re = new RegExp("title|showTitle|id|playOnAppend|delBtn");
		var out = new Array;
		var track = 1;
		var title = d.ce("div");
		var plId = "NLoList";
		var delBtn = d.ce("div");
		d.sa(delBtn, "class", "NLodelPlaylist");
		jQuery(delBtn).click(function(){
			NLo.delPlaylist(this.parentNode.parentNode.className)
		});

		var t = appendArray["title"];
		if(t === undefined) {
			t = 'Untitled Playlist';
			appendArray["title"] = t;
			appendArray["showTitle"] = false;
		}
		var plIUDClass = NLo.getplIUDClass(appendArray);
		d.sa(title, "id", plIUDClass);
		d.sa(title, "class", plIUDClass);
		
		if(appendArray["showTitle"] == 0 || appendArray["showTitle"] == false || !t) {
			d.sa(title, "style", "display:none");
		}
		
		var titleDiv = d.ce("div");
		d.sa(titleDiv, "class", "NLoListTitle");					
		if(appendArray["delBtn"] != 0) {
			d.ac(titleDiv, delBtn);
			d.ac(delBtn,d.ct('x'));
			delBtn.onclick = function(){NLo.delPlaylist(this.parentNode.parentNode.className)};
		}
		var titleLink = d.ce('a');
		titleLink.href="#";
		d.ac(titleLink,d.ct(t));
		d.ac(titleDiv,titleLink);
		
		//add titlediv to li
		d.ac(title, titleDiv);
		out.push(title);
		
		for(var t in appendArray){
			var s = ""+appendArray[t];
			if(t.match(re)) {
			} else {
				//create link
				var a = d.ce("a");
				d.sa(a, "name", s);
				d.sa(a, "href", "#");
				a.onclick = function(){
					parent.NLo.skipTo(this,2); return false;
				};
				d.ac(a,d.ct(t));

				// create li
				var li = d.ce("span");
				d.sa(li, 'class', plIUDClass);
				d.sa(li, 'id', plIUDClass+'_'+track);
				track++;
				//append link to li
				d.ac(li,a);
				
				//append li to out
				out.push(li);
			}
		}
		return out;
	},
	
	getplIUDClass : function (appendArray) {
		var re = new RegExp("[ \.]", 'g');
		var id = appendArray["id"];
		if(id === undefined) {
			id =  Math.floor(Math.random()*10000);
			appendArray["id"] = id;
		}
		
		var t = 'NLoPlaylistId'+'_'+appendArray["id"];
		return t.replace(re, '');
	},
	
	cleanAppendArray : function(appendArray) {
		var out = new Object();
		for(var k in appendArray) {
			var v2 = appendArray[k].replace(/^\s+/g,'').replace(/\s+$/g,'');
			var k2 = k.replace(/^\s+/g,'').replace(/\s+$/g,'');
			out[k2] = v2;
		}
		return out;	
	},
	
	printChildList : function(appendArray, myid) {
		var i = parent.frames['mainIFrame'].document;
		var appendArray2 = NLo.cleanAppendArray(appendArray);
		var newObj = NLo.appendArray2DOMObj(appendArray2);
		try {
			var target = i.getElementById(myid);
			var title = newObj.shift();
			d.ac(target, title);
			for(var a in newObj) {
				var li = newObj[a];
				d.ac(target, li);
			};
			target.className = 'NLoPlaylist';
			
			// if the playlist was loaded but is already playing in parent, set its icon to play		
			NLo.setPlayIcon();
		} catch(err){}
	},
	
	appendToParentList : function(appendArray) {
		var plIUDClass = NLo.getplIUDClass(appendArray);
		var checkDupe = d.ge(plIUDClass);
		try{
			if(checkDupe.id) {
				return;
			};
		} catch(err){}
		var newObj = NLo.appendArray2DOMObj(appendArray);
		var pl = d.ge("NLoPlaylist");
		var firstTrackAppended = 0;
	
		d.ac(pl, newObj.shift());
		for(var a in newObj) {
			var li = newObj[a];
			if(firstTrackAppended == 0) {
				firstTrackAppended = li.firstChild;
			}	
			d.ac(pl, li);
		}

	},
	
	getSpacebar: function(keyCode){
		//alert('getSpacebar');
		if(keyCode == 32 & NLo.textInputFocus == 0) {
			NLo.playToggle();
			return false;
		}
	},
   
	IEgetSpacebar: function(){
		//alert('getSpacebar');
		NLo.getSpacebar(event.keyCode);
	},
	
	
	/* ============ this part of NLo forces the website into an iframe ========== */

	
	updateTitleFavicon : function() {
		// as name implies, sends child doc title and favicon to parent
		parent.document.title = document.title;
		var a = document.getElementsByTagName('link');
		try{
			jQuery('.parentfavicon', parent.document).remove();
		} catch(err){}
		
		for(var b in a) {
			var t = a[b].type;
			if(t == 'image/x-icon') {
				var link = parent.document.createElement('link');
				link.type = 'image/x-icon';
				link.rel = 'shortcut icon';
				link.className = 'parentfavicon';
				link.href = a[b].href;
				parent.document.getElementsByTagName('head')[0].appendChild(link);
			}
		}
	},

	updateChildURL : function() {
		var myurl = location.hash;
		if(myurl == "") {
			myurl = NLo_conf.scope+NLo_conf.defaultPage;
		} else {
			myurl = NLo.decodeUrl(myurl);
		}
		
		window.parent.frames['mainIFrame'].document.location.replace(myurl);
		
	},

	captureIframeLinks : function() {
		//alert('captureIframeLinks');
		var links = document.getElementsByTagName('a');
		for(i = 0; i < links.length; i++) {
			if(links[i].onclick){
				continue; //don't clobber existing onclicks
			}
			if(links[i].target == "") {
				links[i].onclick = function(){parent.NLo.updateParentURL(this.href); return false;}
			}
		}
		var forms = document.getElementsByTagName('form');
		for(i = 0; i < forms.length; i++) {
			if(!NLo.checkIfInScope(forms[i].action)) {
				d.sa(forms[i], 'target', '_new');
			}
		}

	},
	
	pollHash : function () {
	// shitty hack to update child iframe when back / forward buttons are pressed
		if(NLo.hash != location.hash) {
			NLo.hash = location.hash;
			NLo.updateChildURL();
		}
	},

	updateParentURL : function(childUrl) {
		//alert('updateParentURL');
		var res = NLo.checkIfInScope(childUrl);
		if(res){
			//alert('in scope');
			var encurl = NLo.encodeUrl(res);
			var url = ""+window.location;
			var baseurl = url.split('#', 1);
			window.location = baseurl + '#' + encurl;
		 } else {
			//alert('out of scope');
			window.location = childUrl;
		}

	},
	
	checkIfInScope : function(url) {
		if(url == NLo_conf.scope) {
			return true;
		}
		var ScopeRe = new RegExp('^'+NLo_conf.scope);
		var m = url.match(ScopeRe);
		if(m == null) {
			//not in domain
			return false;
		}
		//in domain, return relative path
		return url.substr(NLo_conf.scope.length);

	},
	
	encodeUrl : function(s) {
		if(s.length > 0){
			return escape(s);
		} else {
			return '';
		}
	},
	
	decodeUrl : function(s){
		var u = unescape(s);
		return u.substr(1);
	}
	
}

// Strip the www subdomain if set
if(NLo_conf.stripWWW) {
	var www = window.location.hostname.substring(0,4);
	if(www == 'www.'){
		// remove the friggin www
		var remLen = window.location.protocol+"//www.";
		var newurl = window.location.protocol+"//"+window.location.href.substring(remLen.length);
		window.location.replace(newurl);
		NLo_conf.me = '0';
	}
}


// IE-specific junk
if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)){
	var ieversion=new Number(RegExp.$1);
	if(ieversion < 7) {
	// No IE6
		NLo_conf.me = 'ie6';
		if(NLo.hash.length > 0) {
			window.location = NLo.decodeUrl(NLo.hash)
		}
		NLo.printChildList = function(appendArray, myid) {
			var appendArray2 = NLo.cleanAppendArray(appendArray);
			var newObj = NLo.appendArray2DOMObj(appendArray2);

				var target = d.ge(myid);
				var title = newObj.shift();
				//d.ac(target, title);
				for(var a in newObj) {
					try {
					var li = newObj[a];
					li.onclick = function(){alert(NLo_conf.IE6failMsg)};
					d.ac(target, li);
					} catch(err){}
				};
				target.className = 'NLoPlaylist';
		}
		
	}
	// Suppress all IE errors
	function STFUie() {return true;}
	window.onerror=STFUie;
}

if(NLo_conf.me == 'child') {
	// Embed the page as a child iFrame in the defined parent document
	var id = 0;
	try {
		id = window.frameElement.id;
	} catch(err) { }
	if(id == 0){
		// we're not in an frame, embed self in iframe
		var myurl = ""+document.location;
		var relurl = NLo.checkIfInScope(myurl);
		var urlenc = NLo.encodeUrl(relurl);
		if(urlenc.length > 0) {
			urlenc = '#'+urlenc;
		}
		var dest = NLo_conf.scope+NLo_conf.iFrameFile+urlenc;
		window.location = dest;
	};

	jQuery(document).ready(function(){
	
		NLo.updateTitleFavicon();
		NLo.captureIframeLinks();

		// set up the event handlers for the spacebar
		document.onkeydown=function(event){return parent.NLo.getSpacebar(event.keyCode)};
		var inputs = document.getElementsByTagName('input');
		var newOnf = function(){parent.NLo.textInputFocus = 1; return true;};
		var newObl = function(){parent.NLo.textInputFocus = 0; return true;};
		for(var i in inputs) {
			if(inputs[i].type == 'text'){
				inputs[i].addEventListener('focus', newOnf, false);
				inputs[i].addEventListener('blur', newObl, false);
			}
		}
		var inputs = document.getElementsByTagName('textarea');
		for(var i in inputs) {		
			try{
				inputs[i].addEventListener('focus', newOnf, false);
				inputs[i].addEventListener('blur', newObl, false);
			}catch(err){}
		}
	});
}

if(NLo_conf.me == 'parent') {
	jQuery(document).ready(function() {
		
		if(NLo_conf.playerVisibleByDefault == 1) {
			window.setTimeout("NLo_conf.playerBoxSlideIn();", 3000);
		}
		
		NLo.updateChildURL();
		setInterval(NLo.pollHash, 400);

		document.onkeyup = NLo.IEgetSpacebar; // key catcher for IE
		document.onkeydown=function(event){return NLo.getSpacebar(event.keyCode)}; // key catcher for everyone else
		
		jQuery("#NLoplayToggle").click(function(){
			NLo.playToggle();
		})
		
		jQuery('#'+NLo_conf.playerBoxID).hover(function(){
		//mouseIn
			NLo_conf.playerBoxOpen();
		},function(){
		//mouseOut
			NLo_conf.playerBoxClose();
		});
			
	});
}