/* 
 * WPaudio v3.0 (http://wpaudio.com)
 * by Todd Iceton (todd@wpaudio.com)
 *
 * Converts an mp3 link to a simple player styled by HTML & CSS, powered by HTML5 with SoundManager2 Flash fallback
 *
 * Copyright 2010 Todd Iceton (email: todd@wpaudio.com)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

/* 
 * WPaudio common parent that will be appended to the mp3 link
 *
 * All interaction happens through this object, which calls the child players' control methods.
 * This takes care of click event listening and link decoration.
 */

function Wpaudio (elem) {
	this.elem = elem;
	var player;
	this.player = player;
	
	var getUrl = function () {
		return _wpaudio.enc[elem.id] ? _wpaudio.enc[elem.id] : elem.href;
	};
	this.getUrl = getUrl;
	
	var isPlaying = function () {
		return player.isPlaying();
	};
	this.isPlaying = isPlaying;
	
	var play = function () {
		// Pause all playing players before starting this one
		jQuery('.wpaudio-playing').each(function(i,v){
			v.wpaudio.pause();
		});
		player.play();
		// Mark as playing and slide down
		jQuery(elem).addClass('wpaudio-playing').parent().find('.wpaudio-slide:hidden').slideDown();
	};
	this.play = play;
	
	var pause = function () {
		player.pause();
		jQuery(elem).removeClass('wpaudio-playing');
	};
	this.pause = pause;
	
	var seek = function ( percent ) {
		if ( !isPlaying() ) {
			play();
		}
		player.seek(percent);
	};
	this.seek = seek;
	
	// Update button image, progress bars, time
	var updateDisplay = function () {
		// Get info from player
		var info = player.getInfo();
		// Set button image based on play/pause
		jQuery(elem).children('.wpaudio-play').attr('src', (info.is_playing) ? _wpaudio.url + '/wpaudio-pause.png' : _wpaudio.url + '/wpaudio-play.png');
		// Set bar positions
		jQuery(elem).parent().find('.wpaudio-bar-position').css({
			left: String((info.playable_start/info.duration) || 0) + '%',
			width: String((info.position - info.playable_start) / info.duration * 100 || 0) + '%'
		});
		jQuery(elem).parent().find('.wpaudio-bar-playable').css({
			left: String((info.playable_start/info.duration) || 0) + '%',
			width: String((info.playable_end - info.playable_start) / info.duration * 100 || 0) + '%'
		});
		
		// Set time
		var min = Math.floor(info.position / 60);
		var sec = Math.floor(info.position % 60);
		var time_string = min + ':';
		if ( sec < 10 ) {
			time_string += '0'; // Add leading 0 to seconds if necessary
		}
		time_string += sec;
		jQuery(elem).parent().find('.wpaudio-position').text(time_string);
	};
	this.updateDisplay = updateDisplay;
	
	// Define the slider HTML so the next bit doesn't get too messy
	var slider =
		'<div class="wpaudio-slide">' +
			'<div class="wpaudio-bar">' +
				'<div class="wpaudio-bar-playable"></div>' +
				'<div class="wpaudio-bar-position"></div>' +
				'<div class="wpaudio-bar-click"></div>' +
			'</div>' +
			'<div class="wpaudio-meta">' +
				String( jQuery(elem).hasClass('wpaudio-nodl') ? '' : '<a class="wpaudio-download" href="' + elem.href + '">Download</a>' ) +
				'<div class="wpaudio-position"></div>' +
			'</div>' +
		'</div>';
	
	// Toggle play/pause on click and style the player
	jQuery(elem).click(function(){
		if ( isPlaying() ) {
			pause();
		}
		else {
			play();
		}
		jQuery(this).blur();
		return false;
	}).prepend('<img class="wpaudio-play" src="' + _wpaudio.url + '/wpaudio-play.png"/>').wrap('<span class="wpaudio-container"></span>').after(slider);

	// Fix slide width for IE -- in a timeout b/c Chrome shits otherwise
	jQuery(elem).parent().children('.wpaudio-slide').width(jQuery(elem).width());

	// Click bar to seek
	jQuery(elem).parent().find('.wpaudio-bar-click').mouseup(function (e) {
		if ( e.pageX ) {
			var percent = ( e.pageX - jQuery(this).offset().left ) / jQuery(this).width();
			seek(percent);
		}
	});
	
	// Initialize the player
	player = new this.Player(this);
	//player.init(this);
}

