function sendRequest(uri) {
  if(uri.indexOf('/videoswv?') == 0) {
    sendAjaxRequest(uri, handleSWVResponse);
    resetSWVMessages();
    showMatchesDiv();
    ele('matchedsegs').innerHTML = 
      "<font size=-1>" + MSG_SEARCHING + "<br>&nbsp;</font>";
  } else if (uri.indexOf('/videorelated?') == 0) {
    sendAjaxRequest(uri, handleRelatedResponse);
    switchActiveDiv('relatedvids', false);  // show 'Searching...' message
  } else if (uri.indexOf('/videomorefrom?') == 0) {
    sendAjaxRequest(uri, handleMoreFromResponse);
    switchActiveDiv('morefromvids', false); // show 'Searching...' message
  } else if (uri.indexOf('/videoplaylistnext?') == 0) {
    sendAjaxRequest(uri, handlePlaylistNextResponse);
    switchActiveDiv('next10', false); // show 'Retrieving...' message
  } else if (uri.indexOf('/videostats?' == 0)) {
    sendAjaxRequest(uri, handleStatsResponse);
  } else {
    return;
  }
}

function sendPlaylistNextRequest() {
  if (VP_next10DocId == "0") {
    switchActiveDiv('next10link', false); // should have been disabled...
    return; 
  }
  var currentDoc = window.location;
  var shortPlaylist = "";
  var playlistArray = VP_myPlaylist.split(",");
  if (playlistArray.length > 91) {
    // avoid MSIE's AJAX send-length limitation by choosing subset of playlist
    var arrLen = playlistArray.length;
    var curPos = -1;
    for (var i = 0; i < arrLen; i++) {
      if (currentDoc == playlistArray[i]) {
        curPos = i;
        break;
      }
    }
    var start = Math.max(0, curPos - 40);
    var end = Math.min(arrLen, start + 90);
    shortPlaylist = playlistArray.splice(start, end - start).join(",");
  } else {
    shortPlaylist = VP_myPlaylist;
  }
  var finalUri = '/videoplaylistnext?docid=' + VP_next10DocId + '&num=10&q=' +
                 shortPlaylist + 'n' + currentDoc;
  sendRequest(getNoCacheURL(finalUri));
}

function sendPlaylistPrevRequest(docid) {
  var currentDoc = window.location;
  var finalUri = '/videoplaylistnext?docid=' + docid + '&num=10&q=' +
                 VP_myPlaylist + 'p' + currentDoc;
  sendRequest(getNoCacheURL(finalUri));
}

function handleSWVResponse(req) {
  if (req.readyState == 4) {
    var resp = req.responseText;
    var matchedsegs = ele('matchedsegs');
    var sHTML = "<br>";
    var lineArr = resp.split("\r\n");
    var eleArr;
    var query = lineArr[0];
    if (lineArr[1] == "0") {
      sHTML += "<font size=-1>" + 
               MSG_YOUR_SEARCH_0_DID_NOT_MATCH.replace(/%0/, 
                                 "<b>" + query + "</b>") +
               "</font>";
    } else {
      ele('nummatches').innerHTML = "<b>" + lineArr[1] + "</b> ";
      if (lineArr[1] > 1) {
        ele('nummatches').innerHTML += MSG_MATCHES + "&nbsp;";
      } else {
	ele('nummatches').innerHTML += MSG_MATCH + "&nbsp;";
      }
      for (var i = 2; i < lineArr.length - 1; i++) {
        eleArr = lineArr[i].split("\t");
        sHTML += "<div class='playresultimage' id='seg" + i +
                 "'><a href='javascript:void(0)' onclick='vpseek(" +
                 eleArr[0] + ")'><img src='" + eleArr[1] +
                 "' alt=''></a></div>" +
                 "<div class='playresulttext'>" +
                 "  <div class='playsectiontranscript'>" + eleArr[2] +
                 "</div><div class='timestamp'>" + eleArr[3] + "</div>" +
                 "</div>";
      }
    }
    matchedsegs.innerHTML = sHTML;
  }
}

function handleRelatedResponse (req) {
  if (req.readyState == 4) {
    outputGrid('relatedvidsactive', req.responseText)
    switchActiveDiv('relatedvids', true); // hide message, show results
  }
}

function handleMoreFromResponse (req) {
  if (req.readyState == 4) {
    outputGrid('morefromvidsactive', req.responseText)
    switchActiveDiv('morefromvids', true); // hide message, show results
  }
}

function handlePlaylistNextResponse(req) {
  if (req.readyState == 4) {
    updatePlaylist(req.responseText);
    switchActiveDiv('next10', true); // hide message, show playlist
  }
}

function handleStatsResponse() {
  return;
}

/* Decorate playlist controls based on cookie settings */
function applyPlaylistSettings() {
  readSettingsFromCookie();
  refreshAutoplayLinks();
  refreshDescription();
  refreshVisibleTab();
  setPlaylistValid(false);
}

function readSettingsFromCookie() {
  // read settings from cookie if they are defined
  // needed for correctness after page refresh on IE
  var plSettings = getCookie(VP_playlistSettingsCookieName);
  if (!plSettings) { // cookie is not set yet
    savePlaylistSettings(); // store the values provided by the server
  } else {
    // read 'autoplayEnabled'
    if (plSettings.charAt(0) == '1') {
      VP_autoplayEnabled = true;
    } else {
      VP_autoplayEnabled = false;
    }
    // read 'collapseDescr'
    if (plSettings.charAt(1) == '0') {
      VP_collapseDescr = false;
    } else {
      VP_collapseDescr = true;
    }
    // read 'visibleTab'
    VP_visibleTab = plSettings.charAt(2);
  }
}

function refreshDescription() {
  if (ele('collapselink')) { // collapse/expand links are present
    if (VP_collapseDescr) {
      ele('collapselink').onclick();
    } else {
      ele('expandlink').onclick();
    }
  }
}

function refreshVisibleTab() {
  if (VP_visibleTab == 'd') {
    ele("ldetails").onclick();
  } else if (VP_visibleTab == 'm') {
    ele("lmorefrom").onclick();
  } else if (VP_visibleTab == 'r') {
    ele("lrelated").onclick();
  } else if (VP_visibleTab == 'c' && ele("lcomments")) {
    ele("lcomments").onclick();
  } else { // default is playlist
    VP_visibleTab = 'p';
    ele("lupnext").onclick();
  }
}

