/*:._.:*:._.:*:._.:*:._.:*:._.:*:._.:*:._.:*:._.:*:._.:*:._.:*:._.:*:._.:*:.

  Created: Wednesday 17 February 2010 17:25 PM EST

.:*:._.:*:._.:*:._.:*:._.:*:._.:*:._.:*:._.:*:._.:*:._.:*:._.:*:._.:*:._.:*/


/**
 * SoundManager2 Config
 */
if(soundManager) {
	soundManager.debugMode = false;
	soundManager.consoleOnly = true;
	soundManager.flashVersion = 9;
	soundManager.url = '/_swf/soundmanager2_flash9.swf';
}

/**
 * MiniPlayer
 *
 * Dependencies:
 * SoundManager 2 (V2.95b.20100101)
 * Bernie's Better Animation Class (Animator.js 1.1.9)
 * jQuery 1.4.1 (only to solve IE event stuff)
 */
function MiniPlayer(canvas, audioPath) {

	var self = this;
	var ctx = canvas.getContext ? canvas.getContext('2d') : canvas;
	var center = { x: canvas.width/2, y: canvas.height/2 };
	var maxRadius = Math.min(canvas.width, canvas.height) / 2;
	var minRadius = 9;
	var radius = minRadius;
	this.playing = false;
	var hovering = false;
	var playbackProgress = 0;
	var imagesLoaded = 0;
	var totalImages = 4;
	var sound = soundManager; // reference to SoundManager object
	var track; // reference to sound instance

	this.clicked = false;

	// Generate a unique ID for the sound object
	if(typeof MiniPlayer.id == 'undefined') {
		MiniPlayer.id = 0;
	} else {
		MiniPlayer.id++;
	}


	// IMAGES

	var sprites = {};

	sprites.play = new Image;
	sprites.play.onload = monitorLoading;
	sprites.play.src = '/_img/audioplayer/play.png';

	sprites.playHover = new Image;
	sprites.playHover.onload = monitorLoading;
	sprites.playHover.src = '/_img/audioplayer/play-hover.png';

	sprites.stop = new Image;
	sprites.stop.onload = monitorLoading;
	sprites.stop.src = '/_img/audioplayer/stop.png';

	sprites.stopHover = new Image;
	sprites.stopHover.onload = monitorLoading;
	sprites.stopHover.src = '/_img/audioplayer/stop-hover.png';

	function monitorLoading(e) {
		if(++imagesLoaded >= totalImages) {
			draw();
		}
	};

	// EVENT HANDLING

	var events = [];

	this.addListener = function(event, callback) {
		if(!events[event]) {
			events[event] = [];
		}
		events[event].push(callback);
	};

	function dispatchEvent(event) {
		if(events[event]) {
			for(var e in events[event]) events[event][e]();
		}
	};
	
	
	// CHEAP IE EVENT FIX (annoying!)
	if($.browser.msie) {
		var $s = $('<span>').css({
			width: 26,
			height: 26,
			position: 'absolute',
			left: $(canvas).offset().left,
			top: $(canvas).offset().top,
			z: 20,
			cursor: 'pointer'
		}).appendTo('body');
	}
	

	// EVENTS

	var mouseEvents = {

		mouseover: function() {
			hovering = true;
			draw();
		},

		mouseout: function() {
			hovering = false;
			draw();
		},

		click: function() {
			self.clicked = true;
			self.playing ? self.stop() : self.play();
			draw();
		}
	};
	
	if(window.addEventListener) {
		canvas.addEventListener('mouseover', mouseEvents.mouseover, false);
		canvas.addEventListener('mouseout', mouseEvents.mouseout, false);
		canvas.addEventListener('click', mouseEvents.click, false);
	} else {
		// IE
		$s.mouseover(mouseEvents.mouseover);
		$s.mouseover(mouseEvents.mouseout);
		$s.click(mouseEvents.click);
	}

	var audioEvents = {

		whileplaying: function() {
			draw(this.position/this.durationEstimate);
		},

		onfinish: function() {
			sound.stopAll();
			track.unload();
			playbackProgress = 360;
			fanIn();
			dispatchEvent('finish');
			self.playing = false;
			draw();
		}
	};


	// INIT AUDIO

	//if(sound.canPlayURL(audioPath)) {
		track = sound.createSound({
			id: 'MiniPlayer' + MiniPlayer.id,
			url: audioPath,
			whileplaying: audioEvents.whileplaying,
			onfinish: audioEvents.onfinish
		});
	//}


	// PUBLIC METHODS

	this.stop = function() {
		if(self.playing) {
			dispatchEvent('stop');
			self.playing = false;
			fanIn();
		}

		track.stop();
		track.unload();

		self.clicked = false;
	}

	this.play = function() {
		if(!self.playing) {
			dispatchEvent('play');
			self.playing = true;
			sound.stopAll();
			track.unload();
			playbackProgress = 0;
			fanOut();
			track.play();
		}
	}


	// PRIVATE METHODS

	function draw(playbackPercent, percentLoaded) {
		if(playbackPercent) {
			playbackProgress = playbackPercent * 360;
		}

		clearCanvas();
		drawPie(360, '#17140F'); // background
		drawPie(playbackProgress, '#690c13'); // playback progress
		drawForeground(); // button image
	};

	function fanOut() {
		fanAnimator.play();
	};

	function fanIn() {
		fanAnimator.reverse();
	};

	function drawPie(degrees, color) {
		var offset = 90; // needed for the arc to start at twelve o'clock

		with(ctx) {
			fillStyle = color;
			beginPath();
			moveTo(center.x, center.y);
			arc(center.x, center.y, radius, degreesToRadians(0 - offset), degreesToRadians(degrees - offset), false);
			lineTo(center.x, center.y); // line back to center
			closePath();
			fill();
		}
	};

	function drawForeground() {
		var activeSprite;

		if(!hovering && !self.playing) {
			activeSprite = sprites.play;
		} else if(hovering && !self.playing) {
			activeSprite = sprites.playHover;
		} else if(!hovering && self.playing) {
			activeSprite = sprites.stop;
		} else {
			activeSprite = sprites.stopHover;
		}

		ctx.drawImage(activeSprite, center.x - activeSprite.width/2, center.y - activeSprite.height/2);
	};

	function clearCanvas() {
		ctx.clearRect(0, 0, canvas.width, canvas.height);
	};

	function degreesToRadians(degrees) {
		return degrees * (Math.PI/180);
	};

	function radiansToDegrees(radians) {
		return radians * (180/Math.PI);
	};


	// ANIMATORS

	var fanAnimator = new Animator({
		duration: 250
	});

	fanAnimator.addSubject(function(value) {
		radius = (maxRadius - minRadius) * value + minRadius;
		draw();
	});


	// INIT

	draw();
}


