/* youtube video player functions */
 var playerUrl;
 var videoId;
 var playerTitle;
 var playerDescr;
 
/* math fucntions */
function div(op1, op2) {
	return(Math.round(op1/op2 - op1%op2/op2))
}
 
function zeroPad(num,count) {
	var numZeropad = num + '';
	while(numZeropad.length < count) {
		numZeropad = "0" + numZeropad;
	}
	return numZeropad;
}
 
/* Copyright (c) 2007 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * @fileoverview Provides functions for browsing and searching YouTube 
 * data API feeds, as a sample for how to interact with the JSON output
 * from the API. 
 * @author api.rboyd@google.com (Ryan Boyd)
 */

/**
 * provides namespacing for the YouTube Video Browser (ytvb)
 */
var ytvb = {};

/**
 * maximum number of results to return for list of videos
 * @type Number
 */
ytvb.MAX_RESULTS_LIST = 6;

/**
 * maximum number of results to return for related videos
 * @type Number
 */
ytvb.MAX_RESULTS_RELATED = 5;

/**
 * maximum number of results to return for videos by same
 * author as video currently being played.
 * @type Number
 */
ytvb.MAX_RESULTS_USER = 5;

/**
 * width of thumbnail images to display
 * @type Number
 */
ytvb.THUMBNAIL_WIDTH = 130;

/**
 * height of thumbnail images to display
 * @type Number
 */
ytvb.THUMBNAIL_HEIGHT = 97;

/**
 * navigation button id used to page to the previous page of
 * results in the list of videos
 * @type String
 */
ytvb.PREVIOUS_PAGE_BUTTON = 'previousPageButton';

/**
 * navigation button id used to page to the next page of
 * results in the list of videos
 * @type String
 */
ytvb.NEXT_PAGE_BUTTON = 'nextPageButton';

/**
 * table id used to display list of videos
 * @type String
 */
ytvb.VIDEO_LIST_TABLE = 'videoListTable';

/**
 * container div id used to hold table for list of videos
 * @type String
 */
ytvb.VIDEO_LIST_TABLE_CONTAINER_DIV = 'videoList';

/**
 * container div id used to hold the video player
 * @type String
 */
ytvb.VIDEO_PLAYER_DIV = 'videoPlayer';

/**
 * container div id used to hold the related video thumbnails
 * @type String
 */
ytvb.RELATED_VIDEOS_DIV = 'relatedVideos';

/**
 * container div id used to hold the video thumbnails for videos by the same
 * user as the video currently being played
 * @type String
 */
ytvb.USER_VIDEOS_DIV = 'userVideos';

/**
 * container div id used to hold the search box which displays when the page
 * first loads
 * @type String
 */
ytvb.MAIN_SEARCH_CONTAINER_DIV = 'mainSearchBox';

/** 
 * container div id used to hold the search box displayed at the top of
 * the browser after one search has already been performed
 * @type String
 */
ytvb.TOP_SEARCH_CONTAINER_DIV = 'searchBox';

/** 
 * container div id used to hold the page number displayed at the top of
 * @type String
 */
ytvb.PAGE_NUM_DIV = 'page';

/**
 * css class used for the paragraphs of video description information
 * @type String
 */
ytvb.VIDEO_DESCRIPTION_CSS_CLASS = 'video-descr';

/**
 * css class used for the video list
 * @type String
 */
ytvb.VIDEO_LIST_CSS_CLASS = 'video-list';

/**
 * the rel value to look for in the atom:link collection of each video
 * in order to find the videos related to it by YouTube's logic
 * @type String
 */
ytvb.RELATED_VIDEOS_REL = 
    'http://gdata.youtube.com/schemas/2007#video.related';

/**
 * the MIME type used for flash videos, needed to find the appropriate
 * media:content link to use
 * @type String
 */
ytvb.FLASH_MIME_TYPE = 'application/x-shockwave-flash';