/* Set my playlist values in the cookie */
function setMyPlaylist() {
  setSessionCookie(VP_playlistCookieName,
                   VP_myPlaylist,
                   VP_cookieDomain);
  setSessionCookie(VP_playlistIndexCookieName,
                   VP_myPlaylistIndex,
                   VP_cookieDomain);
  // Play request is generated at play page, set playlistValid to true
  setPlaylistValid(true);
  savePlaylistSettings();
}

/* Functions for saving playlist settings in the cookie */
function saveAutoplay(autoplay) {
  var plSettings = getCookie(VP_playlistSettingsCookieName);
  if (!plSettings) { // cookie is not set
    savePlaylistSettings(); // store current values
    return;
  }
  setPermanentCookie(VP_playlistSettingsCookieName,
                     ((autoplay ? "1" : "0" ) + plSettings.substring(1,3)),
                     VP_cookieDomain);
}

function saveCollapseDescr(collapse) {
  VP_collapseDescr = collapse;
  var plSettings = getCookie(VP_playlistSettingsCookieName);
  if (!plSettings) { // cookie is not set
    savePlaylistSettings(); // store current values
    return;
  }
  setPermanentCookie(VP_playlistSettingsCookieName,
                     (plSettings.charAt(0) + (collapse ? "1" : "0" ) +
          plSettings.charAt(2)),
                     VP_cookieDomain);
}

function saveVisibleTab(tabIndex) {
  VP_visibleTab = tabIndex;
  var plSettings = getCookie(VP_playlistSettingsCookieName);
  if (!plSettings) { // cookie is not set
    savePlaylistSettings(); // store current values
    return;
  }
  setPermanentCookie(VP_playlistSettingsCookieName,
                     (plSettings.substring(0,2) + tabIndex),
                     VP_cookieDomain);
}

function savePlaylistSettings() {
  setPermanentCookie(VP_playlistSettingsCookieName,
                     ((VP_autoplayEnabled ? "1" : "0") +
          (VP_collapseDescr ? "1" : "0") +
          VP_visibleTab),
                     VP_cookieDomain);
}

// sets playlistValid parameter to '0' (false) or '1' (true) in the cookie
function setPlaylistValid(isValid) {
  if (isValid) {
    setSessionCookie(VP_playlistParametersCookieName, "1", VP_cookieDomain);
  } else {
    setSessionCookie(VP_playlistParametersCookieName, "0", VP_cookieDomain);
  }
}

function getAutoplayFromCookie() {
  var plSettings = getCookie(VP_playlistSettingsCookieName);
  if (!plSettings) {  // not set in the cookie yet
    return VP_autoplayEnabled; // retun the value provided by server
  }
  if (plSettings.charAt(0) == '1') {
    return true;
  } else {
    return false;
  }
}

function flipAutoplay() {
  VP_autoplayEnabled = !VP_autoplayEnabled;
  saveAutoplay(VP_autoplayEnabled);
  refreshAutoplayLinks();
}

function refreshAutoplayLinks() {
  if (VP_autoplayEnabled) {
    ele('autoplayon').style.display = 'inline';
    ele('autoplayoff').style.display = 'none';
  } else {
    ele('autoplayon').style.display = 'none';
    ele('autoplayoff').style.display = 'inline';
  }
}

/* Update the playlist based on AJAX results

  The format of the response is as follows:
  - first line is the number of results, 
  - followed by playlist entries (one result on each line with a maximum 
      of 12 results: first result is the current video, next 10 are the 
      visible playlist entries, and the 12th result is the video following
      the last playlist result -needed for populating 'next 10' link), 
  - on next line is the docid of the prev video,
  - finally the new playlist on the last line.
  There is always an empty line at the end; so in a typical case with
  all 10 playlist entries present, the response will have 16 lines.
*/
function updatePlaylist(resp) {
  var lineArr = resp.split("\r\n");
  var currentDocId = window.location;
  
  if (lineArr[0] == "0") {
    // should never be empty! Disable all links
    disablePlaylistLinks();
    ele('upnextvids').innerHTML = ""; // no playlist 
    return;
  }

  // regenerate playlist HTML and show it in 'upnextvids' tab
  var plHTML = generatePlaylistHTML(lineArr, currentDocId); 
  ele('upnextvids').innerHTML = plHTML;
  ele('summary').scrollTop = 0;  // scroll to the top of the playlist

  // update prev/next/prev10/next10 links
  updatePlaylistLinks(lineArr, currentDocId);
}

// disables next/prev/next10 links
function disablePlaylistLinks() {
  switchActiveDiv('nextlink', false); // disable 'next video' link
  switchActiveDiv('prevlink', false); // disable 'prev video' link
  switchActiveDiv('next10link', false); // disable 'next 10 videos' link
}

// sets the visible div for div pairs
function switchActiveDiv(linkName, isActive) {
  if (isActive) { // show active div, hide inactive div
    ele(linkName + 'active').style.display = 'inline';
    ele(linkName + 'inactive').style.display = 'none';
  } else { // hide active div, show inactive div
    ele(linkName + 'active').style.display = 'none';
    ele(linkName + 'inactive').style.display = 'inline';
  }
}

// generates the HTML code for the playlist
function generatePlaylistHTML(responseArr, currentDocId) {
  var plHTML = '<table cellpadding="4" cellspacing="0" id="upnexttable"> ' +
    '<tbody> '; 
  // Playlist entries start at index 1 and goes until 'length - 4' 
  // (we have prevId, new_playlist, and empty line in last 3 entries.
  // There are at most 10 playlist entries (11 items including current),
  // so don't pass index 11 (exclude 'next10 docid' at index 12 if present)
  var playlistEnd = Math.min(responseArr.length - 4, 11);
  for (var i = 1; i <= playlistEnd; i++) {
    // Each playlist entry has various fields separated by '\t'
    var eleArr = responseArr[i].split("\t");
    plHTML +='<tr style="';
    if (eleArr[0] == currentDocId) {
      plHTML += 'background-color:#E1DAE1;';
    }
    plHTML += '">';
    plHTML += generatePlaylistEntryHTML(eleArr);
  }
  plHTML += '</tbody> </table>';
  return plHTML;
}

