/*!
 * jQuery Sound Manager Plugin
 * http://github.com/adriengibrat/jQuery-SoundManager
 *
 * Copyright (c) 2009 Adrien Gibrat
 * Dual licensed under the MIT and GPL licenses.
 * http://opensource.org/licenses/mit-license.php
 */
(function($){
	var sm = soundManager;
	$.playable = $.extend( function( url, settings ) {
		$.extend( sm, {
			url : url, // Set Flash url
			debugMode : false,//window.location.hash.match(/^#debug/i), // Activate Debugging with hash (#debug)
			consoleOnly : true,//window.location.hash.match(/console$/i), // Debug in console only (#debugconsole)
			defaultOptions : $.extend({ // Extends soundManager default options
				autoStart : false,
				pauseOnly : false,
				playNext : true,
				loopNext : true,
				playAlone : true,
				doUnload : false
			}, settings )
		});
		$.each( $.playable.events, function( i, event ) { // Set Events Handler as element custom Handler
			sm.defaultOptions[event] = function() {
				this.options.element.triggerHandler( event, this );
			};
		} );
	}, {
		count : 0,
		current : null,
		searching : null,
		css : {
			playable: 'playable',
			loading : 'loading',
			playing : 'playing',
			paused : 'paused'
		},
		methods : ['play','stop','pause','resume','togglePause','mute','unmute','unload','setPosition','setVolume','setPan'],
		events : ['onload', 'onplay', 'onpause', 'onresume', 'onstop', 'onfinish'],
		init : function( options, playlist ) {
			var options = $.extend( true, {playlist: playlist}, sm.defaultOptions, options ),
				self = $( this );
			if(self.hasClass($.playable.css.playable) ) return;
			self.addClass( $.playable.css.playable )
			.data( 'playable', sm.createSound( $.extend( options, {
				id : 'playable' + $.playable.count++,
				url : this.href,
				element : self
			} ) ) )
			.click( function( event ) {
				event.preventDefault();
				self.data( 'playable' ).togglePause();
				return false;
			} )
			.bind( 'onload.playable', function( event, sound ){
				if ( sound.readyState == 2 )
					$.playable.next();
			} )
			.bind( 'onplay.playable', function(){
				if ( options.playAlone && $.playable.current && $.playable.current != self )
					$.playable.current.data( 'playable' )[ options.pauseOnly ? 'pause' : 'stop' ]();
				$.playable.current = self.focus();
			} )
			.bind( 'onresume.playable', function( event, sound ){
				self.triggerHandler( 'onplay', sound );
			} )
			.bind( 'onstop.playable', function( event, sound ){
				if ( options.doUnload )
					sound.unload();
			} )
			.bind( 'onfinish.playable', function( event, sound ){
				self.triggerHandler( 'onstop', sound );
				if ( options.playNext )
					$.playable.next();
			} );
			$.each( $.playable.ui, function( i, ui ){ // Bind UIs
				ui.call( self, options );
			} );
		},
		ui : {
			basic : function() {
				var self = this
				.bind( 'onload.playable', function(){
					self.removeClass( $.playable.css.loading );
				} )
				.bind( 'onplay.playable', function(){
					self.removeClass( $.playable.css.paused ).addClass( $.playable.css.playing );
					if ( self.data( 'playable' ).readyState == 1 )
						self.addClass( $.playable.css.loading );
				} )
				.bind( 'onpause.playable', function(){
					if ( ! $.playable.searching )
						self.removeClass( $.playable.css.playing ).addClass( $.playable.css.paused );
				} )
				.bind( 'onstop.playable', function(){
					self.removeClass( [$.playable.css.playing, $.playable.css.loading, $.playable.css.paused].join(' ') );
				} );
			}
		},
		next : function( move ) {
			if ( ! this.current )
				return;
			var options		= this.current.data( 'playable' ).options,
				playlist	= $( options.playlist ),
				songs		= playlist.is( 'a[href]' ) ? playlist : playlist.find( 'a[href]' ),
				move		= move || 1,
				next		= songs.eq( songs.index( options.element ) + move ).data( 'playable' );
			if ( ! next && options.loopNext )
				next = songs.eq( 0 ).data( 'playable' );
			if ( next && ! next.playState )
				next.play();
		}
	} );
	$.fn.playable = function( options ) {
		
		var playlist	= this.selector,
			songs		= this.is( 'a[href]' ) ? this : this.find( 'a[href]' ),
			options		= options || {};
		
		if ( typeof options == 'string' && $.inArray( options, $.playable.methods ) != -1 )
			songs.each( function( args ){
				var sound = $( this ).data( 'playable' );
				sound && sound[options]( args );
			}, [arguments[1]] );
		else
		{
			sm.onready( function() {
				//log('sm.onready - songs',songs);
				songs.each( function(){
									 
					if ( sm.canPlayURL( this.href ) )
						$.playable.init.call( this, options, playlist );
						
				});
				if ( options && options.autoStart )
					songs.filter( ':first' ).click();
			} );
		}
		return this;
	};
})(jQuery);