/**
 * the URL for the 'Top Rated' standard YouTube feed
 * @type String
 */
ytvb.STANDARD_FEED_URL_TOP_RATED = 
    'http://gdata.youtube.com/feeds/standardfeeds/top_rated';

/**
 * the URL for the 'Most Viewed' standard YouTube feed
 * @type String
 */
ytvb.STANDARD_FEED_URL_MOST_VIEWED = 
    'http://gdata.youtube.com/feeds/standardfeeds/most_viewed';

/**
 * the URL for the 'Recently Featured' standard YouTube feed
 * @type String
 */
ytvb.STANDARD_FEED_URL_RECENTLY_FEATURED = 
    'http://gdata.youtube.com/feeds/standardfeeds/recently_featured';

/** 
 * the URL to use for the standard YouTube video feed
 * @type String
 */
ytvb.VIDEO_FEED_URL = 
    'http://gdata.youtube.com/feeds/videos';

/**
 * map of URLs used for the different types of feeds to query
 * @type Object
 */
ytvb.QUERY_URL_MAP = {
  'top_rated' : ytvb.STANDARD_FEED_URL_TOP_RATED,
  'most_viewed' : ytvb.STANDARD_FEED_URL_MOST_VIEWED,
  'recently_featured' : ytvb.STANDARD_FEED_URL_RECENTLY_FEATURED,
  'all' : ytvb.VIDEO_FEED_URL
};

/**
 * the suffix to add onto the user profile feed to get the feed of
 * videos upload by the specified user
 * @type String
 */
ytvb.USER_VIDEOS_SUFFIX = '/uploads';

/**
 * the internal string used to represent the type of the feed
 * for which an index is a reference to - this is for references
 * to videos in the main list of videos displayed in the app
 * @type String
 */
ytvb.REFERRING_FEED_TYPE_MAIN = 'main';

/**
 * the internal string used to represent the type of the feed
 * for which an index is a reference to - this is for references
 * to videos in the list of related videos
 * @type String
 */
ytvb.REFERRING_FEED_TYPE_RELATED = 'related';

/**
 * the internal string used to represent the type of the feed
 * for which an index is a reference to - this is for references
 * to videos in the list of a user's videos
 * @type String
 */
ytvb.REFERRING_FEED_TYPE_USER = 'user';

/**
 * the page number to use for the next page navigation button
 * @type Number
 */
ytvb.nextPage = 2;

/**
 * the page number to use for the previous page navigation button
 * @type Number
 */
ytvb.previousPage = 0;

/** 
 * the last search term used to query - allows for the navigation
 * buttons to know what string query to perform when clicked
 * @type String
 */
ytvb.previousSearchTerm = '';

/**
 * the last query type used for querying - allows for the navigation
 * buttons to know what type of query to perform when clicked
 * @type String
 */
ytvb.previousQueryType = 'all';

/**
 * the JSON feed for the list of search results - stored for debugging 
 * purposes and to access data in the future based upon the index value
 * of the entry in the feed
 * @type {Object|Null}
 */
ytvb.jsonFeed_ = null;

/**
 * the JSON feed for the list of related video results - stored for debugging 
 * purposes and to access data in the future based upon the index value
 * of the entry in the feed
 * @type {Object|Null}
 */
ytvb.jsonFeedRelated_ = null;

/**
 * the JSON feed for the list of videos by the author of the currently playing
 * video - stored for debugging purposes and to access data in the future 
 *  based upon the index value of the entry in the feed
 * @type {Object|Null}
 */
ytvb.jsonFeedUser_ = null;

/**
 * Creates a script tag for retrieving a Google data JSON feed and and
 * adds it into the html head. 
 * @param {String} scriptSrc The URL for the script, assumed to already have at
 *     least one query parameter, so the '?' is not added to the URL
 * @param {String} scriptId The id to use for the script tag added to the head
 * @param {String} scriptCallback  The callback function to be used after the 
 *     JSON is retrieved.  The JSON is passed as the first argument to the 
 *     callback function.
 */