// generates HTML code for a playlist entry
function generatePlaylistEntryHTML(eleArr) {
  // thumbnail link
  var rowHTML = '<td> <a href="videoplay?docid=' + eleArr[0] + 
    VP_queryParam + VP_langParam +
    '" onclick="setMyPlaylist()">' + 
    '<img src="' + eleArr[1] + '" title="' + eleArr[3] +
    '" height="' + eleArr[5] + '" width="100" alt="" ' + 
    'border="1"> </a> </td>'; 
  // title link
  rowHTML += '<td class="playlistentry" valign="top"> ' +
    '<a href="videoplay?docid=' + eleArr[0] + 
    VP_queryParam + VP_langParam +
    '" onclick="setMyPlaylist()" ' +
    'title="' + eleArr[3] + '"> ' + eleArr[2] + '</a> <br> ';
  // provider
  rowHTML += '<span class="meta"> ';
  if (eleArr[6] != ".") { // server returns '.' if provider is invalid 
    rowHTML += eleArr[6] + ' <br> ';
  }
  rowHTML += eleArr[4] + ' </span> </td> </tr> ';
  return rowHTML;
}

function updatePlaylistLinks(lineArr, currentDocId) {
  // lineArr items that will be used here:
  //  [length-3]: Prev item that precedes current playlist
  //  [length-2]: new playlist
  //  last array item is empty string.
  //  [2]: Second item in playlist, which is the 'next video'
  //    (given that 'length > 5' because last 3 items are fixed)
  //  [12]: Next item that follows current playlist
  //    (given that 'length == 16' because last 3 items are 
  //     fixed and there are 11 items, [1-11], currently visible)
  var argLength = lineArr.length; 

  // update 'prev video' link
  var currentLine = argLength - 3; // Index for item preceeding playlist
  var prevDocId = lineArr[currentLine];
  if (prevDocId == "0") { // prev is null
    switchActiveDiv('prevlink', false); // disable 'prev video' link
  } else {
    ele('playlistPrev').href = '/videoplay?docid=' + prevDocId + 
      VP_queryParam + VP_langParam;
    switchActiveDiv('prevlink', true); // enable 'prev video' link
  }
  
  // update 'next video' link
  if (argLength > 5) { // playlist has at least 2 items
    currentLine = 2; // Index for second playlist item
    ele('playlistNext').href = '/videoplay?docid=' + 
      lineArr[currentLine].split("\t")[0] + VP_queryParam + VP_langParam;
    switchActiveDiv('nextlink', true); // enable 'next video' link
  } else { 
    switchActiveDiv('nextlink', false); // disable 'next video' link
  }

  // update 'next10 videos' link 
  if (argLength == 16) { // item following playlist exists
    currentLine = 12; // Index for item following playlist
    VP_next10DocId = lineArr[currentLine].split("\t")[0];
    switchActiveDiv('next10link', true); // enable 'next 10 videos' link
  } else {
    VP_next10DocId = "0";
    switchActiveDiv('next10link', false); // disable 'next 10 videos' link
  }
    
  // read new playlist and update local playlist values
  // (only if the original playlist is not fixed)
  if (!isFixedPlaylist(VP_myPlaylist)) {
    currentLine = argLength - 2; // Index for new playlist
    verifyNewPlaylist(lineArr[currentLine], currentDocId, prevDocId);
  }
}

// returns true if the last docid in the playlist is 0
function isFixedPlaylist(playlist) {
  if (playlist.length >= 4) {
    var lastZeroIndex = playlist.indexOf(",0", playlist.length - 4);
    if (lastZeroIndex >= 0) {
      return true;
    }
  }
  return false;
}

// Check if current and prev docids are in the playlist, 
//  add them to the beginning of the playlist if they are missing; 
//  update VP_myPlaylist and VP_myPlaylistIndex accordingly
function verifyNewPlaylist(newPlaylist, currentDocId, prevDocId) {
  var plArr = newPlaylist.split(",");
  var currentIndex = -1;
  var prevIndex = -1;
  var foundBoth = 0;
  if (prevDocId == 0) { // prev is null so not in the list anyway
    foundBoth++;
  }
  for (var i = 0; i < plArr.length; i++) {
    if (currentDocId == plArr[i]) {
      currentIndex = i;
      foundBoth++;
    } else if (prevDocId == plArr[i]) {
      prevIndex = i;
      foundBoth++;
    }
    if (foundBoth == 2) {
      break;
    }
  }

  var plUpdated = true;
  var newApi = currentIndex;
  if (foundBoth == 2) {
    plUpdated = false;
  }
  if (plUpdated) { // update playlist if current or previous docId is missing
    if (prevDocId != 0) { // prev is not null
      if (prevIndex < 0) { // prevDocId is missing
        plArr[0] = prevDocId; // add prev at the beginning
  prevIndex = 0;
  if (currentIndex <= 0) { // then add current
          plArr[1] = currentDocId;
    newApi = 1;
  }
      } else if (currentIndex < 0) { // currentDocId is missing
        if (prevIndex == 0) {
          plArr[1] = currentDocId;
    newApi = 1;
  } else {
          plArr[0] = currentDocId;
    newApi = 0;
  }
      }
    } else if (currentIndex < 0) { // prev is null, currentDocId is missing
      plArr[0] = currentDocId;
      newApi = 0;
    }
    newPlaylist = plArr.join(",");
  }
  VP_myPlaylist = newPlaylist;
  VP_myPlaylistIndex = newApi;
}