/**
 * Initilizes MiniPlayers
 *
 * This class should be instantiated after the DOM is ready to receive events.
 *
 * Dependencies:
 * jQuery 1.4.1
 * MiniPlayer (above)
 */
MiniPlayerController = function() {

	var miniPlayers = [];

	if(soundManager && !soundManager.supported()) {
		soundManager.reboot();
	}

	soundManager.onready(function(status) {
		if(status.success) {
			$('canvas').each(function() {
				
				var m = new MiniPlayer(this, $(this).attr('data-stream'));
				m.addListener('play', resetPlayers);

				// Don't play tracks in succession on a search results page.
				if($('div#searchResults.content').size() == 0) {
					m.addListener('finish', playNext);
				}

				miniPlayers.push(m);

			});
		}
	});

	/**
	 * Stop all players on the page.
	 */
	function resetPlayers() {
		for(var m in miniPlayers) {
			miniPlayers[m].stop();
		}
	}

	/**
	 * Play next miniplayer on page. This should be called via an event
	 * listener on a MiniPlayer after a track has finished playing.
	 */
	function playNext() {
		for(var i = 0; i < miniPlayers.length; i++) {
			if(miniPlayers[i].playing) {
				miniPlayers[i].stop();
				miniPlayers[i+1].play();
				break;
			}
		}
	}

}