ytvb.appendScriptTag = function(scriptSrc, scriptId, scriptCallback) {
  // Remove any old existance of a script tag by the same name
  var oldScriptTag = document.getElementById(scriptId);
  if (oldScriptTag) {
    oldScriptTag.parentNode.removeChild(oldScriptTag);
  }
  // Create new script tag
  var script = document.createElement('script');
  script.setAttribute('src', 
      scriptSrc + '&alt=json-in-script&callback=' + scriptCallback);
  script.setAttribute('id', scriptId);
  script.setAttribute('type', 'text/javascript');
  // Append the script tag to the head to retrieve a JSON feed of videos
  // NOTE: This requires that a head tag already exists in the DOM at the
  // time this function is executed.
  document.getElementsByTagName('head')[0].appendChild(script);
};

/**
 * Given the JSON representing an entry, finds the atom:link element with the
 * specified 'rel' value.  Used to find the list of related feeds, comments, 
 * etc. for a particular video.
 * @param {Object} entry The evaluated JSON data representing an entry/video
 * @param {String} rel The rel value for which to find.
 * @return {String|Null} The URL (href) value in the found atom:link or null.
 */
ytvb.findLinkHref = function(entry, rel) {
  for (var i = 0, link; link = entry.link[i]; i++) {
    if (link.rel == rel) {
      return link.href;
    }
  }
  // a link with the specified rel was not found
  return null;
};

/**
 * Given the JSON representing an entry, finds the media:content element with
 * a 'type' attribute of the specified value.
 * @param {Object} entry The evaluated JSON data representing an entry/video
 * @param {String} type The MIME type to find amongst the 
 *     media:content elements
 * @return {String|Null} The URL (href) value int he found atom:link or null
 */
ytvb.findMediaContentHref = function(entry, type) {
  for (var i = 0, content; content = entry.media$group.media$content[i]; i++) {
    if (content.type == type) {
      return content.url;
    }
  }
  // a media:content element with the specified MIME type was not found
  return null;
};

/**
 * Retrieves a list of videos matching the provided criteria.  The list of
 * videos can be restricted to a particular standard feed or search criteria.
 *
 * Please see the following URL for more info on the different standard feeds
 * in the <a href="http://code.google.com/apis/youtube/reference.html#Feeds">
 * Reference Guide</a>
 * @param {String} queryType The type of query to be done - either 'all'
 *     for querying all videos, or the name of a standard feed.
 * @param {String} searchTerm The search term(s) to use for querying as the
 *     'vq' query parameter value
 * @param {Number} page The 1-based page of results to return.
 */
ytvb.listVideos = function(playList, page) {
	
  var queryUrl = playList;
  queryUrl += '?max-results=' + ytvb.MAX_RESULTS_LIST +
        '&start-index=' + (((page - 1) * ytvb.MAX_RESULTS_LIST) + 1);
  ytvb.appendScriptTag(queryUrl, 
                         'videoListScript', 
                         'ytvb.listVideosCallback');
  ytvb.updateNavigation(page);
};

/**
 * Callback function used for processing the results of ytvb.listVideos.
 * This function calls appendVideoData to list each of the videos in the UI
 * @param {Object} data The object obtained by evaluating the JSON text 
 *     returned by the YouTube data API
 */