function outputGrid(divname, resp) {
  var sHTML = "";
  var lineArr = resp.split("\r\n");
  var eleArr;
  var plDocids = "";
  var plFirstDocid;
  if (lineArr[0] == "0") {
    sHTML += "<font size=-1>" + MSG_NO_MATCHING_VIDEOS + 
             "</font>"
  } else {
    // first construct playlist (Note that lineArr[0] is
    // skipped because it contains the number of results)
    for (var i = 1; i < lineArr.length - 1; i++) {
      eleArr = lineArr[i].split("\t");
      plDocids += eleArr[0] + ",";
    }
    
    // create the thumbnail table
    sHTML += "<table cellpadding=0 cellspacing=3>";
    for (var i = 1; i < lineArr.length - 1; i++) {
      eleArr = lineArr[i].split("\t");
      if (i % 2 == 1) {
        sHTML += "<tr>";
      }
      sHTML +=
        "<td align=center class='standardfont' valign=top>" +
        "<a href='/videoplay?docid=" + eleArr[0] + VP_langParam +
        "' onclick='" +
        "setSessionCookie(VP_playlistCookieName, \"" + plDocids +
        "\", VP_cookieDomain); " +
        "setSessionCookie(VP_playlistIndexCookieName, -1, " +
        "VP_cookieDomain);'>" +
        "<img border=1 height=" + eleArr[5] + " width=100 alt=''" +
        "title=\"" + eleArr[3] + "\" src='" + eleArr[1] +
        "'></a><br>" +
        "<a href='/videoplay?docid=" + eleArr[0] + VP_langParam +
        "' onclick='" +
        "setSessionCookie(VP_playlistCookieName, \"" + plDocids +
        "\", VP_cookieDomain); " +
        "setSessionCookie(VP_playlistIndexCookieName, -1, " +
        "VP_cookieDomain);' " +
        "title='" + eleArr[3] + "'>" + eleArr[2] + "</a><br>" +
        "<font color=green>" + eleArr[4] + "</font></td>";
      if (i == 1) {
        plFirstDocid = eleArr[0];
      }
      if (i % 2 == 0) {
        sHTML += "</tr>";
        sHTML += "<tr><td height=10></td></tr>";
      }
    }
    if (i % 2 == 0) {
      sHTML += "<td></td></tr>"
    }
    sHTML += "</table>";
  }
  ele(divname).innerHTML = sHTML;
}

function updateText(obj, cl, text) {
  obj.className = cl;
  obj.innerHTML = text;
}

function resetSWVMessages () {
  updateText(ele("matchedsegs"), "", "");
  updateText(ele("nummatches"), "", "");
}

function showMatchesDiv() {
  hideEle(ele('summary'));
  showEle(ele('matches'));
}

function vpsearchthisshow(thequery) {
  var thedocid = window.location;
  sendRequest("/videoswv?docid=" + thedocid +
     "&q=" + prepareSearchParams(thequery));
  return false;
}

function vpsearch(query, allVideos, hasTranscript) {
  if (allVideos) {
    return pvsearch(query);
  } else if (hasTranscript) {
    return vpsearchthisshow(query);
  } else {
    showMatchesDiv();
    return false;
  }
}

function vpseek(time) {
  var movie = ele("VideoPlayback");
  movie.SetVariable("seekTime", time/1000);
}

function getFullScreenWindowParams() {
  return "toolbar=no"
    + ",status=no"
    + ",resizable=yes"
    + ",scrollbars=0";
  /*
    + ",width=" + screen.availWidth
    + ",height=" + screen.availHeight
    + ",fullscreen=yes"
  */
}

function goFullscreen(videoPath, time, state) {
  var timeRegex = new RegExp("&begin=[0-9]+", "i");
  var newVideoUrl = videoPath.replace(
                      timeRegex, "&begin=" + Math.floor(time * 1000));
  var w = window.open(
          "http://" + window.location.host + '/videopopup?q='
           + prepareSearchParams(newVideoUrl)
           + "&windowtitle="
           + prepareSearchParams(window.document.title + " - " 
                                 + MSG_FULL_SCREEN),
           "GoogleVideo", getFullScreenWindowParams());
  w.focus();
}

function expand() {
  window.moveTo(0,0);
  window.resizeTo(screen.availWidth, screen.availHeight);
}

function removeScrollBars() {
  document.body.scroll = 'no';
}

function getNoCacheURL(url) {
  return url + "&ms=" + new Date().getTime();
}

function donePlaying() {
  if (!VP_autoplayEnabled) {
    return;
  }
  playbackSegmentEnded("finished");
  VP_userTouchedSomething = false;
  if (VP_waitForSale) {  // pause 10 seconds for purchasable videos
    setTimeout(startNextVideo, 10000);
  } else { // go to next video after 5 seconds
    setTimeout(startNextVideo, 5000);
  }
}

function startNextVideo() {
  // don't go to next video in any of these cases.
  if (!VP_autoplayEnabled || VP_userTouchedSomething ||
      isVisible("send") || isVisible("embed") ||
      isVisible("videopurchasediv") ||
      ele("playlistNext").href == null) {
    return;
  }
  // start playing next video...
  setMyPlaylist();
  window.location.href = ele("playlistNext").href + "&auto=true";
}

function isVisible(elementId) {
  return ele(elementId).style.display == "";
}

// set of links on the right side of the videoplay page
var VP_linksArray = [ "upnext", "details", "morefrom", "related", "comments" ];
  
// renders the links and tabs based on the selected tab id
function switchTab(linkId) {
  for (var i = 0; i < VP_linksArray.length; i++) {
    var el = ele(VP_linksArray[i]);
    if (el) {
      if (linkId == VP_linksArray[i]) { // this is selected link and visible tab
        ele("l" + VP_linksArray[i]).className = "nodecoration";
        showEle(el);
      } else { // make this link unselected and hide associated tab
        ele("l" + VP_linksArray[i]).className = "decorated";
        hideEle(el);
      }
    }
  }
}


var VP_windowHeight;
var VP_usableHeight;
var VP_cornerHeight;
var VP_flashPlayerHeight;
var VP_extraHeight1 = 2; // was 16
var VP_extraHeight2 = 19;

function setStyleHeightPx(id, heightPx) {
  setStyleHeightSuffix(id, heightPx, "px");
}

function setStyleHeightSuffix(id, height, suffix) {
  el =  ele(id);
  if(el === null || el.style == null) {
    return;
  }
  var heightString = height.toString() + suffix;
  el.style.height = heightString;
}