/*!
 * jQuery Sound Manager Simple UI
 * http://github.com/adriengibrat/jQuery-SoundManager
 *
 * Copyright (c) 2009 Adrien Gibrat
 * Dual licensed under the MIT and GPL licenses.
 * http://opensource.org/licenses/mit-license.php
 */
(function($){
	if ( ! $.playable )
		return;
	$.playable.events.push( 'whileloading', 'whileplaying' );
	$.extend( true, $.playable, {
		css : {
			ui : 'ui',
			timing : 'timing',
			elapsed : 'elapsed',
			total : 'total',
			controls : 'controls',
			loading : 'loading',
			position : 'position',
			searching : 'searching'
		},
		formatTime : function( ms ) {
			var ns = Math.floor( ms / 1000 ),
				m = Math.floor( ns / 60 ),
				s = ns - m * 60 ;
			return m + ':' + ( s < 10 ? '0' + s : s );
		},
		ui : {
			simple : function() {
				var doNothing = function() {
						return false;
					};
				$( '<span class="' + $.playable.css.ui + ' ' + $.playable.css.timing + '"><span class="' + $.playable.css.elapsed + '"></span><span class="' + $.playable.css.total + '"></span></span>' )
				.bind( 'click.playable', doNothing )
				.prependTo( this );
				$( '<span class="' + $.playable.css.ui + ' ' + $.playable.css.controls + '"><span class="' + $.playable.css.loading + '"></span><span class="' + $.playable.css.position + '"></span></span>' )
				.bind( 'click.playable', doNothing )
				.bind( 'mousedown.playable', function( event ) {
					var controls	= $( this ).addClass( $.playable.css.searching ),
						position	= controls.find( '.' + $.playable.css.position ),
						left		= controls.offset().left,
						width		= controls.width(),
						sound		= controls.parent().data( 'playable' );
						x			= event.clientX - left;
					$.playable.searching = controls;
					position.width( x );
					sound.setPosition( x / width * sound.durationEstimate );
					sound.pause();
					$( document ).bind( 'mousemove.playable', function( event ) {
						var x = Math.max( 0, Math.min( event.clientX - left, width ) );
						position.width( x );
						sound.setPosition( x / width * sound.durationEstimate );
						return false;
					} );
					return false;
				} )
				.appendTo( this );
				$( this )
				.bind( 'onstop.playable', function(){
					$( '.' + $.playable.css.elapsed + ', .' + $.playable.css.total, this ).empty();
				} )
				.bind( 'whileloading.playable', function( event, sound ){
					$( '.' + $.playable.css.loading, this ).width( sound.bytesLoaded / sound.bytesTotal * 100 + '%' );
				} )
				.bind( 'whileplaying.playable', function( event, sound ){
					$( '.' + $.playable.css.position, this ).width( sound.position / sound.durationEstimate * 100 + '%' );
					$( '.' + $.playable.css.elapsed, this ).html( $.playable.formatTime( sound.position ) );
					$( '.' + $.playable.css.total, this ).html( ' / ' + $.playable.formatTime( sound.durationEstimate ) );
				} );
				$( document ).bind( 'mouseup.playable', function( event ) {
					//event.preventDefault();
					if ( ! $.playable.searching )
						return;
					var element	= $.playable.searching.removeClass( $.playable.css.searching ).parent(),
						sound	= element.data( 'playable' );
					$( document ).unbind( 'mousemove.playable' );
					if ( element.hasClass( $.playable.css.playing ) )
						sound.resume();
					$.playable.searching = null;
					return false;
				} );
			}
		}
	});
})(jQuery);