ytvb.listVideosCallback = function(data) {
  // Stores the json data returned for later lookup by entry index value
  ytvb.jsonFeed_ = data.feed;
  var resultsTableContainer = document.getElementById(
      ytvb.VIDEO_LIST_TABLE_CONTAINER_DIV);

  // Deletes and re-adds the results table from container
  // NOTE: Any other elements added to the container will also be cleared
  while (resultsTableContainer.childNodes.length >= 1) {
    resultsTableContainer.removeChild(resultsTableContainer.firstChild);
  }
  
  var vidTitle;
  var strIdx;
  var vidCount;
  var vidInfo;
  var vidMins;
  var vidSecs;
  var vidTime;
  var thumbnailTd;
  var thumbnailImage;
  var metadataLink;
  var resultsTable = document.createElement('table');
  resultsTable.setAttribute('class', ytvb.VIDEO_LIST_CSS_CLASS);
  var tbody = document.createElement('tbody');
  resultsTable.setAttribute('width', '420px');
  resultsTableContainer.appendChild(resultsTable);
 
  vidCount = 0;
  // Loops through entries in the feed and calls appendVideoData for each
  for (var i = 0, entry; entry = data.feed.entry[i]; i++) {
    // The entry.yt$noembed property will exist if this YouTube video does
    // not support viewing in an embedded player on a third-party site.  
    // Exclude these videos from listing here.  A feature request has been
    // submitted for an additional query parameter to exclude these results
    // from the initial results feed.
    if (! entry.yt$noembed) {
	  if (i == 0) {
		  window['row' + i] = document.createElement('tr');
	  }
	  if (i % 2 == 0 && i != 0) {
		  tbody.appendChild(eval("row" + (i - 2)));
		  window['row' + i] = document.createElement('tr');
	  }
	  if (i == ytvb.MAX_RESULTS_LIST - 1) {
		  tbody.appendChild(eval("row" + (i - 1)));
	  }
	  /* Video cell */
	  thumbnailTd = document.createElement('td');
	  thumbnailTd.onclick = ytvb.generatePlayVideoLinkOnclick(entry.id.$t, i, ytvb.REFERRING_FEED_TYPE_MAIN);
  	  thumbnailTd.setAttribute('width', '130');
	  thumbnailImage = document.createElement('img');
  	  thumbnailImage.setAttribute('src', entry.media$group.media$thumbnail[0].url);
  	  thumbnailTd.appendChild(thumbnailImage);
	  /* Video Info */
	  metadataLink = document.createElement('a');
	  metadataLink.setAttribute('href', '#'); 
	  vidTitle = entry.media$group.media$title.$t;
	  strIdx = vidTitle.indexOf('-');
	  metadataLink.innerHTML = '<span class="episode-title"><br>' + vidTitle.substring(strIdx + 1, vidTitle.length) + '</span>';
	  thumbnailTd.appendChild(metadataLink);
	  vidMins = div(entry.media$group.yt$duration.seconds, 60);
	  vidSecs = entry.media$group.yt$duration.seconds % 60;
	  vidTime = document.createTextNode(vidMins + ":" + zeroPad(vidSecs,2));
	  thumbnailTd.appendChild(document.createElement('br'));
	  thumbnailTd.appendChild(vidTime);
	  
	  if (i % 2 == 0 || i == 0) {
	  	eval("row" + i).appendChild(thumbnailTd);
	  } else {
	  	eval("row" + (i - 1)).appendChild(thumbnailTd);
	  }
	  vidCount = vidCount + 1;
    }
  }
  if (vidCount % 3 != 0) {
	  if (vidCount % 2 == 0){
	  	tbody.appendChild(eval("row" + (i - 2)));
	  } else {
		tbody.appendChild(eval("row" + (i - 1)));		  
	  }
  }
  resultsTable.appendChild(tbody);
  ytvb.playVideo(0, ytvb.REFERRING_FEED_TYPE_MAIN, 0);
};
  
/**
 * For the video at the specified index in the passed feed 
 * (stored as json in a ytvb-scoped property), find and show the related
 * videos.  The videos are added as thumbnail images to a div specified by
 * a constant and are presented in order of relevance (default ordering).
 * @param {Number} entryIndex The index of the entry in the JSON
 * @param {String} referringFeed The name for the referring feed - currently
 *     'related', 'user', or 'main'
 */