function onWindowResize() {
  if (!(VP_windowHeight = window.innerHeight)) {
    if (!(VP_windowHeight = document.documentElement.clientHeight)) {
      VP_windowHeight = document.body.clientHeight;
    }
  }

  VP_usableHeight = VP_windowHeight - ele("playvideoblock").offsetTop;
  VP_flashPlayerHeight = VP_usableHeight - ele("flashobjectplaceholder").offsetTop;

  setStyleHeightPx("playvideoblock", VP_usableHeight);
  setStyleHeightPx("flashobjectplaceholder", VP_flashPlayerHeight);
  setStyleHeightPx("playrightblock", VP_usableHeight);
  setStyleHeightPx("summary", VP_usableHeight - VP_extraHeight1);
  setStyleHeightPx("matches", VP_usableHeight - VP_extraHeight1);

  VP_cornerHeight =
    VP_usableHeight - ele("abovecorner").offsetHeight - VP_extraHeight2;

  setStyleHeightPx("corner", VP_cornerHeight);

  if (this['onWindowResizeExtra']) {
    onWindowResizeExtra();
  }
}

function insertHtmlInEle(newHtml, eleName) {
  var newEle = document.createElement('div');
  ele(eleName).appendChild(newEle);
  newEle.innerHTML = newHtml;
}

var VP_playbackSegmentStartTimeOffset = 0;
var VP_playbackSegmentStartTimeStampMillis = 0;
var VP_playState = "paused";
var VP_userTouchedSomething = false;

function stateChanged(oldState, newState, timeOffset) {
  if (VP_playState != oldState) {
    sendRequest(getNoCacheURL("/videostats?error=BADSTATE&os=" + oldState + "&ns=" + newState + "&ps=" + VP_playState));
  }
  if (oldState == "playing") {
    playbackSegmentEnded(newState);
  } else {
    VP_userTouchedSomething = true;
    if (newState == "playing") {
      playbackSegmentStarted(timeOffset);
    }
  }
  VP_playState = newState;
}

function beginScrub(timeOffset) {
  VP_userTouchedSomething = true;
  if (VP_playState == "playing") {
    playbackSegmentEnded("scrub");
  }
}

function endScrub(timeOffset) {
  VP_userTouchedSomething = true;
}

function playbackSegmentStarted(timeOffset) {
  VP_playbackSegmentStartTimeOffset = timeOffset;
  var thedate = new Date();
  VP_playbackSegmentStartTimeStampMillis = thedate.getTime();
}

function playbackSegmentEnded(endEvent) {
  if (VP_playbackSegmentStartTimeOffset == -1) {
    return;
  }
  var thedate = new Date();
  var segDuration =
    (thedate.getTime() - VP_playbackSegmentStartTimeStampMillis) / 1000;
  var endTimeOffset = VP_playbackSegmentStartTimeOffset + segDuration;
  var thedocid = window.location;
  VP_playbackSegmentStartTimeOffset = -1;
}

function onUnloadPlaybackSegmentEnded() {
  if (VP_playState == "playing") {
    playbackSegmentEnded("unload");
  }
}

function monitorDivOffset() {
  var el = ele('playvideoblock');
  if (el) {
    if (VP_divOffset != el.offsetTop || el.clientHeight < el.scrollHeight) {
      VP_divOffset = el.offsetTop;
      onWindowResize();
    }
  }
}

// properly sets inut boxes when visited
function massageReviewInput(input,value) {
  if (typeof value == 'string') {
    input.value = value;
  }
  input.style.color = 'black';
  input.style.fontStyle = 'normal';
  input.onfocus = null;
}

// sends a review (if review is defined) and receives a list of current reviews
function updateReviews(url, docId, sortByRating, loc, reviewer, review) {
  var doc = getXmlDocument();
  var root = appendElement(doc, doc, "review"); 
  appendElement(doc, root, "docid", docId); 

  if (review) {
    appendElement(doc, root, "name", reviewer ? reviewer : "");
    appendElement(doc, root, "text", review);
  } else {
    ele('commentlist').innerHTML = '';
    ele('gettingreviews').innerHTML = MSG_GETTING_REVIEWS;
    showEle(ele('gettingreviews'));
  }
  
  appendElement(doc, root, "sort", (sortByRating ? "rating" : "date"));
  sendAjaxRequest(url, handleReviewResponse, doc, loc, 
    'text/xml; charset="utf-8"');
}

// sends a tag (if name is defined) and receives a list of current tags
function updateTags(url, docId, name) {

  var doc = getXmlDocument();
  var root = appendElement(doc, doc, "tags");
  appendElement(doc, root, "docid", docId);

  if (name) {
    appendElement(doc, root, "name", name);
  }
  sendAjaxRequest(url, handleTagResponse, doc, null, 'text/xml; charset="utf-8"');
}

