/* Thanks Google/Youtube API Examples!!!
 *
 * 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.
 */

/**
 * Largely inspired by Ryan Boyd's functions for browsing and searching YouTube data API
 * feeds, as a sample for how to interact with the JSON output from the API. 
 * 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 = 1;

/**
 * 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 = 80;

/**
 * height of thumbnail images to display
 * @type Number
 */
ytvb.THUMBNAIL_HEIGHT = 72;

/**
 * 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 = 'searchResultsVideoListTable';

/**
 * container div id used to hold table for list of videos
 * @type String
 */
ytvb.VIDEO_LIST_TABLE_CONTAINER_DIV = 'searchResultsVideoList';

/**
 * 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';

/**
 * css class used for the paragraphs of video description information
 * @type String
 */
ytvb.VIDEO_DESCRIPTION_CSS_CLASS = 'videoDescription';

/**
 * css class used for the video list
 * @type String
 */
ytvb.VIDEO_LIST_CSS_CLASS = 'videoList';

/**
 * 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;
};


/* MTH FUNCTIONS */
// Great thanks to http://911-need-code-help.blogspot.com/2009/10/youtube-javascript-player-with-playlist.html
  
  var ytplayer_playlist = [ ];
  var ytplayer_playitem = 0;
  swfobject.addLoadEvent( ytplayer_render_player );
  //swfobject.addLoadEvent( ytplayer_render_playlist );
  function ytplayer_render_player( )
  {
    swfobject.embedSWF
    (
      'http://www.youtube.com/v/' + ytplayer_playlist[ ytplayer_playitem ] + '&autoplay=1&enablejsapi=1&rel=0&fs=1',
      'ytplayer_div1',
      '425',
      '344',
      '8',
      null,
      null,
      {
        allowScriptAccess: 'always',
        allowFullScreen: 'true'
      },
      {
        id: 'ytplayer_object'
      }
    );
  }
  function ytplayer_render_playlist( )
  {
    for ( var i = 0; i < ytplayer_playlist.length; i++ )
    {
      var img = document.createElement( "img" );
      img.src = "http://img.youtube.com/vi/" + ID + "/default.jpg";
      var a = document.createElement( "a" );
      a.href = "#ytplayer";
      //
      // Thanks to some nice people who answered this question:
      // http://stackoverflow.com/questions/1552941/variables-in-anonymous-functions-can-someone-explain-the-following
      //
      a.onclick = (
        function( j )
        {
          return function( )
          {
            ytplayer_playitem = j;
            ytplayer_playlazy( 1000 );
          };
        }
      )( counter );
      a.appendChild( img );
      document.getElementById( "ytplayer_div2" ).appendChild( a );
    }
  }
  function ytplayer_playlazy( delay )
  {
    //
    // Thanks to the anonymous person posted this tip:
    // http://www.tipstrs.com/tip/1084/Static-variables-in-Javascript
    //
    if ( typeof ytplayer_playlazy.timeoutid != 'undefined' )
    {
      window.clearTimeout( ytplayer_playlazy.timeoutid );
    }
    ytplayer_playlazy.timeoutid = window.setTimeout( ytplayer_play, delay );
  }
  function ytplayer_play( )
  {
    var o = document.getElementById( 'ytplayer_object' );
    if ( o )
    {
      o.loadVideoById( ytplayer_playlist[ ytplayer_playitem ] );
    }
  }
  //
  // Ready Handler (this function is called automatically by YouTube JavaScript Player when it is ready)
  // * Sets up handler for other events
  //
  function onYouTubePlayerReady( playerid )
  {
    var o = document.getElementById( 'ytplayer_object' );
    if ( o )
    {
      o.addEventListener( "onStateChange", "ytplayer_statechange" );
      o.addEventListener( "onError", "ytplayer_error" );
	  o.addEventListener( "onPlay", "ytplayer_start" );
    }
  }
  //
  // State Change Handler
  // * Sets up the video index variable
  // * Calls the lazy play function
  //

  var oldfoon = "list0";
  var foon = "list0";
  var oldb = false;
  function ytplayer_statechange( state )
  {
    if ( state == 0 )
    {
      ytplayer_playitem += 1;
      ytplayer_playitem %= ytplayer_playlist.length;
      ytplayer_playlazy( 2000 );
    }
	else if ( state == 3 )
    {
		if(!oldb) oldb = document.getElementById(oldfoon).style.background;
		old = document.getElementById(oldfoon);
		old.style.padding = "0";
		old.style.background = oldb;
		

	  foon = document.getElementById("list"+ytplayer_playitem);
	  document.getElementById("nowplaying").innerHTML = document.getElementById("img"+ytplayer_playitem).title;
	  
	  oldb = foon.style.backgroundColor;
	  document.getElementById("nowplaying").style.color = "#ffffff";
	  document.getElementById("nowplaying").style.backgroundColor = oldb;
	  foon.style.padding = "0 0 8px 0";
	  
	  oldfoon = "list"+ytplayer_playitem;
	  
	  
    }

  } 
  //
  // Error Handler
  // * Sets up the video index variable
  // * Calls the lazy play function
  //
  function ytplayer_error( error )
  {
    if ( error )
    {
      ytplayer_playitem += 1;
      ytplayer_playitem %= ytplayer_playlist.length;
      ytplayer_playlazy( 2000 );
    }
  }




