/**
 * Copyright (c) 2009 eSolutions Group Ltd.
 * 
 * Author: Timothy Grant Vogelsang <tvogelsang@esolutionsgroup.ca>
 */

/**
 * The default account to retrieve results from.
 */
YouTube.DEFAULT_ACCOUNT = 'netski77';

/**
 * The default base feed URL.
 */
YouTube.DEFAULT_BASE_FEED_URL = 'http://gdata.youtube.com/feeds/api';

/**
 * The default class name.
 */
YouTube.DEFAULT_CLASS_NAME = 'youtube';

/**
 * The default play on select.
 */
YouTube.DEFAULT_PLAY_ON_SELECT = true;

/**
 * The default player height.
 */
YouTube.DEFAULT_PLAYER_HEIGHT = '344';

/**
 * The default player width.
 */
YouTube.DEFAULT_PLAYER_WIDTH = '425';

/**
 * The default player version.
 */
YouTube.DEFAULT_PLAYER_VERSION = '8';

/**
 * The default thumbnail width.
 */
YouTube.DEFAULT_THUMBNAIL_WIDTH = '90';

/**
 * The default title length.
 */
YouTube.DEFAULT_TITLE_LENGTH = 50;

/**
 * The default query parameters.
 */
YouTube.DEFAULT_QUERY_PARAMS = '?v=2.0&max-results=50&alt=json-in-script&callback=?';

/**
 * The YouTube JavaScript API retrieves the playlist results of a specific account over AJAX/JSON.
 *
 * The results are processed and displayed to the public in the following format:
 *
 *	<div class="youtube">
 *		<div class="video"></div>
 *		<div class="videos">
 *			<div class="entry">
 *				<div class="entry-image">
 *					<img src="..." border="0" width="90" valign="absmiddle" />
 *				</div>
 *				<div class="entry-content">
 *					<a href="#">Title</a>
 *					<div class="entry-content-duration">1 min 30 sec</div>
 *				</div>
 *			</div>
 *		</div>
 *	</div>
 */
function YouTube(options) {
	this.initialize(options);
}

/**
 * Initialization of object.
 */
YouTube.prototype.initialize = function(options) {
	this.clientId = Math.uuid();
	
	this.options = jQuery.extend(
		{
			account:				YouTube.DEFAULT_ACCOUNT,
			className:				YouTube.DEFAULT_CLASS_NAME,
			height:				YouTube.DEFAULT_PLAYER_HEIGHT,
			playOnSelect:			YouTube.DEFAULT_PLAY_ON_SELECT,
			playerHeight:			YouTube.DEFAULT_PLAYER_HEIGHT,
			playerWidth:			YouTube.DEFAULT_PLAYER_WIDTH,
			playerVersion:			YouTube.DEFAULT_PLAYER_VERSION,
			thumbnailWidth:			YouTube.DEFAULT_THUMBNAIL_WIDTH,
			titleLength:			YouTube.DEFAULT_TITLE_LENGTH
		}, options);
	
	this.resolvePlayList();
}

/**
 * This public function performs the necessary routines to properly
 * retrieve the duration of the video.
 */
YouTube.prototype.getDuration = function(duration) {
	var result = '';
	
	if (duration > 59) result = Math.floor(duration / 60) + ' min ';
	if (duration % 60) result += (duration % 60) + ' sec';
	
	return result;
}

/**
 * This public function performs the necessary routines to properly
 * resolve the playlist.
 */
YouTube.prototype.resolvePlayList = function() {
	var _self = this;
	
	var url = YouTube.DEFAULT_BASE_FEED_URL + '/users/' + this.options.account + '/playlists' + YouTube.DEFAULT_QUERY_PARAMS;
	
	jQuery.getJSON(url, function(data) {
		var entries = data.feed.entry || [ ];
		jQuery.each(entries, function(i, entry) {
			if (entry.title.$t == _self.options.playlist) _self.resolveVideosByPlayList(entry.yt$playlistId.$t);
		} );
	} );
}

/**
 * This public function performs the necessary routines to properly
 * resolve the videos for the playlist.
 */