// called when AJAX returns
function handleReviewResponse(req, success, url, odata, loc) {
  var errObj;
  var dontEnable = false;
  var scrollDiv = ele('summary');

  ele('gettingreviews').innerHTML = '';
  hideEle(ele('gettingreviews'));
  ele('reviewpublishstatus_top').innerHTML = '';
  ele('reviewpublishstatus_bottom').innerHTML = '';
  
  // default error object
  if (!loc || (loc != 'top' && loc != 'bottom')) {
    errObj = ele('commentlist');
  } else {
    errObj = ele('reviewpublisherror_' + loc);
  }
     
  if (!success || !req.responseXML) {
    showReviewError(errObj, MSG_REVIEW_PUBLISH_ERROR, loc);
  } else {
    var root = req.responseXML.documentElement;
    
    // error reply
    if (root.tagName == 'error') {
      var source = 'errorin';
      source += getElementValue(root, 'errorsource');
      source += '_'+loc;
      var msg = getElementValue(root, 'errormessage');
      var temp = ele(source);
      if (temp) {
        errObj = temp;
      }
      showReviewError(errObj, msg, loc);
    } else if (root.tagName != 'reviews') {
      showReviewError(errObj, 'Unknown error', loc);
    } else {
      // success: construct HTML
      var html = '';
      errObj = null;

      var reviewList = root.getElementsByTagName('review');
      var i;
      for (i = 0; i < reviewList.length; i++) {
        var review = reviewList.item(i);
        html += '<div style="margin:2px 0pt .5em;"><font size="-1"><b>';
        html += getElementValue(review, 'name');
        html += '</b><br>';
        var stars = getElementValue(review, 'rating');
        if (stars && stars > 0) {
          html += createStarsHtml(stars, stars != null);
          html += '&nbsp;';
        }
        html += '<font color=green>';
        html += getElementValue(review, 'textdate');
        html += '</font><br>';

        html += getElementValue(review, 'text');

        html += '</font></div>';

      }
      ele('commentlist').innerHTML = html;

      // handle allowed.value
      if (getElementValue(root, 'value') != 'true') {
        var reason = getElementValue(root, 'reason');
        ele('reviewpublisherror_top').innerHTML = reason;
        ele('reviewpublisherror_bottom').innerHTML = reason;
        showEle(ele('reviewpublisherror_top'));
        showEle(ele('reviewpublisherror_bottom'));
        ele('publishreview_top').disabled = true;
        ele('publishreview_bottom').disabled = true;
        dontEnable = true;
      } else {
        hideEle(ele('reviewpublisherror_top'));
        hideEle(ele('reviewpublisherror_bottom'));
        if (loc == 'top') {
          ele('publishreview_bottom').disabled = false;
        } else {
          ele('publishreview_top').disabled = false;
        }
      }
      
      // show/hide applicable divs
      hideEle(ele('leavecomment_top'));
      hideEle(ele('topreviewshown'));
      showEle(ele('topreviewhidden'));
      showEle(ele('commentlist'));
      if (reviewList.length == 0) {
        showEle(ele('nocomments'));
        hideEle(ele('sortit'));
      } else {
        hideEle(ele('nocomments'));
        showEle(ele('sortit'));
      }
      
      // disbale onfocus and copy name to unused form
      if (loc == 'top') {
        ele('reviewtext_top').value = '';
        massageReviewInput(ele('reviewtext_bottom'), '');
        massageReviewInput(ele('reviewername_bottom'), 
          ele('reviewername_top').value);
      } else if (loc == 'bottom') {
        ele('reviewtext_bottom').value = '';
        massageReviewInput(ele('reviewtext_top'), '');
        massageReviewInput(ele('reviewername_top'), 
          ele('reviewername_bottom').value);
        scrollDiv.scrollTop = 0;
      }
    }
  }
  
  // if long output -> enable top review form
  var bottomWidget = ele('leavecomment_bottom');
  showEle(bottomWidget);
  showEle(ele('reviewboxandtext_bottom'));
  showEle(ele('reviewblankdiv'));
  if (scrollDiv.scrollHeight - bottomWidget.scrollHeight > 
      scrollDiv.clientHeight) {
    showEle(ele('reviewboxandtext_top'));
    hideEle(ele('reviewblankdiv'));
  } else {
    hideEle(ele('reviewboxandtext_top'));
    showEle(ele('reviewblankdiv'));
  }

  // enable button  
  if (!dontEnable) {
    ele('publishreview_' + loc).disabled = false;
  }
}


// called when AJAX returns
function handleTagResponse(req, success, url, odata, oid) {
  var errObj;

  // default error object
  errObj = ele('tag_error');
  errObj.innerHtml = "";
  errObj.style.display = "none";

  if (!success || !req.responseXML) {
    errObj.innerHTML = MSG_UNKNOWN_ERROR;
  } else {
    var root = req.responseXML.documentElement;

    // error reply
    if (root.tagName == 'error') {
      var msg = getElementValue(root, 'errormessage');
      errObj.innerHTML = msg;
    } else if (root.tagName != 'tags') {
      errObj.innerHTML = MSG_UNKNOWN_ERROR; 
    } else {
      // success: construct HTML
      var html = '';
      errObj.value="";
      errObj = null;

      var tagList = root.getElementsByTagName('common_tag');
      var i;
      if (tagList.length > 0) {
        html += MSG_BROWSE + " ";
      }
      for (i = 0; i < tagList.length; i++) {
        var tag = tagList.item(i);
        if (i != 0) {
          html += ", ";
        }
        html += "<a class='taglink' title=\"";
        html += getElementValue(tag, 'name');
        html += "\" href=\"/videosearch?q="
        html += "label:" + encodeURIComponent(getElementValue(tag, 'raw_name'));
        html += "\"><nobr>";
        html += getElementValue(tag, 'name');
        html += "</nobr></a>"
      }
      if(tagList.length > 3) {
        html += ", <a class='taglink' href='javascript:void(0)' onclick='discloseTags(\"common_tags\", \"false\");'>"
        html += "&laquo;</a>"
      }
      ele('common_tags_all').innerHTML = html;

      var html2 = '';
      if (tagList.length > 0) {
        html2 += MSG_BROWSE + " ";
      }
      for (i = 0; i < tagList.length && i< 3; i++) {
        var tag = tagList.item(i);
        if (i != 0) {
          html2 += ", ";
        }
        html2 += "<a class='taglink'  title=\"";
        html2 += getElementValue(tag, 'name');
        html2 += "\" href=\"/videosearch?q="
        html2 += "label:" + encodeURIComponent(getElementValue(tag, 'raw_name'));
        html2 += "\"><nobr>";
        html2 += getElementValue(tag, 'name');
        html2 += "</nobr></a>"
      }
      if (tagList.length > 3) {
        html2 += ", <a class='taglink' href='javascript:void(0)' onclick='discloseTags(\"common_tags\", \"true\");'>"
        html2 += MSG_MORE_TAGS + " &raquo;</a>"
      }
      ele('common_tags_short').innerHTML = html2;
      var tag_display = ele('common_tags');
      if (tag_display) {
        if(tag_display.TAG_DISCLOSURE &&
            tag_display.TAG_DISCLOSURE == "true") {
          tag_display.innerHTML = html;
        } else {
          tag_display.innerHTML = html2;
          tag_display.TAG_DISCLOSURE = "false";
        }
      }

      if (ele('taginput').value != MSG_ADD_LABEL) {
        ele('tag_error').innerHTML = MSG_ANNOTATION_SAVED;
        ele('tag_error').style.display = "inline";
        setTimeout("concealTagInfo()", 5000);
        ele('taginput').value = "";
      }
    }
  }
  if(errObj) {
    errObj.style.color = "#ff0000";
    errObj.style.display ="block";
  }
}

// shows review error and scroll
function showReviewError(errObj, msg, optLoc) {
  errObj.innerHTML = msg;
  showEle(errObj);
  if (optLoc) {
    var scrollDiv = ele('summary');
    if (optLoc != 'bottom') {
      scrollDiv.scrollTop = 0;
    } else {
      scrollDiv.scrollTop = scrollDiv.scrollHeight - scrollDiv.clientHeight;
   }
  }
}