ytvb.showRelatedVideos = function(entryIndex, referringFeed) {
  var entry;
  try {
    if (referringFeed == ytvb.REFERRING_FEED_TYPE_RELATED) {
      entry = ytvb.jsonFeedRelated_.entry[entryIndex];
    } else if (referringFeed == ytvb.REFERRING_FEED_TYPE_USER) {
      entry = ytvb.jsonFeedUser_.entry[entryIndex];
    } else if (referringFeed == ytvb.REFERRING_FEED_TYPE_MAIN) {
      entry = ytvb.jsonFeed_.entry[entryIndex];
    } else {
      throw "Unknown type of referring feed.";
    }
    var relatedHref = ytvb.findLinkHref(entry, ytvb.RELATED_VIDEOS_REL);
    var relatedVideosDiv = document.getElementById(ytvb.RELATED_VIDEOS_DIV);
    while (relatedVideosDiv.childNodes.length >= 1) {
      relatedVideosDiv.removeChild(relatedVideosDiv.firstChild);
    }
    relatedVideosDiv.innerHTML = '<b>Related:</b><br />';
    if (relatedHref) {
      relatedHref += '?max-results=' + ytvb.MAX_RESULTS_RELATED;
      ytvb.appendScriptTag(relatedHref, 
          'showRelatedVideosScript', 
          'ytvb.showRelatedVideosCallback');
    }
  } catch (err) {
    alert(err);
  }
};

/**
 * For each related video in the JSON feed, add an thumbnail representing
 * that video to the div specified by a constant.
 * @param {Object} data The object obtained by evaluating the JSON text 
 *     returned by the YouTube data API
 */
ytvb.showRelatedVideosCallback = function(data) {
  var relatedVideosDiv = document.getElementById(ytvb.RELATED_VIDEOS_DIV);
  ytvb.jsonFeedRelated_ = data.feed;
  for (var i= 0, entry; entry = data.feed.entry[i]; i++) {
    relatedVideosJson = entry; 
    var img = document.createElement('img');
    img.setAttribute('src', entry.media$group.media$thumbnail[0].url);
    img.onclick = ytvb.generatePlayVideoLinkOnclick(entry.id.$t, i, 
        ytvb.REFERRING_FEED_TYPE_RELATED);
    img.setAttribute('width', ytvb.THUMBNAIL_WIDTH);
    img.setAttribute('height', ytvb.THUMBNAIL_HEIGHT);
    relatedVideosDiv.appendChild(img);
  }
};

/**
 * Finds the list of videos by the author whose profile URL is passed in.
 * These videos are added as thumbnail images to a div specified by a 
 * constant and are presented in the order of their ratings.
 * @param {String} userProfileUrl The URL pointing to the user's profile
 */
ytvb.showVideosByUser = function(userProfileUrl) {
  var userVideosDiv = document.getElementById(ytvb.USER_VIDEOS_DIV);
  while (userVideosDiv.childNodes.length >= 1) {
    userVideosDiv.removeChild(userVideosDiv.firstChild);
  }
  var queryUrl = userProfileUrl + ytvb.USER_VIDEOS_SUFFIX +
      '?max-results=' + ytvb.MAX_RESULTS_USER + 
      '&orderby=rating';
  userVideosDiv.innerHTML = '<br /><b>Top rated videos by user:</b><br />';
  ytvb.appendScriptTag(queryUrl, 
      'showVideosByUserScript', 
      'ytvb.showVideosByUserCallback');
};

/**
 * For each video entry in the provided JSON, add thumbnail images to
 * a div specified by a constant.
 * @param {Object} data The object obtained by evaluating the JSON text 
 *     returned by the YouTube data API
 */