/*
 * HTML5 player
 *
 * This contains controls and event handling for the native player
 */
function WpaudioHTML5 (parent) {
	var player = document.createElement('audio');
	this.player = player;
	
	//this.init = function (parent) {
		this.parent = parent;
		player.src = parent.getUrl();
		jQuery(player).bind('play pause ended timeupdate progress canplaythrough', parent.updateDisplay);
		//return this;
	//};
	
	var isPlaying = function () {
		return !player.paused;
	};
	this.isPlaying = isPlaying;
	
	var getInfo = function () {
		return {
			is_playing: isPlaying(),
			position: player.currentTime || 0,
			duration: player.duration || 0,
			playable_start: player.seekable.start() || 0,
			playable_end: player.seekable.end() || 0
		};
	};
	this.getInfo = getInfo;
	
	var play = function () {
		player.play();
	};
	this.play = play;
	
	this.pause = function () {
		player.pause();
	};
	
	this.seek = function ( fraction ) {
		player.currentTime = player.duration * fraction;
	};
	
	return this;
}

function WpaudioSM2 (par) {
	var that = this, player, parent;
	this.player = player;
	this.parent = parent;
	
	//this.init = function (par) {
		this.parent = par;
		this.player = soundManager.createSound({
			id: (par.elem.id && jQuery('#' + par.elem.id).length === 1) ? par.elem.id : 'wpaudio-' + String(Math.random()).split('.')[1] + String((new Date()).getTime()),
			url: par.getUrl(),
			onplay: par.updateDisplay,
			onresume: par.updateDisplay,
			onpause: par.updateDisplay,
			onfinish: par.updateDisplay,
			whileplaying: par.updateDisplay,
			whileloading: par.updateDisplay
		});
		//return this;
	//};
	
	var isPlaying = function () {
		return !(that.player.paused || that.player.playState === 0);
	};
	this.isPlaying = isPlaying;
	
	var getInfo = function () {
		return {
			is_playing: isPlaying(),
			position: that.player.position / 1000 || 0,
			duration: (((that.player.bytesLoaded == that.player.bytesTotal) ? that.player.duration : that.player.durationEstimate) / 1000) || 0,
			playable_start: 0,
			playable_end: ((that.player.bytesLoaded / that.player.bytesTotal) * that.player.duration) / 1000 || 0
		};
	};
	this.getInfo = getInfo;
	
	var play = function () {
		//soundManager.pauseAll();
		that.player.togglePause();
	};
	this.play = play;
	
	this.pause = function () {
		that.player.togglePause();
	};
	
	this.seek = function ( fraction ) {
		if ( !isPlaying() ) {
			play();
		}
		that.player.setPosition(((that.player.bytesLoaded == that.player.bytesTotal) ? that.player.duration : that.player.durationEstimate) * fraction);
	};
	
	return this;
}

/*
 * Append CSS to head
 */