YouTube.prototype.resolveVideosByPlayList = function(playlistId) {
	var _self = this;
	
	var url = YouTube.DEFAULT_BASE_FEED_URL + '/playlists/' + playlistId + YouTube.DEFAULT_QUERY_PARAMS;
	
	jQuery.getJSON(url, function(data) {
		_self.videos = [ ];
		
		var entries = data.feed.entry || [ ];
		jQuery.each(entries, function(i, entry) {
			_self.videos[i] = new Object();
			_self.videos[i].id = entry.media$group.yt$videoid.$t;
			_self.videos[i].duration = entry.media$group.yt$duration.seconds;
			_self.videos[i].title = entry.media$group.media$title.$t;
			if (_self.videos[i].title.length > _self.options.titleLength) _self.videos[i].title = _self.videos[i].title.substring(0, _self.options.titleLength) + '...';
			if (entry.media$group.media$thumbnail) _self.videos[i].thumbnail = entry.media$group.media$thumbnail[0].url;
		} );
		
		_self.loadVideos(_self.videos);
		
		if (_self.videos.length > 0) _self.loadVideo(_self.videos[0]);
	} );
}

/**
 * This public function performs the necessary routines to properly
 * load the SWF video.
 */
YouTube.prototype.loadVideo = function(video, autoPlay) {
	var parameters = {
		allowScriptAccess:	"always",
		wmode: "transparent"
	};
	var attributes = {
		id:	this.videoContainer.id
	};

	swfobject.embedSWF(
		'http://www.youtube.com/v/' + video.id + '&enablejsapi=1&rel=0&playerapiid=ytplayer&autoplay=' + (autoPlay == true ? '1' : '0'),
		this.videoContainer.id,
		this.options.playerWidth,
		this.options.playerHeight,
		this.options.playerVersion,
		null,
		null,
		parameters,
		attributes
	);
}

/**
 * This public function performs the necessary routines to properly
 * load the videos.
 */
YouTube.prototype.loadVideos = function(videos) {
	var _self = this;
	
	jQuery.each(videos, function(i, video) {
		jQuery('<div id=\'' + i + '\' class=\'entry\'><div class=\'entry-image\'><img src=\'' + video.thumbnail + '\' border=\'0\' width=\'' + _self.options.thumbnailWidth + '\' valign=\'absmiddle\' /></div><div class=\'entry-content\'><a href=\'javascript: return false;\'>' + video.title + '</a></div><div class=\'entry-content-duration\'>' + _self.getDuration(video.duration) + '</div><div class=\'clear\'></div></div>').appendTo(_self.videosControl);
	} );
	
	var entries = jQuery('.entry', this.control);
	
	entries.bind('mouseover', function(e) { jQuery(this).addClass('hover'); } );
	entries.bind('mouseout', function(e) { jQuery(this).removeClass('hover'); } );
	entries.bind('click', function(e) { _self.loadVideo(_self.videos[this.id], _self.options.playOnSelect); } );
	
	jQuery('.entry:first', this.control).addClass('first');
	jQuery('.entry:odd', this.control).addClass('alternate');
	jQuery('.entry:last', this.control).addClass('last');
}

/**
 * This public function performs the necessary routines to properly
 * render the control.
 */
YouTube.prototype.render = function() {
	// Render the control
	document.writeln('<div id=\'' + this.clientId + '\' class=\'' + this.options.className + '\'></div>');
	
	this.control = document.getElementById(this.clientId);
	
	// Render the video control
	jQuery('<div id=\'' + this.clientId + '_video\' style=\'height: ' + this.options.playerHeight + 'px; width: ' + this.options.playerWidth + 'px;\' class=\'video\'></div>').appendTo(this.control);
	
	this.videoControl = document.getElementById(this.clientId + '_video');
	
	// Render the video container
	jQuery('<div id=\'' + this.videoControl.id + '_container\'></div>').appendTo(this.videoControl);
	
	this.videoContainer = document.getElementById(this.videoControl.id + '_container');
	
	// Render the videos control
	jQuery('<div id=\'' + this.clientId + '_videos\' style=\'height: ' + this.options.playerHeight + 'px;\' class=\'videos\'></div>').appendTo(this.control);
	
	this.videosControl = document.getElementById(this.clientId + '_videos');
}
