// Copyright 2008 YouTube, Inc.
// All Rights Reserved

/**
 * @fileoverview Utility functions and objects for the Greeting Card Browser
 *
 * @author ahauth@google.com (Anja Hauth)
 */


/*
 * Create the global YT namespace, if it doesn't already exist.
 */
var YT = YT || {};

var _shortTitlePattern = /(.{1,32})\W/;

function VideoContainer() {
	this.videos = [];
	this.addVideo = function(encrypted_id, title, link, thumbnail, avg_rating, length_seconds) {
		var video = {};
		video.encrypted_id = encrypted_id;
		video.title = title;
		video.link = link;
		video.thumbnail = thumbnail;
		video.avg_rating = avg_rating;
		video.length_seconds = length_seconds;
		video.shortTitle = function() {
			if (title.length >= 35) {
				var match = title.match(_shortTitlePattern)
				if (match) {
					return match[1] + "...";
				} else {
					return title.substr(0, 32) + "...";
				}
			}
			return title;
		}
		this.videos[this.videos.length] = video;
	};
	this.getVideo = function(index) {
		return this.videos[index];
	};
	this.size = function() {
		return this.videos.length;
	};
	this.empty = function() {
		return this.videos.length == 0;
	};
};

function VideoResultRenderer(noVideoResultText, videoViewText, pagerText) {
	var rating_widgets = {};
	this.formatDuration = function(lengthSeconds) {
		var hours = Math.floor(lengthSeconds / 3600);
		var minutes = Math.floor((lengthSeconds % 3600) / 60);
		var seconds = lengthSeconds % 60;
		var result = [];
		if (hours > 0) {
			result[result.length]= (hours < 10 ? "0" : "") + hours;
		}
		result[result.length] = (minutes < 10 ? "0" : "") + minutes;
		result[result.length] = (seconds < 10 ? "0" : "") + seconds;
		return result.join(":");
	};
	this.addVideo = function(content, video) {
		content.push('<div class="vlcell" style="width: 125px; height: 135px; margin: 0px 2px 15px 2px; zoom: 1; overflow: hidden;">');
		content.push('  <div id="'+video.encrypted_id+'" class="vlentry">');
		content.push('    <div class="vlcontainer">');
		content.push('      <div class="v120WideEntry" id="video-thumb">');
		content.push('	<div class="v120WrapperOuter">');
		content.push('	  <div class="v120WrapperInner" onclick="GreetingCard.showVideoPlayer(\''+video.link+'\', \''+video.encrypted_id+'\');">');
		content.push('	    <img alt="" class="vimg120" src="'+video.thumbnail+'" title="'+video.title+'"/>');
		content.push('	  </div>');
		content.push('	</div>');
		content.push('      </div>');
		content.push('      <div class="vldescbox">');
		content.push('	<div class="vltitle">');
		content.push('	  <div class="vlshortTitle">');
		content.push('	    <a  onclick="GreetingCard.showVideoPlayer(\''+video.link+'\', \''+video.encrypted_id+'\');" title="'+video.title+'">'+video.shortTitle()+'</a>');
		content.push('	  </div>');
		content.push('	</div>');
		content.push('      </div>');
		content.push('    </div>');
		content.push('    <div class="vlfacets">');
		content.push('      <div class="video-thumb-duration-rating">');
		content.push(rating_widgets[this.getInternalRating(video.avg_rating)]);
		content.push('	<div class="runtime">'+this.formatDuration(video.length_seconds)+'</div>');
		content.push('      </div>');
		content.push('    </div>');
		content.push('  </div>');
		content.push('</div>');
	};
	this.render = function(videos, page, maxVideosPerPage, totalVideos, dynamicSearch, pagingFunction) {
		var content = [];
		if (videos.empty()) {
			content.push(noVideoResultText);
		} else {
			content.push('<div class="grid-view videoResultEntry">');
			var videoOffset = dynamicSearch ? 0 : (page - 1) * maxVideosPerPage;
			for (i = videoOffset; (i < videoOffset + maxVideosPerPage) && (i < videos.size()); ++i) {
				var video = videos.getVideo(i);
				this.addVideo(content, video);
			}
			content.push('</div>');
			content.push('<div class="pagingDiv pager">');
			var expected_pages = Math.ceil(totalVideos / maxVideosPerPage);
			content.push(pagerText);
			if (page > 1) {
				content.push('<span class="pagerNotCurrent" onclick="'+pagingFunction+'('+(page - 1)+');">&lt;&lt;</span>');
				if (page > 3) {
					content.push('...');
				}
			}
			for (i = Math.max(1, page - 2); i <= Math.min(expected_pages, page + 2); ++i) {
				if (i === page) {
					content.push('<span class="pagerCurrent">'+i+'</span>');
				} else {
					content.push('<span class="pagerNotCurrent" onclick="'+pagingFunction+'('+i+');">'+i+'</span>');
				}
			}
			if (page < expected_pages) {
				if ((page + 2) < expected_pages) {
					content.push('...');
				}
				content.push('<span class="pagerNotCurrent" onclick="'+pagingFunction+'('+(page + 1)+');">&gt;&gt;</span>');
			}
			content.push('</div>');
		}
		return content.join("");
	};
	this.getInternalRating = function(avg_rating) {
		return Math.round((Number(avg_rating) + 0.25) * 2);
	};
	this.addStarRatingWidget = function(avg_rating, widget) {
		var rating = this.getInternalRating(avg_rating);
		rating_widgets[rating] = widget;
	};
};