ytvb.showVideosByUserCallback = function(data) {
  var userVideosDiv = document.getElementById(ytvb.USER_VIDEOS_DIV);
  ytvb.jsonFeedUser_ = data.feed;
  for (var i = 0, entry; entry = data.feed.entry[i]; i++) {
    userVideosJson = entry;
    var img = document.createElement('img');
    img.setAttribute('src', entry.media$group.media$thumbnail[0].url);
    img.onclick = ytvb.generatePlayVideoLinkOnclick(entry.id.$t, i, 
        ytvb.REFERRING_FEED_TYPE_USER);
    img.setAttribute('width', ytvb.THUMBNAIL_WIDTH);
    img.setAttribute('height', ytvb.THUMBNAIL_HEIGHT);
    userVideosDiv.appendChild(img);
  }
};

/**
 * Returns a function that can be added as an event handler for playing
 * a video upon the firing of the event.
 * @param {String} videoUrl The URL of the video to play
 * @param {Number} entryIndex The index of the entry in the referring feed
 * @param {String} referringFeed The referring feed
 * @return {Function} The video playing function
 */
ytvb.generatePlayVideoLinkOnclick = function(videoUrl, 
                                             entryIndex, 
                                             referringFeed) {
  return function() {
    ytvb.playVideo(entryIndex, referringFeed, 1);
    return false;
  };
};

/**
 * Adds the HTML representation of the passed video entry to the 
 * table (tbody) element bassed.
 * @param {Node} tbody The table tbody node.  tbody is needed due to IE, as IE
 *     doesn't allow direct adding of rows to a table.
 * @param {Object} entry The JSON-encoded video entry to display in the table
 * @param {Number} entryIndex The index of the video in the JSON feed's
 *     entries.  This is needed to pass to the code which generates a video
 *     player when an onclick event is fired.
 */
ytvb.appendVideoDataToTable = function(tbody, entry, entryIndex) {
  var tr = document.createElement('tr');
  tr.onclick = ytvb.generatePlayVideoLinkOnclick(entry.id.$t, entryIndex, 
      ytvb.REFERRING_FEED_TYPE_MAIN);
  
  var thumbnailTd = document.createElement('td');
  thumbnailTd.setAttribute('width', '130');
  var thumbnailImage = document.createElement('img');
  thumbnailImage.setAttribute('src', 
      entry.media$group.media$thumbnail[0].url);
  thumbnailTd.appendChild(thumbnailImage);

  var metadataTd = document.createElement('td');
  metadataTd.setAttribute('width', '100%');
  var metadataLink = document.createElement('a');
  metadataLink.setAttribute('href', '#'); 
  metadataLink.innerHTML = entry.media$group.media$title.$t;
  var descPara = document.createElement('p');
  descPara.innerHTML = entry.media$group.media$description.$t;
  descPara.setAttribute('class', ytvb.VIDEO_DESCRIPTION_CSS_CLASS);
  metadataTd.appendChild(metadataLink);
  metadataTd.appendChild(descPara);

  tr.appendChild(thumbnailTd);
  tr.appendChild(metadataTd);
  tbody.appendChild(tr);
};

/**
 * Adds the object and embed tags to play the specified video
 * @param {Number} entryIndex The index of the video in the referring feed
 * @param {String} referringFeed Name of the referring feed
 */