function concealTagInfo() {
  ele('tag_error').style.display = "none";
}

// called when submit review is clicked
function publishComment(url, docId, loc, name, review) {
  var errObj = ele('reviewpublisherror_' + loc);
  if (review && review.length > 0) {
    review = review.replace(/(^\s+)|(\s+$)/g, '').replace(/ {2,}/g, ' ');
  }
  if (!review || review.length == 0 || 
    ele('reviewtext_' + loc).style.color != 'black') {
    showReviewError(errObj, MSG_EMPTY_REVIEW, loc);
    return;
  }
  if (review.length > 512) {
    showReviewError(errObj, MSG_REVIEW_TOO_LONG, loc);
    return;
  }
  if (name && name.length > 60) {
    showReviewError(errObj, MSG_NAME_TOO_LONG, loc);
    return;
  }
  ele('publishreview_' + loc).disabled = true;
  
  var input = ele('reviewername_' + loc);
  if (input.style.color != 'black') {
    massageReviewInput(input, '');
    name = '';
  } else {
    name = name.replace(/(^\s+)|(\s+$)/g, '');
    input.value = name;
  }
  hideEle(ele("reviewpublisherror_" + loc));
  hideEle(ele("errorinname_" + loc));
  ele('reviewpublishstatus_' + loc).innerHTML = MSG_ANNOTATION_SAVING;
  updateReviews(url, docId, isVisible("commentsbyrating"), loc, name, review);
}


// called when submit tag is clicked
function publishTag(url, docId, input) {
 var errObj = ele('tag_error');
 hideEle(errObj);

  if (!input || input.length == 0 ||
      ele('taginput').style.color != 'black') {
    errObj.innerHTML = MSG_ERROR_TAG_MISSING;
    errObj.style.color = "#ff0000";
    showEle(errObj);
    return;
  }

  if (input.length > 50) {
    errObj.innerHTML = MSG_ERROR_TAG_TOO_LONG;
    errObj.style.color = "#ff0000";
    showEle(errObj);
    return;
  }
  errObj.innerHTML = MSG_ANNOTATION_SAVING;
  errObj.style.color="#000000";
  showEle(errObj);

  input = input.replace(/(^\s+)|(\s+$)/g, '')

  updateTags(url, docId, input);
}

function discloseTags(fieldName, disclose) {
  var tagField = ele(fieldName);
  var longField = ele(fieldName + "_all");
  var shortField = ele(fieldName +"_short");

  if (disclose == "true") {
    tagField.innerHTML = longField.innerHTML;
    tagField.TAG_DISCLOSURE = "true";
  } else {
    tagField.innerHTML = shortField.innerHTML;
    tagField.TAG_DISCLOSURE = "false"
  }
}

function handleSharePanelClick() {
  var thedocid = window.location;

  if (isVisible('sharelinks')) {
    hideEle(ele('sharelinks'));
    hideEle(ele('send'));
    hideEle(ele('embed'));
    sendRequest(getNoCacheURL("/videostats?shareclick=close&docid=" + thedocid + "&frame=share&ps=" + VP_playState));
  } else {
    showEle(ele('sharelinks'));
	handleSendEmailLinkClick();
    sendRequest(getNoCacheURL("/videostats?shareclick=open&docid=" + thedocid + "&frame=share&ps=" + VP_playState));
  }
}

function handleSendEmailLinkClick() {
  var thedocid = window.location;

  ele('lsend').className = 'nodecoration';
  ele('lembed').className = 'decorated';
  hideEle(ele('embed'));
  showEle(ele('send'));
  ele('sendform').from.focus();
  sendRequest(getNoCacheURL("/videostats?shareclick=send&docid=" + thedocid + "&frame=share&ps=" + VP_playState));
}

function handleEmbedHTMLClick() {
  var thedocid = window.location;

  ele('lembed').className = 'nodecoration';
  ele('lsend').className = 'decorated';
  hideEle(ele('send'));
  showEle(ele('embed'));
  sendRequest(getNoCacheURL("/videostats?shareclick=embed&docid=" + thedocid + "&frame=share&ps=" + VP_playState));
}

var rated = false;
var newRating = -1;

// TODO(katerina): clean up
function setStars(url, docId, val, location) {
  ele("rating_info_" + location).style.display = "inline";
  if (location == 'top') {
    // need to conceal community rating
    ele('communityRating').style.display = "none";
  }
  ele("rating_info_" + location).innerHTML = MSG_ANNOTATION_SAVING;
  rated = true; 
  submitRating(url, docId, val, location);
 }

function overStars(rating, location, realRating, cell) {
  rated = false;
  cell.style.cursor='pointer';
  ele("rating_info_" + location).style.display = "inline";
  if (location == 'top') {
    // need to conceal community rating
    ele('communityRating').style.display = "none";
  }

  ele('1_' + location).src = 'images/st_pe_off_l_lg.gif';	
  ele('2_' + location).src = 'images/st_pe_off_m_lg.gif';	
  ele('3_' + location).src = 'images/st_pe_off_m_lg.gif';	
  ele('4_' + location).src = 'images/st_pe_off_m_lg.gif';	
  ele('5_' + location).src = 'images/st_pe_off_r_lg.gif';	

  if (rating >= 1) {
    ele('1_' + location).src = 'images/st_pe_on_l_lg.gif';	
    if (location == 'top') {
      ele('rating_info_' + location).innerHTML = MSG_RATING_POOR;
    } else {
      ele('rating_info_' + location).innerHTML = MSG_RATING_POOR_SHORT;	
    }
  }
  if (rating >= 2) {
    ele('2_' + location).src = 'images/st_pe_on_m_lg.gif';	
    if (location == 'top') {
      ele('rating_info_' + location).innerHTML = MSG_RATING_BELOW_AVERAGE;	
    } else {
      ele('rating_info_' + location).innerHTML = MSG_RATING_BELOW_AVERAGE_SHORT;	
    }
  }  
  if (rating >= 3) {
    ele('3_' + location).src = 'images/st_pe_on_m_lg.gif';
    if (location == 'top') {
      ele('rating_info_' + location).innerHTML = MSG_RATING_AVERAGE;
    } else {
      ele('rating_info_' + location).innerHTML = MSG_RATING_AVERAGE_SHORT;	
    }	
  } 
  if (rating >= 4) {
    ele('4_' + location).src = 'images/st_pe_on_m_lg.gif';	
    if (location == 'top') {
      ele('rating_info_' + location).innerHTML = MSG_RATING_ABOVE_AVERAGE;	
    } else {
      ele('rating_info_' + location).innerHTML = MSG_RATING_ABOVE_AVERAGE_SHORT;	
    }
  } 
  if (rating >= 5) {
    ele('5_' + location).src = 'images/st_pe_on_r_lg.gif';	
    if (location == 'top') {
      ele('rating_info_' + location).innerHTML = MSG_RATING_EXCELLENT;
    } else {
      ele('rating_info_' + location).innerHTML = MSG_RATING_EXCELLENT_SHORT;	
    }	
  } 
}

