//
// BreakbitMusic.com player
//

// Reprogram so that 'lists' are pre-array'd by a container's playlist ID. Better playlist management.

function initBBPlayer(){
	
	var self = this;
	
	this.BBPplayer = '#player';
	this.BBPposition = '#playerBar #bar.play';
	this.BBPloading = '#playerBar #bar.load';
	this.BBPinfo = '#playerInfo';
	this.BBPtimeElapsed = '#playerText p.time_elapsed';
	this.BBPtimeSelect = '#playerText p.time_select';
	this.BBPtimeTotal = '#playerText p.time_total';
	
	this.body = 'body';
	this.jpC = '#playerCore';
	this.jpCC = '#playerCoreCont';
	this.jpFS = '#fullscreen';
	this.jpW = '#fwidth';
	this.jp = $(self.jpC).jPlayer({
			size: {width:"100%", height: "100%"},
			swfPath: "/",
			supplied: "mp3, m4v"
		});
	this.jpD = self.jp.data("jPlayer");
	this.jpO = '#player_overlay';
		
	var uA = navigator.userAgent;
	
	var isIE = uA.match(/msie/i);
	var isOpera = uA.match(/opera/i);
	var isFirefox = uA.match(/firefox/i);
	var isChrome = uA.match(/chrome/i);
	var isSafari = uA.match(/safari/i);	
	var isTouchDevice = (uA.match(/ipad|iphone/i));
	
	this.excludeClass = 'BBPx'; // CSS class for ignoring MP3 links
	this.fs = false;
	this.links = [];
	this._lcData = [];
	this.indexByURL = [];
	this.lastWPExec = new Date();
	this.dragPlayFrom = 0;
	
	this.css = {
		// CSS class names appended to link during various states
		sDefault: 'BBP_link', // default state
		sLoading: 'BBP_loading',
		sPlaying: 'BBP_playing',
		sPaused: 'BBP_paused'
	}
	
	_event = (function() {

		var old = (window.attachEvent && !window.addEventListener),
		_slice = Array.prototype.slice,
		evt = {
			add: (old?'attachEvent':'addEventListener'),
			remove: (old?'detachEvent':'removeEventListener')
		};

		function getArgs(oArgs) {
			var args = _slice.call(oArgs), len = args.length;
			if (old) {
				args[1] = 'on' + args[1]; // prefix
				if (len > 3) {
					args.pop(); // no capture
				}
			} else if (len === 3) {
				args.push(false);
			}
			return args;
		}

		function apply(args, sType) {
			var element = args.shift(),
			method = [evt[sType]];
			if (old) {
				element[method](args[0], args[1]);
			} else {
				element[method].apply(element, args);
			}
		}

		function add() {
			apply(getArgs(arguments), 'add');
		}

		function remove() {
			apply(getArgs(arguments), 'remove');
		}

		return {
			'add': add,
			'remove': remove
		};

	}());

	this.isChildOfNode = function(o,sNodeName) {
		if (!o || !o.parentNode) {
			return false;
		}
		sNodeName = sNodeName.toLowerCase();
		do {
			o = o.parentNode;
		} while (o && o.parentNode && o.nodeName.toLowerCase() != sNodeName);
		return (o.nodeName.toLowerCase() == sNodeName?o:null);
	}

	this.getTheDamnLink = (isIE)?function(e) {
		// I really didn't want to have to do this.
		return (e && e.target?e.target:window.event.srcElement);
	}:function(e) {
		return e.target;
	}
	
	this.stopEvent = function(e) {
		if (typeof e != 'undefined' && typeof e.preventDefault != 'undefined') {
			e.preventDefault();
		} else if (typeof event != 'undefined' && typeof event.returnValue != 'undefined') {
			event.returnValue = false;
		}
		return false;
	}
	
	this.getTheDamnTarget = function(e) { return (e.target||(window.event?window.event.srcElement:null)); };

	this.withinStatusBar = function(o) { return ($(o).is("#bar.click")); };

	this.getOffX = function(o) {
		// http://www.xs4all.nl/~ppk/js/findpos.html
		var curleft = 0;
		if (o.offsetParent) {
			while (o.offsetParent) {
				curleft += o.offsetLeft;
				o = o.offsetParent;
			}
		}
		else if (o.x) {
			curleft += o.x;
		}
		return curleft;
	};
	
	this.getTime = function(input,bAsString) {
		var nSec = Math.floor(input);
		var min = Math.floor(nSec/60);
		var sec = nSec-(min*60);
		// if (min == 0 && sec == 0) return null; // return 0:00 as null
		return (bAsString?(min+':'+(sec<10?'0'+sec:sec)):{'min':min,'sec':sec});
	}
	
	this.changeClass = function(node,className){
		$(node).removeClass(self.css.sLoading);
		$(node).removeClass(self.css.sPlaying);
		$(node).removeClass(self.css.sPaused);
		if (className){ $(node).addClass(className); }
	}
	
	this.cleanPlayer = function(){
//		$('#player_lyrics','html, body').empty();
		$(self.BBPtimeElapsed).html('');
		$(self.BBPtimeSelect).html('');
		$(self.BBPtimeTotal).html('');
		$(self.BBPloading).stop().css({width:'0px'});
		$(self.BBPposition).css({width:'0px'});
		$(self.BBPinfo).empty();
	}
	
	this.events = {

		play: function() {
			self.changeClass($(self._lcData.cont),self.css.sPlaying);
			self.changeClass(self.BBPplayer,self.css.sPlaying);
		},

		pause: function() {
			self.changeClass($(self._lcData.cont),self.css.sPaused);
			self.changeClass(self.BBPplayer,self.css.sPaused);
		},

		finish: function() {
			$(self.jpC).unbind(".BBP");
			self.changeClass($(self._lcData.cont));
			self.changeClass(self.BBPplayer);
			self.cleanPlayer();
			var thisLink = (self.indexByURL[self._lcData.href]);
			var nextLink = (self.indexByURL[self._lcData.href]+1);
			if (self.fs){
				if (self.links[nextLink].type != "video/mp4"){
					self.toggleFullscreen();
				} else {
					$(self.jpFS).addClass("buffer");
				}
			}
			if (nextLink<self.links.length) {
				if (self.links[thisLink].id == self.links[nextLink].id){
					self.handleClick({'target':self.links[nextLink]});
				} 
			} else {
				$('body').removeClass('BBPshow');
				self._lcData.cont = undefined;
			}
		},

		whileplaying: function() {
			var d = null;
			$(self.BBPposition).css({width:((self.jpD.status.currentTime/self.jpD.status.duration)*self.jpD.status.seekPercent)+'%'});
			$(self.BBPloading).stop().animate({width:(self.jpD.status.seekPercent)+'%'},300);
			if (self.dragActive) {
				self.updateTime.apply(this);
				if (self._lcData.metadata) {
					d = new Date();
					if (d && d-self.lastWPExec>100) {
						self.refreshMetadata(this);
						self.lastWPExec = d;
					}
				}
			} else {
				d = new Date();
				if (d-self.lastWPExec>100) {
					self.updateTime.apply(this);
					if (self._lcData.metadata) self.refreshMetadata(this);
					self.lastWPExec = d;
				}
			}
			if (self.jpD.status.seekPercent==100){ $(self.BBPloading).stop().css({width:'100%'}); }
			$(self.jpFS).removeClass("buffer");
		},
		
		whileprogress: function() {
//			$(self.jpFS).addClass("buffer");
		}

	}
	
	this.updateTime = function() {
		if ($(self.BBPtimeElapsed).html() == ""){
			$(self.BBPtimeElapsed).stop().css("opacity",0).animate({opacity:1},500);
			$(self.BBPtimeSelect).stop().css("opacity",0).animate({opacity:1},500);
			$(self.BBPtimeTotal).stop().css("opacity",0).animate({opacity:1},500);
		}
		$(self.BBPtimeElapsed).html(self.getTime(self.jpD.status.currentTime,true));
		$(self.BBPtimeTotal).html(self.getTime(self.jpD.status.duration,true));
		var progressPercentage = self.jpD.status.currentPercentAbsolute;
		
		function updateLyrics(){
			var lyricsTop = 0-(($('#player_lyrics #lyricscontainerIn #lyrics','html, body').height()-$('#player_lyrics #lyricscontainerIn','html, body').height())*progressPercentage);
			$('#player_lyrics #lyricscontainerIn #lyrics','html, body').css({top:lyricsTop});
		}

/*		
		var d = new Date();
		if (d-self.lyricsExec>50) {
			updateLyrics();
		} else {
			window.clearTimeout(self.lyricsTimer);
			self.lyricsTimer = window.setTimeout(function(){updateLyrics();},20);
		}
		self.lyricsExec = d;
*/

	};

	this.handleClick = function(e) {
	
		if (typeof e.button != 'undefined' && e.button > 1) { return true; }
		var o = self.getTheDamnLink(e);
		var linkActive = (self.indexByURL[self._lcData.href]);
			
		if (self.withinStatusBar(o)) {

			return true;

		} else if ($(o).is('a.BBPplaynow')){
			var clickSound = self.links[0];
			if ((!($('body','html').hasClass("fullscreen")))&&(clickSound.type == "video/mp4")){
				self.toggleFullscreen();
				$(self.jpFS).removeClass("anim").addClass("buffer");
			}
		} else if ($(o).is('#player_overlay #hit')||$(o).parent().hasClass('videoHit')) {
		
			self.toggleFullscreen();
			return true;
			
		} else if ($(o).parent().hasClass('BBPplaypause')){

			if (linkActive == undefined){
				var clickSound = self.links[0];
			} else {
				var clickSound = self.links[linkActive];
			}

		} else if ($(o).parent().hasClass('BBPprevious')){

			if ((linkActive > 0) && (linkActive != undefined)){
				this.position = 0;
				var clickSound = self.links[linkActive-1];
			} else {
				$(o).animate({left:"-10px"},100).animate({left:"10px"},100).animate({left:"0px"},100);
				return true;
			}

		} else if ($(o).parent().hasClass('BBPnext')){

			if ((linkActive < (self.links.length-1)) && (linkActive != undefined)){
				this.position = 0;
				var clickSound = self.links[linkActive+1];
			} else {
				$(o).animate({left:"-10px"},100).animate({left:"10px"},100).animate({left:"0px"},100);
				return true;
			}

		} else {
		
				if (o.nodeName.toLowerCase() != 'a') {
					o = self.isChildOfNode(o,'a');
					if (!o){ return true; }
				}

				if (!o.href || ((o.type != "audio/mp3") && (o.type != "video/mp4")) || $(o).hasClass(self.excludeClass)) {
					return true; // pass-thru for non-MP3/non-links
				}

			var clickSound = o;
		
		}
		
		var thisSound = self._lcData.href;
		if ((thisSound)&&(thisSound == clickSound.href)) {
			if (self.jpD.status.paused){
				self.jp.jPlayer("play");
			} else {
				self.jp.jPlayer("pause");
			}
		} else {
		
			if (thisSound){
				self.changeClass($(self._lcData.cont));
				self.changeClass(self.BBPplayer);
				$(self.jpC).unbind(".BBP");
			}
		
			// SET COOKIE
			var cookie_date = new Date ( ); cookie_date.setTime ( cookie_date.getTime() );
			var cookie_expire = new Date ( ); cookie_expire.setTime ( cookie_date.getTime() + (10*1000) );
			document.cookie = "breakbit_requeststream=" + encodeURIComponent(cookie_date.toUTCString()) + "; path=/; expires=" + cookie_expire.toUTCString();
			
			// create sound
			if (clickSound.type == "video/mp4"){
				var soundSRC = ({ m4v: clickSound.href });
				$(self.BBPplayer).addClass('video');
				$('body').addClass('video');
			} else {
				$('body').removeClass('fullscreen');
				self.videoframePosition();
				self.jp.jPlayer({fullScreen:false});
				var soundSRC = ({ mp3: clickSound.href });
				$(self.BBPplayer).removeClass('video');
				$('body').removeClass('video');
			}
			self.jp.jPlayer("setMedia", soundSRC);

			$(self.jpC).bind($.jPlayer.event.play + ".BBP", self.events.play);
			$(self.jpC).bind($.jPlayer.event.pause + ".BBP", self.events.pause);
			$(self.jpC).bind($.jPlayer.event.timeupdate + ".BBP", self.events.whileplaying);
			$(self.jpC).bind($.jPlayer.event.progress + ".BBP", self.events.whileprogress);
			$(self.jpC).bind($.jPlayer.event.ended + ".BBP", self.events.finish);
		
			/*
			 = sm.createSound({
				id:'inlineMP3Sound'+(self.soundCount++),
				onmetadata:self.events.metadata
			});
			*/

			// set initial timer stuff (before loading)
			self.cleanPlayer();
			$(self.BBPinfo).empty().html('<p><b>Please Wait..</b></p>');
			
			$('body').addClass('BBPshow');
			self.videoframePosition();

			self._lcData.cont = $(clickSound).parent().parent();
			self._lcData.src = clickSound;
			self._lcData.href = clickSound.href;
				
			var trackid = $(self._lcData.src).attr('bbtrackid');
//			var tracklyricson = $('#options .o_lyricdisplay',self._lcData.oLink);
//			if (tracklyricson.length!=0){
//				$('#player_lyrics','html, body').load('/x/P_lyrics/' + trackid).css({display:'block'});
//			}
			$(self.BBPinfo).load('/x/P_info/' + trackid);
				
			self.changeClass($(self._lcData.cont),self.sPlaying);
			self.changeClass(self.BBPplayer,self.sPlaying);
			self.jp.jPlayer("play",0);
			
		}
				
		if (typeof e != 'undefined' && typeof e.preventDefault != 'undefined') {
			e.preventDefault();
		} else {
			e.returnValue = false;
		}
		return false;
	}
	
	this.handleMouseDown = function(e) {
		// a sound link was clicked
		if (isTouchDevice && e.touches) { e = e.touches[0]; }
		if (e.button === 2) {
//			self.stopEvent(e);
			return false; // ignore right-clicks
		}
		var o = self.getTheDamnTarget(e);
		if (!o) { return true; }
		if (!self.withinStatusBar(o)) { return true; }
		self.dragActive = true;
		self.jp.jPlayer("pause");
		self.setPosition(e);
		if (!isTouchDevice) {
			_event.add(document,'mousemove',self.handleMouseMove);
		} else {
			_event.add(document,'touchmove',self.handleMouseMove);
		}
		$(self.BBPplayer).addClass('dragging');
		return self.stopEvent(e);
	};

	this.handleMouseMove = function(e) {
		if (isTouchDevice && e.touches) { e = e.touches[0]; }
		// set position accordingly
		if (self.dragActive) {
			// be nice to CPU/externalInterface
			var d = new Date();
			if (d-self.dragExec>5) {
				self.setPosition(e);
			} else {
				window.clearTimeout(self.dragTimer);
				self.dragTimer = window.setTimeout(function(){self.setPosition(e);},5);
			}
			self.dragExec = d;
		} else {
			self.stopDrag();
		}
		e.stopPropagation = true;
		return false;
	};

	this.stopDrag = function(e) {
		if (self.dragActive) {
			$(self.BBPplayer).removeClass('dragging');
			if (!isTouchDevice) {
				_event.remove(document,'mousemove',self.handleMouseMove);
			} else {
				_event.remove(document,'touchmove',self.handleMouseMove);
			}
			// If it's not paused
//			if (!$(self.lastSound._data.oLI).hasClass(self.css.sPaused)) {
				var playFrom = Math.floor((self.dragPlayFrom/100)*self.jpD.status.duration);
				self.jp.jPlayer("play",playFrom);
//			}
			self.dragActive = false;
			return self.stopEvent(e);
		}
	};
	
	this.setPosition = function(e) {
		// called from slider control
		var oThis = self.getTheDamnTarget(e), x, oControl, nMsecOffset;
		if (!oThis) { return true; }
		oControl = oThis;
//		while (!$(oControl).hasClass('controls') && oControl.parentNode) { oControl = oControl.parentNode; }
		x = parseInt(e.clientX,10);
		// play sound at this position
		nPercOffset = (((x-self.getOffX(oControl)-4)/(oControl.offsetWidth)*self.jpD.status.duration)/(self.jpD.status.duration))*100;
		if (!isNaN(nPercOffset)) { nPercOffset = Math.floor(Math.max(Math.min(nPercOffset,100)),0); }
		if (!isNaN(nPercOffset)) {
			$(self.BBPposition).css({width:nPercOffset+'%'});
			self.dragPlayFrom = nPercOffset;
			self.jp.jPlayer("playHead",nPercOffset);
//			self.jp.jPlayer("play",Math.floor((nPercOffset/100*self.jpD.status.duration)));
		}
	};
	
	this.videoframePosition = function(){
		if ($(self.BBPplayer).hasClass('video')){
			if (self.fs){
				$(self.jpO).addClass("fs").attr("style", "");
				$(self.jpCC).attr("style", "").css({"width":$(window).width(),"height":$(window).height()});
				$(self.jpW).attr("style", "").css({"max-width":$(window).width()});
			} else {
				$(self.jpO).removeClass("fs");
				$(self.jpCC).attr("style", "");
				$(self.jpW).attr("style", "");
			}
		}
	}
	this.videoframeResize = function(){
		if (self.fs){ $(self.jpFS).removeClass("anim"); }
		self.videoframePosition();
	}
	
	this.toggleFullscreen = function(){
		if (self.fs){
			$('body','html').removeClass("fullscreen");
			self.jp.jPlayer({fullScreen:false});
			self.fs = false;
			if (isChrome||isSafari){ document.webkitCancelFullScreen(); }
		} else {
			$('body','html').addClass("fullscreen");
			self.jp.jPlayer({fullScreen:true});
			self.fs = true;
			if (isChrome||isSafari){ document.body.webkitRequestFullScreen(); }
		}
		self.videoframePosition();
		if (!isChrome&&!isSafari){ $(self.jpFS).addClass("anim"); }
	}
	
	this.init = function() {
		function doEvents(action) { // action: add / remove
			_event[action](document,'click',self.handleClick);
			if (!isTouchDevice) {
				_event[action](document,'mousedown',self.handleMouseDown);
				_event[action](document,'mouseup',self.stopDrag);
			} else {
				_event[action](document,'touchstart',self.handleMouseDown);
				_event[action](document,'touchend',self.stopDrag);
			}
			_event[action](window, 'unload', cleanup);
		}
		function initTrackInspect(){
			$('#searchbutton a').mouseover(function(){ $(this).parent().stop().animate({width: "268px"},250,'easeOutQuint'); });
			$('#searchbutton a').mouseout(function(){ $(this).parent().stop().animate({width: "32px"},250,'easeOutQuint'); });
		}
		cleanup = function() { doEvents('remove'); };
		var oLinks = $("a.BBPmedia");
		var foundItems = 0;
		for (var i=0; i<oLinks.length; i++) {
			var thisLink = oLinks[i];
			if (!$(thisLink).hasClass(self.excludeClass)) {
				$(thisLink).parent().parent().addClass(self.css.sDefault); // add default CSS decoration
				self.links[foundItems] = (oLinks[i]);
				self.indexByURL[oLinks[i].href] = foundItems; // hack for indexing
				foundItems++;
			}
		}
		if (foundItems>0) {
			initTrackInspect();	
			doEvents('add');
		}
		
		$("#player_overlay").mouseover(function (){ $("#playerDisplay").addClass("hover"); } );
		$("#player_overlay").mouseout(function (){ $("#playerDisplay").removeClass("hover"); } );
		
		$(window).resize(function (){ self.videoframeResize(); } );
		$(window).scroll(function (){ self.videoframePosition(); } );
	};

	this.init();
	
}

var BBPlayer = new Object();
$(document).ready(function(){
	BBPlayer = new initBBPlayer();
	BBPlayer.init();
});