ytvb.playVideo = function(entryIndex, referringFeed, autoplay) {
  var entry;
 
  try {
    if (referringFeed == ytvb.REFERRING_FEED_TYPE_RELATED) {
      entry = ytvb.jsonFeedRelated_.entry[entryIndex];
    } else if (referringFeed == ytvb.REFERRING_FEED_TYPE_USER) {
      entry = ytvb.jsonFeedUser_.entry[entryIndex];
    } else if (referringFeed == ytvb.REFERRING_FEED_TYPE_MAIN) {
      entry = ytvb.jsonFeed_.entry[entryIndex];
    } else {
      throw "Unknown type of referring feed.";
    }
    var videoHref = ytvb.findMediaContentHref(entry, ytvb.FLASH_MIME_TYPE) + '&fs=1';
    var videoPlayerDiv = document.getElementById(ytvb.VIDEO_PLAYER_DIV);
	var videoShareDiv = document.getElementById('videoShare');
	// set sharing variables
	playerUrl = videoHref;
	playerTitle = entry.media$group.media$title.$t;
	playerDescr = entry.media$group.media$description.$t;
	
	var iStart = playerUrl.indexOf('v/') + 2;
	var iEnd = playerUrl.indexOf('&f');
	videoId = playerUrl.substring(iStart, iEnd);
    // Add standard YouTube video embed code, with standard height/width
    // values.  Enable autoplay of the video.
    var html = [];
    html.push('<b>');
    html.push(entry.media$group.media$title.$t);
    html.push('</b><br />');
    html.push('<object width="425" height="350"><param name="movie" value="');
    html.push(videoHref);
    html.push('&autoplay="');
	html.push(autoplay);
	html.push('"></param><param name="wmode" value="transparent"><param name="allowFullScreen" value="true"></param>');
    html.push('</param><embed src="');
    html.push(videoHref);
    html.push('&autoplay=');
	html.push(autoplay);
	html.push('" type="application/x-shockwave-flash" ');
    html.push('allowfullscreen="true" wmode="transparent" width="425" height="350"></embed></object>');
	// Add share button
	html.push('<div id="videoShare">');
    html.push('<a href="http://www.addthis.com/bookmark.php?v=20" onmouseover="return addthis_open(this,\'\',\'http://www.youtube.com/watch?v=' + videoId + '\',\'' + playerTitle + '\')" onmouseout="addthis_close()" onclick="return addthis_sendto()">');
	html.push('<img src="http://s7.addthis.com/static/btn/lg-share-en.gif" width="125" height="16" alt="Bookmark and Share" style="border:0"/></a>');
	html.push('</div>');
    videoPlayerDiv.innerHTML = html.join('');
    //not using related video content
	//ytvb.showRelatedVideos(entryIndex, referringFeed);
    //if (entry.author && entry.author.length > 0) {
    //  ytvb.showVideosByUser(entry.author[0].uri.$t);
    //}
  } catch (err) {
    alert(err);
  }
};

/**
 * Updates the variables used by the navigation buttons and the 'enabled' 
 * status of the buttons based upon the current page number passed in.
 * @param {Number} page The current page number
 */
ytvb.updateNavigation = function(page) {
  ytvb.nextPage = page + 1;
  ytvb.previousPage = page - 1;
  document.getElementById(ytvb.NEXT_PAGE_BUTTON).style.display = 'inline';
  document.getElementById(ytvb.PREVIOUS_PAGE_BUTTON).style.display = 'inline';
  if (ytvb.previousPage < 1) {
    document.getElementById(ytvb.PREVIOUS_PAGE_BUTTON).style.display = 'none';
  } else {
    document.getElementById(ytvb.PREVIOUS_PAGE_BUTTON).style.display = 'inline';
  }
  document.getElementById(ytvb.NEXT_PAGE_BUTTON).style.display = 'inline';
 
 };

/**
 * Hides the main (large) search form and enables one that's in the
 * title bar of the application.  The main search form is only used
 * for the first load.  Subsequent searches should use the version in
 * the title bar.
 */
ytvb.hideMainSearch = function() {
  document.getElementById(ytvb.MAIN_SEARCH_CONTAINER_DIV).style.display = 
      'none';
  document.getElementById(ytvb.TOP_SEARCH_CONTAINER_DIV).style.display = 
      'inline';
};

/**
 * Method called when the query type has been changed.  Clears out the
 * value of the search term input box by default if one of the standard
 * feeds is selected.  This is to improve usability, as many of the standard
 * feeds may not include results for even fairly popular search terms.
 * @param {String} queryType The type of query being done - either 'all'
 *     for querying all videos, or the name of one of the standard feeds.
 * @param {Node} searchTermInputElement The HTML input element for the input
 *     element.
 */
ytvb.queryTypeChanged = function(queryType, searchTermInputElement) {
  if (queryType != 'all') {
    searchTermInputElement.value = '';
  }
};