(function(){
	var css = 
		'.wpaudio-container {display:inline-block; zoom:1; *display:inline; font-family: Sans-serif; line-height: 1;}' +
		'.wpaudio-container a, .wpaudio-container a:visited {color: ' + _wpaudio.style.link_color + '; text-decoration: none;}' +
		'.wpaudio-container a:hover {color: ' + _wpaudio.style.link_hover_color + ';}' + 
		'.wpaudio {font-family: ' + _wpaudio.style.text_font + '; font-size: ' + _wpaudio.style.text_size + '; font-weight: ' + _wpaudio.style.text_weight + '; letter-spacing: ' + _wpaudio.style.text_letter_spacing + ';}' +
		'.wpaudio-play {margin: 0 5px 0 0; border: 0; width: 14px; height: 13px; background: #666; vertical-align: baseline;}' +
		'.wpaudio-slide {display: none;}' +
		'.wpaudio-bar {position: relative; margin: 2px 0 0 19px; height: 5px; font-size: 1px; background: ' + _wpaudio.style.bar_base_bg + ';}' +
		'.wpaudio-bar-playable {position: absolute; top: 0; left: 0; right: 100%; height: 5px; z-index: 11; background: ' + _wpaudio.style.bar_load_bg + ';}' +
		'.wpaudio-bar-position {position: absolute; top: 0; left: 0; right: 100%; height: 5px; z-index: 12; background: ' + _wpaudio.style.bar_position_bg + ';}' +
		'.wpaudio-bar-click {position: absolute; top: 0; left: 0; right: 0; width: 100%; height: 5px; z-index: 12; cursor: pointer;}' +
		'.wpaudio-meta {margin: 3px 0 0 19px; font-size: 11px; color: ' + _wpaudio.style.sub_color + ';}' +
		'.wpaudio-download {float: right;}';
	/*var css = 
		'.wpaudio-container {display:inline-block; zoom:1; *display:inline; line-height: 1; font-family: Sans-serif; font-size: 18px; line-height: 1;}' +
		'.wpaudio-container a, .wpaudio-container a:visited {color: #06c; text-decoration: none;}' +
		'.wpaudio-container a:hover {color: #03a;}' + 
		'.wpaudio-play {margin: 0 5px 0 0; border: 0; width: 14px; height: 13px; background: #666; vertical-align: baseline;}' +
		'.wpaudio-slide {display: none;}' +
		'.wpaudio-bar {position: relative; margin: 2px 0 0 19px; height: 5px; font-size: 1px; background: #eee;}' +
		'.wpaudio-bar-playable {position: absolute; top: 0; left: 0; right: 100%; height: 5px; z-index: 11; background: #ccc;}' +
		'.wpaudio-bar-position {position: absolute; top: 0; left: 0; right: 100%; height: 5px; z-index: 12; background: #06c;}' +
		'.wpaudio-bar-click {position: absolute; top: 0; left: 0; right: 0; width: 100%; height: 5px; z-index: 12; cursor: pointer;}' +
		'.wpaudio-meta {margin: 3px 0 0 19px; font-size: 11px; color: #888;}' +
		'.wpaudio-download {float: right;}';*/
	/*var node = document.createElement('style');
	node.type = 'text/css';
	var head = document.getElementsByTagName('head')[0];*/
	jQuery('head').append('<style type="text/css">' + css + '</style>');
}());

// Autoplay - consider moving this to the Wpaudio object (play if autoplay and no .wpaudio-playing)
function wpaudioReady () {
	if ( jQuery('.wpaudio-autoplay:first').length ) {
		jQuery('.wpaudio-autoplay:first')[0].wpaudio.play();
	}
}

/*
 * Initialize WPaudio players
 *
 * Detect HTML5 support, set WPaudio player to either HTML5 or SM2, and initialize WPaudio players
 */
jQuery(document).ready(function(){
	var wpaudio_selector = '.wpaudio, .wpaudio-autoplay' + (_wpaudio.convert_mp3_links ? ' a[href$=.mp3]' : '');
	var _wpaudio_html5 = document.createElement('audio');
	if (!!(_wpaudio_html5.canPlayType && _wpaudio_html5.canPlayType('audio/mpeg;').replace(/no/, ''))) {
		Wpaudio.prototype.Player = WpaudioHTML5;
		jQuery('.wpaudio, .wpaudio-autoplay').each(function(i,v){
			v.wpaudio = new Wpaudio(v);
		});
		wpaudioReady();
	}
	else {
		if (typeof soundManager !== 'object') {
			jQuery.getScript(_wpaudio.url + '/sm2/soundmanager2-nodebug-jsmin.js', function(){
				soundManager.debugMode = false;
				soundManager.url =  _wpaudio.url + '/sm2/';
				soundManager.nullURL = 'about:blank'; //_wpaudio.url + '/sm2/null.mp3';
				soundManager.useHighPerformance = true;
				soundManager.useFastPolling = false;
				soundManager.waitForWindowLoad = false;
				soundManager.onready(function(){
					jQuery('.wpaudio, .wpaudio-autoplay').each(function(i,v){
						v.wpaudio = new Wpaudio(v);
					});
					wpaudioReady();
				});
			});
		}
		Wpaudio.prototype.Player = WpaudioSM2;
	}
});

// Preload pause image
(function(){
	var pause_img = new Image();
	pause_img.src = _wpaudio.url + '/wpaudio-pause.png';
}());
