/**
 * Synergypoint Music Player
 * Play music files on your webpage through Flash controlled by Javascript
 * 
 * Options
 * ----------
 * 
 * 
 * Methods
 * ----------
 * init					Called once to initialize the musicplayer, including
 * 						embedding the flash file into the page
 * 						init(options)
 * 
 * bind					Listens for an event to be triggered
 * 						bind(EVENT, CALLBACK)
 * 							EVENT		Event name to listen for
 * 							CALLBACK	Function to call when EVENT is triggered
 * 
 * unbind				Removes a callback from an event trigger
 * 						unbind(EVENT, CALLBACK)
 * 							EVENT		Event name being listened for
 * 							CALLBACK	Function to remove
 * 										Default remove all functions
 * 
 * play					Plays or resumes a music file
 * 						play()		Resumes the currently loaded music file
 * 									from its last track position
 * 						play(N)		Loads new music file at url N and plays it
 * 
 * stop					Stops the currently playing music file
 * 
 * volume				Get or set the volume level
 * 						volume()	Returns the current volume level
 * 						volume(X)	Sets volume to X (X between 0 and 1)
 * 
 * position				Get or set the position of the currently playing track
 * 						position()	Returns the current track position as a
 * 									fraction of trackLength() (between 0 and 1)
 * 						position(X)	Sets track position to X, where X is
 * 									between 0 and 1
 * 
 * trackLength			Gets the length of the current track
 * 						If no track loaded, returns 0
 * 
 * Events
 * ----------
 * onReady				Called when the music player is ready to play music
 * 						callback: function()
 * 
 * onLoadStart			Called when a music file has begun loading
 * 						callback: function(filepath)
 * 							filepath	Path and filename of music file
 * 
 * onLoadProgress		Called periodically while a music file is loading
 * 						callback: function(filepath, bytesLoaded, bytesTotal)
 * 							filepath	Path and filename of music file
 * 							bytesLoaded	Number of bytes loaded so far
 * 							bytesTotal	Total number of bytes to be loaded
 * 
 * onLoadStop			Called when a music file has stopped loading
 * 						(successfully or not)
 * 						callback: function(filepath, status)
 * 							filepath	Path and filename of music file
 * 							error		False if load successful
 * 										Error message if load failed
 * 
 * onPlayStart			Called when a music file has begun to play
 * 						callback: function(filepath)
 * 							filepath	Path and filename of music file
 * 
 * onPlayStop			Called when a music file has stopped playing
 * 						callback: function(filepath)
 * 							filepath	Path and filename of music file
 */
(function(_sp){
var sp = window[_sp];
var _self = 'musicplayer';
var self = sp.musicplayer = {
	options: {
		uiVolumeSlider: null,
		uiTrackSlider: null,
		flashId: 'spMusicPlayerFlash',
		debug: 0
	},
	evtBindings: {onReady:[], onLoadStart:[], onLoadProgress:[], onLoadStop:[], onPlayStart:[], onPlayStop:[] },
	ready:false,
	
/* init **/
	init: function(userOptions, secondTry) {
		// First, we need to ensure that SWFOBJECT has been loaded
		if (!window.swfobject) {
			// swfobject not found, attempt to load it
			if (!secondTry) {
				$.getScript('/shared/swfobject/swfobject.js', function() { self.init(userOptions, true); });
			}
			// swfobject could not be loaded, notify the user and die
			else {
				alert('swfobject could not be loaded!');
			}
			return;
		}
		
		// If we get here, swfobject is loaded and ready to go
		self.options = $.extend({}, self.options, userOptions);
		
		// Embed the flash movie into the page
		$('body').append('<div id="'+self.options.flashId+'"></div>');
	    if (swfobject.hasFlashPlayerVersion("9.0.0")) {
			self.swf = swfobject.createSWF(
				{data:'/shared/splib/musicplayer/spMusicPlayer.swf', width:1, height:1},
				{flashvars:'debug='+self.options.debug+'&eventHandler='+_sp+'.'+_self+'.trigger'},
				self.options.flashId);
		}
	},
	
/* bind **/
	bind: function(evt, cb) {
		if (!self.evtBindings[evt]) return;
		
		if (evt == 'onReady' && self.ready) { cb(); return; }
		
		var found = false;
		for (var i in self.evtBindings[evt])
			if (self.evtBindings[evt][i] == cb) found = true;
		if (!found) self.evtBindings[evt].push(cb);
	},
	
/* unbind **/
	unbind: function(evt, cb) {
		var B = self.evtBindings[evt];
		if (!B) return;
		
		self.evtBindings[evt] = $.grep(B, function(n) { return n!=cb; });
	},
	
/* play **/
	play: function(url) {
		return self.cmd('play', url);
		
	},

/* pause **/
	pause: function() {
		return self.cmd('pause');
	},
	
/* stop **/
	stop: function() {
		return self.cmd('stop');
	},
	
/* volume **/
	volume: function(level) {
		return self.cmd('volume', level);
	},
	
/* position **/
	position: function(pos) {
		return self.cmd('position', pos);
	},
	
/* trackLength **/
	trackLength: function() {
		return self.cmd('trackLength');
	},
	
/* cmd **/
	cmd: function(method, param) {
		var result = "INVALID COMMAND";
		// Ensure that swf file exists
		try { result = self.swf.cmd(method, param); }
		catch(e) {
			if (window.console) console.error(e);
			else {
				var s = ['self.swf: ' + self.swf.id];
				for (var i in e) s.push(i + ": " + e[i]);
				alert("Error: \n\n" + s.join("\n"));
			}
		}
		return result;
	},
	
/* trigger **/
	trigger: function(name, args) {
		switch (name) {
			case 'onReady':
				self.ready = true;
				break;
		}
		
		$.each(self.evtBindings[name], function() {
			this.apply(this, args);
		});
	}
};
})('sp');