/* END MTH FUNCTIONS */
/**
 * 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;
};

ytvb.listVideo = function(rArray) {
clearTimeout(t);
searchTerm=rArray[counter];
//alert ('search term: ' + searchTerm);
page=1;
queryType = 'all';

  ytvb.previousSearchTerm = searchTerm; 
  ytvb.previousQueryType = queryType; 
  var queryUrl = ytvb.QUERY_URL_MAP[queryType];
  if (queryUrl) {
    queryUrl += '?max-results=' + ytvb.MAX_RESULTS_LIST +
        '&start-index=' + (((page - 1) * ytvb.MAX_RESULTS_LIST) + 1);
    if (searchTerm != '') {
      queryUrl += '&vq=' + searchTerm;
    }
	queryUrl += '&format=5';
	t=setTimeout("ytvb.advance()",1000);
    ytvb.appendScriptTag(queryUrl, 
                         'searchResultsVideoListScript', 
                         'ytvb.listVideoCallback');
    //ytvb.updateNavigation(page);
	
  } else {
    //alert('Unknown feed type specified');
	ytvb.advance();
  }
};
ytvb.advance = function() {
	counter = counter + 1;
	ytvb.listVideo(myRequests);
};
var fooText = '';
var booText = '';
var innercounter = 0;
ytvb.listVideoCallback = function(data) {
	clearTimeout(t);
	
  // Stores the json data returned for later lookup by entry index value
  ytvb.jsonFeed_ = data.feed;
  //alert(data.feed.entry[0].id.$t);
  
  if(data.feed.entry) {
	var url = data.feed.entry[0].id.$t;
	var id = url.split('/videos/')[1];
  
	//alert (data.feed.entry[0].title.$t);//).appendTo("#ytplayer_div2").wrap("<p></p>");
	
      var img = document.createElement( "img" );
	  var titl = document.createTextNode( data.feed.entry[0].title.$t );
	  
      img.src = "http://img.youtube.com/vi/" + id + "/default.jpg";
	  img.title = data.feed.entry[0].title.$t;
	  img.style.margin = "0 10px 0 0";
	  img.id = "img"+innercounter;
	  img.align = "left";
	  
	  
	  img.width = "80";
	  img.height = "60";
	        
	  var li = document.createElement( "li");
	  li.id = "list"+innercounter;
	  li.style.background = "#"+Math.round(0xffffff * (1 - .13 * Math.random())).toString(16);
	  var a =  document.createElement( "a");
      a.href = "#ytplayer";
      //
      // Thanks to some nice people who answered this question:
      // http://stackoverflow.com/questions/1552941/variables-in-anonymous-functions-can-someone-explain-the-following
      //
      a.onclick = (
        function( j )
        {
          return function( )
          {
            ytplayer_playitem = j;
            ytplayer_playlazy( 1000 );
          };
        }
      )( innercounter );
      a.appendChild( img );
	  a.appendChild( titl );
	  li.appendChild( a );
      document.getElementById( "ytplayer_div2" ).appendChild( li );
	  document.getElementById( "ytplayer_div1" ).innerHTML = '<br><br><br><br><br><br><br><strong>Loading playlist...</strong><br/><small>'+data.feed.entry[0].title.$t+'</small>';
    
	
	
	
	
	if(booText=='') booText = id;
	else if(fooText=='') fooText = id;
	else fooText = fooText + (',' + id);
  
  //myResults.push(data.feed.entry[0].id.$t);
  //foodiv = document.getElementById("player");
  //foodiv.innerHTML = '<object><param name="movie" 
	ytplayer_playlist.push( id ); //function in 
	innercounter = innercounter + 1;
  }
  counter = counter + 1;
  if (counter < myRequests.length) ytvb.listVideo(myRequests);
  else {
  //shouldn't need to do anything here..
  //foodiv = document.getElementById("player");
  //foodiv.innerHTML = '<object><param name="movie" value="http://www.youtube.com/v/'+booText+'?version=3&autoplay=1&playlist='+fooText+'&feature=player_embedded&showinfo=1"><param name="allowFullScreen" value="true"><param name="allowScriptAccess" value="always"><embed src="http://www.youtube.com/v/'+booText+'?version=3&autoplay=1&playlist='+fooText+'&feature=player_embedded&showinfo=1" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="425" height="344"></object>';
  }
};