var GreetingCard = function() {
	var preselectedVideos;
	var ownedVideos;
	var renderer;
	return {
		insertScript: function(query) {
			var script = document.createElement('script');
			script.type = 'text/javascript';
			script.src = query;
			document.body.appendChild(script);
		},
		getTotalResultsJSON: function(feed) {
			if (!feed.openSearch$totalResults || !feed.openSearch$totalResults.$t) {
				return 0;
			}
			return feed.openSearch$totalResults.$t;
		},
		getPageJSON: function(feed) {
			if (!feed.openSearch$startIndex || !feed.openSearch$startIndex.$t) {
				return 1;
			}
			return 1 + Math.floor(feed.openSearch$startIndex.$t / 4);
		},
		getVideoLinkJSON: function(video) {
			if (!video.media$group || !video.media$group.media$content || !video.media$group.media$content[0] || !video.media$group.media$content[0].url) {
				return "";
			}
			return video.media$group.media$content[0].url;
		},
		getVideoThumbnailJSON: function(video) {
			if (!video.media$group || !video.media$group.media$thumbnail || !video.media$group.media$thumbnail[0] || !video.media$group.media$thumbnail[0].url) {
				return "";
			}
			return video.media$group.media$thumbnail[0].url;
		},
		getVideoTitleJSON: function(video) {
			if (!video.title || !video.title.$t) {
				return "";
			}
			return video.title.$t;
		},
		getVideoAverageRatingJSON: function(video) {
			if (!video.gd$rating || !video.gd$rating.average) {
				return 0;
			}
			return video.gd$rating.average;
		},
		getVideoLengthSecondsJSON: function(video) {
			if (!video.media$group || !video.media$group.yt$duration || !video.media$group.yt$duration.seconds) {
				return 0;
			}
			return video.media$group.yt$duration.seconds;
		},
		renderVideoResultsJSON: function(root) {
			var feed = root.feed;
			var videos = feed.entry || [];
			var video_container = new VideoContainer();
			var total_results = this.getTotalResultsJSON(feed);
			var page = this.getPageJSON(feed);
			/* Pattern to match the video-id;*/
			/* Format of link is "http://www.youtube.com/v/adc3MSS5Ydc&f=gdata_videos&c=ytapi-youtube-greetingcard"*/
			var pattern = /.*\/v\/([^&]+).*/;
			for (i=0; i<videos.length; ++i) {
				var link = this.getVideoLinkJSON(videos[i]);
				var matching_result = link.match(pattern);
				if (matching_result) {
					encrypted_id = matching_result[1];
				} else {
					/* we cannot parse the video-id */
					continue;
				}
				var thumbnail = this.getVideoThumbnailJSON(videos[i]);
				var title = this.getVideoTitleJSON(videos[i]);
				var avg_rating = this.getVideoAverageRatingJSON(videos[i]);
				var length_seconds = this.getVideoLengthSecondsJSON(videos[i]);
				video_container.addVideo(encrypted_id, title, link, thumbnail, avg_rating, length_seconds);
			}
			return renderer.render(video_container, page, 4, total_results, true, "GreetingCard.performVideoSearch");
		},
		updateSearchResults: function(req) {
			var watchSearchButton = _gel("searchbox_submit");
			if (watchSearchButton) {
				watchSearchButton.disabled = false;
			}
			var searchResults = _gel("search_results");
			searchResults.innerHTML = GreetingCard.renderVideoResultsJSON(req);
			searchResults.style.textAlign = "left";
		},
		performVideoSearch: function(page) {
			var searchResults = _gel("search_results");
			searchResults.style.textAlign = "center";
			searchResults.style.display = "block";
			searchResults.innerHTML = "<img src='http://s.ytimg.com/yt/img/LoadingGraphic-vfl3869.gif'>";

			var watchSearchButton = _gel("searchbox_submit");
			if (watchSearchButton) {
				watchSearchButton.disabled = true;
			}
			var query = _gel("searchbox").value;
			GreetingCard.insertScript("http://gdata.youtube.com/feeds/api/videos?q="+encodeURIComponent(query)+"&max-results=4&start-index="+(((page - 1) * 4) + 1)+"&client=ytapi-youtube-greetingcard&alt=json-in-script&callback=GreetingCard.updateSearchResults");
		},
		showPreselection: function(page) {
			var videoProposals = _gel("videoProposals");
			videoProposals.innerHTML = renderer.render(preselectedVideos, page, 12, preselectedVideos.size(), false, "GreetingCard.showPreselection");
		},
		showOwned: function(page) {
			if (ownedVideos.size() > 0) {
				var videoOwned = _gel("videoOwned");
				videoOwned.innerHTML = renderer.render(ownedVideos, page, 6, ownedVideos.size(), false, "GreetingCard.showOwned");
			}
		},
		showVideoPlayer: function(embedUrl, videoId) {
			yt.overlay.getPlayer(videoId, embedUrl);
		},
		chooseVideo: function(videoId) {
			_gel("video_id").value = videoId;
			document.getElementById("video_select").submit();
		},
		hideVideoPlayer: function() {
			yt.overlay.hide();
			_gel("video_id").value = "";
		},
		showQuickCapture: function(vidcapData) {
			yt.overlay.getCapture(vidcapData);
		},
		hideQuickCapture: function() {
			yt.overlay.hide();
		},
		init: function(document, videoRenderer, preselection, owned, selectVideoText, closeVideoText) {
			preselectedVideos = preselection;
			ownedVideos = owned;
			renderer = videoRenderer;
			yt.overlay.install(425, 344, closeVideoText, selectVideoText, function(video_id) {GreetingCard.chooseVideo(video_id);});
			GreetingCard.showPreselection(1);
			GreetingCard.showOwned(1);
			GreetingCard.hideVideoPlayer();
			GreetingCard.hideQuickCapture();
		}
	}
}();
