/**
 * @author alexander.farkas
 */

(function($){
		
	var strToObj = $.location.strToObj;
	
	
	
	var tmplMatch = {
		title: 'title.$t'.split('.'),
		id: 'id.$t'.split('.'),
		link: 'link.0.href'.split('.'),
		description: 'media$group.media$description.$t'.split('.'),
		thumbnail: 'media$group.media$thumbnail.0'.split('.')
	};
	
	$.fn.youtubeData = function(opts){
		opts = $.extend({}, $.fn.youtubeData.defaults, opts);
		var ajaxOpts 		= {
						dataType: "jsonp",
						data: $.extend({}, 
							{alt: 'json-in-script', v: '2'}, 
							opts.youTubeParams || {}
						),
						success: success,
						error: opts.complete
					},
			itemTmpl 		= $.tmpl(opts.itemTmpl),
			feedWrapperTmpl = $.tmpl(opts.feedWrapperTmpl)
		;
		
		function success(data){
			if(data && data.feed && data.feed && data.feed.entry && data.feed.entry.length){
				var entrys = data.feed.entry,
					feed = {
						items: ''
					},
					jElm,
					parsedEntrys = []
				;
				
				$.each(entrys, function(i, entry){
					var content = $.transformObj(entry, tmplMatch);
					if(content){
						feed.items += itemTmpl(content);
						parsedEntrys.push(content);
					}
				});
				
				jElm = $(feedWrapperTmpl(feed))
					.replaceAll(this.replace[0]);
				
				opts.complete.call(this, {data: data, DOMFeed: jElm, entrys: parsedEntrys}, 'success');
			} else {
				opts.complete.call(this, {data: data}, 'errorNoFeed');
			}
		}
		 
		return this.each(function(i){
			var jElm = $(this),
				url = $.trim($('span.value', jElm).text());
			if(url){
				$.ajax(
					$.extend(true, {}, ajaxOpts, {
						url: url,
						replace: jElm
					})
				);
			}
		});
	};
	
	$.fn.youtubeData.defaults = {
		itemTmpl: 
			'<li>' +
				'<a class="youtubevideo" href="<%=link%>">' +
					'<%=title%>' +
					'<img src="<%=thumbnail.url%>" alt="" />' +
				'</a>' +
				'<p><%=description%></p>' +
			'</li>',
		feedWrapperTmpl: '<ul><%=items%></ul>',
		youTubeParams: false,
		complete: function(){}
	};
	
	window.onYouTubePlayerReady = function(playerId) {
		var player = $('#'+ playerId);
		if(player && player[0]){
			$.ytPlayer.createHandler(playerId, player);
			player[0].addEventListener('onStateChange', '$.ytPlayer.handler.'+playerId+'.change');
			player[0].addEventListener('onError', '$.ytPlayer.handler.'+playerId+'.error');
			
			player.trigger('ytPlayerReady');
			$(document).trigger({
				type: 'ytPlayerReady'+playerId,
				player: player
			});
		}
	};
	
	$.ytPlayer = (function(){
		
		var handler = {},
			types 	= {
				'-1': 'unstarted',
				'0': 'ended',
				'1': 'playing',
				'2': 'paused',
				'3': 'buffering',
				'5': 'cued'
			}
		;
		
		function createEvent(playerObj, e, playerId){
			var url = playerObj[0].getVideoUrl(),
				urlData = strToObj(url),
				evt = {
					type: 'yt'+ types[e],
					typeName: types[e],
					typeIndex: e,
					target: playerObj[0],
					realTarget: playerObj[0],
					url: url,
					urlData: urlData,
					vId: urlData.v,
					pId: playerId
				};
				
			if(/playing|ended|paused/.test(evt.typeName)){
				$.extend(evt, {
					time: playerObj[0].getCurrentTime(),
					duration: playerObj[0].getDuration()
				});
			}
			
			return evt;
		}
		
		function createHandler(playerId, playerObj){
			if(!handler[playerId]){
				handler[playerId] = {
					change: function(e){
						var evt = createEvent(playerObj, e, playerId);
						playerObj.trigger(evt);
						evt.type = 'ytchange';
						playerObj.trigger(evt);
						
					},
					error: function(e){
						var evt = createEvent(playerObj, e, playerId);
						evt.type = 'yterror';
						playerObj.trigger(evt);
					}
				};
			}
		}
		
		var ytAPI = 'playVideo pauseVideo stopVideo clearVideo getVideoBytesLoaded getVideoBytesTotal getVideoStartBytes mute unMute isMuted setVolume getVolume seekTo getPlayerState getCurrentTime getDuration getVideoUrl getVideoEmbedCode loadVideoById cueVideoById setSize'.split(' ');
		var playerAPI = {
			getVideoId: function(){
				return strToObj( this[0].getVideoUrl() ).v || '';
			},
			playLoadVideoById: function(id, start){
				if(id === this.getVideoId()){
					if(isFinite(start)){
						this[0].seekTo(start, true);
					}
					this[0].playVideo();
				} else {
					this[0].loadVideoById(id, start);
				}
			}
		};
		$.each(ytAPI, function(i, method){
			playerAPI[method] = function(){
				var ret = this[0][method].apply(this[0], arguments);
				return ret || this;
			};
		});
		
		function add(playerObj){
			$.each(playerAPI, function(name, method){
				playerObj[name] = method;
			});
			return playerObj;
		}
		
		return {
			handler: handler,
			createHandler: createHandler,
			add: add
		};
	})();
	
	var YOUTUBEVIDEOPATH 		= 'http://www.youtube.com/v/',
		CHROMELESSPLAYERPATH 	= 'http://www.youtube.com/apiplayer';
	
	$.fn.youtubeVideo = function(ytID, opts){
		opts = $.extend(true, {}, $.fn.youtubeVideo.defaults, opts);
		return this.pushStack(this.map(function(){
			var jElm 		= $(this),
				width		= opts.width || jElm.width(),
				height		= opts.height || jElm.height(),
				id			= jElm.getID(),
				path 		= (opts.chromeless) ? CHROMELESSPLAYERPATH : YOUTUBEVIDEOPATH + ytID,
				ytParams 	= [];
			
			$.each(opts.ytParams, function(name, val){
				ytParams.push(name +'='+ val);
			});
			
			ytParams.push('enablejsapi=1&amp;playerapiid='+ id);
			path += ((opts.chromeless) ? '?' : '&amp;')+ ytParams.join('&amp;');
			if(opts.chromeless){
				$(document).bind('ytPlayerReady'+id, function(){
					$('#'+id)[0].cueVideoById(ytID);
				});
			}
			swfobject.embedSWF(path, id, width, height, "8.0.0", null, null, opts.flashParams);
			
			return $('#'+ id)[0];
		}));
	};
	
	$.fn.youtubeVideo.defaults = {
		flashParams: {
			allowFullScreen: 'true',
			allowScriptAccess: "always"		
		},
		ytParams: {
			fs: '1'
		},
		chromeless: false
	};
	
	$.fn.youtubeList = function(opts, playerOpts){
		
		opts = $.extend({}, $.fn.youtubeList.defaults, opts);
		
		var changeTypes = 'unstarted ended playing paused buffering cued'.split(' ');
		
		
		function getVIDFromLink(elem){
			var id = strToObj( (typeof elem == 'string') ? elem : $(elem).attr('href') ).v;
			if(!id && window.console && window.console.log){
				console.log('konnte keine ID parsen');
			}
			return id;
		}
		
		return this.each(function(){
			var widgetElm	= $(this),
				videos 		= $(opts.vLinks, this),
			 	player 		= $(opts.player, this),
				playerID 	= player.getID(),
				list 		= (opts.listItems) ? $(opts.listItems, this) : false;
			
			
			
			if(list){
				list.each(function(){
					$(this)
						.attr('data-ytid', 
							getVIDFromLink(
								$(opts.vLinks, this).attr('href')
							)
						);
				});
			}
			
			function init(){
				var showingVideo 	= videos.filter('ui-current'), vID;
				if(!showingVideo[0]){
					showingVideo = videos.filter(':eq('+ opts.selectedIndex +')');
				}
				
				vID = getVIDFromLink(showingVideo);
				if(!vID){
					return false;
				}
				
				player = $.ytPlayer.add( player.youtubeVideo(vID, playerOpts) );
				
				widgetElm.data('ytVideo', player);
				
				player.bind('ytchange', function(e){
					var currentType = widgetElm.attr('class');
					
					if (list) {
						if (!showingVideo.is('[data-ytid=' + e.vId + ']')) {
						
							showingVideo.removeClass('ui-current')
								.trigger('removedCurrentYt');
							
							showingVideo = list.filter('[data-ytid=' + e.vId + ']')
								.addClass('ui-current')
								.trigger('addedCurrentYt');
						}
					}
					
					$.each(changeTypes, function(i, type){
						if(currentType.indexOf('yt-'+ type) !== -1){
							widgetElm
								.removeClass('yt-'+ type)
								.trigger('removedYt'+ type);
							return false;
						}
					});
					widgetElm.addClass('yt-'+ e.typeName);
				});
				
				videos
					.bind('click', playVideo);
				
			}
						
			function playVideo(e){
				e.preventDefault();
				var jElm 	= $(this), 
					id 		= getVIDFromLink(jElm);
				
				if(!id){
					return false;
				}
				
				player.playLoadVideoById(id);
				return false;
			}
			
			
			init();
		});
	};
	
	$.fn.youtubeList.defaults = {
		selectedIndex: 0,
		vLinks: 'a.youtube-video'
	};
})(jQuery);