function outStars(rating, location, realRating, cell) {
  cell.style.cursor='default';
  if (!rated) {
    ele('communityRating').style.display = "inline";
    if (newRating == -1) {
      setStarsToValueInLocation(realRating, location);
    } else { 
      setStarsToValueInLocation(newRating, location);
    }
  }
}

function submitRating(url, docId, rating, location) {
  var doc = getXmlDocument();
  var root = appendElement(doc, doc, "rating"); 
  appendElement(doc, root, "docid", docId); 
  appendElement(doc, root, "user_rating", rating);

  sendAjaxRequest(url, handleRatingResponse, doc, location, 'text/xml; charset="utf-8"');	
}

function handleRatingResponse(req, success, url, odata, loc) {   
  ele("rating_info_" + loc).style.display = "none";
  ele('communityRating').style.display = "inline";
  ele("rating_info_" + loc).innerHTML = "";

  var errObj;
  errObj = ele('rating_error_' + loc);
     
  if (!success || !req.responseXML) {
    errObj.innerHTML = MSG_UNKNOWN_ERROR;
    errObj.style.display = 'inline';
  } else {
      var root = req.responseXML.documentElement;
      // error reply	
      if (root.tagName == 'error') {
        var msg = getElementValue(root, 'errormessage');
        errObj.innerHTML = msg;
        errObj.style.display = 'inline';
        setStarsToValueInLocation(userRating, loc);
      } else {
        var userRating = getElementValue(root, 'user_rating');
        // need to update rating in all locations
        setStarsToValueInLocation(userRating, 'top');
        setStarsToValueInLocation(userRating, 'top_bottom');
        setStarsToValueInLocation(userRating, 'bottom_bottom');
	ele("rating_info_" + loc).style.display = "inline";
        if (loc == 'top') {
          ele('communityRating').style.display = "none";
        }
        ele("rating_info_" + loc).innerHTML = MSG_ANNOTATION_SAVED;
        newRating = userRating;
        // 5 seconds
        setTimeout("concealRatingInfo()",5000);
     }
   }
}

function concealRatingInfo() {
  ele("rating_info_top").style.display = "none";
  ele("rating_info_top_bottom").style.display = "none";
  ele("rating_info_bottom_bottom").style.display = "none";
  ele('communityRating').style.display = "inline";
  ele("rating_info_top" ).innerHTML = "";
  ele("rating_info_top_bottom").innerHTML = "";
  ele("rating_info_bottom_bottom" ).innerHTML = "";
}

function setStarsToValueInLocation(rating, location) {
    ele('rating_info_'+ location).innerHTML = '';
    ele('rating_info_' + location).style.display = "none";
    ele('1_' + location).src = 'images/st_pe_off_l_lg.gif';	
    ele('2_' + location).src = 'images/st_pe_off_m_lg.gif';	
    ele('3_' + location).src = 'images/st_pe_off_m_lg.gif';	
    ele('4_' + location).src = 'images/st_pe_off_m_lg.gif';	
    ele('5_' + location).src = 'images/st_pe_off_r_lg.gif';	
	
    if (rating >= 1) {
      ele('1_' + location).src = 'images/st_pe_on_l_lg.gif';	
    }
    if (rating >= 2) {
      ele('2_' + location).src = 'images/st_pe_on_m_lg.gif';	
    }  
    if (rating >= 3) {
      ele('3_' + location).src = 'images/st_pe_on_m_lg.gif';	
    } 
    if (rating >= 4) {
      ele('4_' + location).src = 'images/st_pe_on_m_lg.gif';	
    } 
    if (rating >= 5) {
      ele('5_' + location).src = 'images/st_pe_on_r_lg.gif';	
    }
}

function createStarsHtml(stars, allowRating) {
  if (allowRating && stars > 0) {
    var imageString = '';
    for (var i = 0; i < stars; i++) {
        imageString = imageString + '<img src="images/starLittle.gif">';
    }
    for (var j = stars; j < 5; j++) {
	imageString = imageString + '<img src="images/starLittleEmpty.gif">';
    }
    return imageString;
  }
  return " ";
}

function tagInputFieldOnKeyDown(e) {
  if (!e) {
    e = window.event;
  }
  var keycode = e.keyCode || e.which;
  if (keycode == 13 && ele('taginput').value != MSG_ADD_LABEL) {
    ele('taginputbutton').onclick();	
  }
}
 
 
function doPause(target) {
  var params = "targetId=" + target + "&functionName=pause";
  insertFlash("proxyflashdiv", "/proxy.swf", params);
}

function insertFlash(container, swf, params) {
  var objectAttr;
  if (isIE) {
    objectAttr = 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"';
  } else {
    objectAttr = 'data="' + swf + '"';
  }
  
  ele(container).innerHTML = '\
    <object ' + objectAttr +
      ' width="1" height="1" id="VideoDataStore" align="middle"> \
      <param name="movie" value="' + swf + '" /> \
      <param name="quality" value="best" /> \
      <param name="bgcolor" value="#ffffff" /> \
      <param name="scale" value="noScale" /> \
      <param name="wmode" value="window" /> \
      <param name="salign" value="TL" /> \
      <param name="FlashVars" \
             value="' + params + '" /> \
    </object>';
}


