SubKorea > ¿ÀÇ API > Google YouTube API > ÇÁ·Î±×·¡¹Ö > js ÆÄÀÏ - º¯¼öÆÄ¾Ç

 
/** 
 * Copyright (c) 2008 Google Inc. 
 * 
 * You are free to copy and use this sample. 
 * License can be found here: http://code.google.com/apis/ajaxsearch/faq/#license 
*/ 

function GSvideoBar(barRoot, opt_playerRoot, options) { 

  this.processArguments(barRoot, opt_playerRoot, options); 

  this.setGlobals(); 
  this.buildSuperStructure(); 
  this.buildSearchControl(); 

  // if we have an auto execute list, then start it up 

  if (this.autoExecuteMode) { 

    this.cycleTimeClosure = this.methodClosure(this, GSvideoBar.prototype.cycleTimeout, [null]); 

    // if there is only a single item in the execute list, then 
    // disable autoExecuteMode... 

    if ( this.executeList.length == 1) { 
      this.switchToListItem(0); 
    } else { 
      this.cycleTimeout(); 
    } 
  } 
} 

// cycle time for selecting a video set 
GSvideoBar.CYCLE_TIME_EXTRA_SHORT = 3000; 
GSvideoBar.CYCLE_TIME_SHORT = 10000; 
GSvideoBar.CYCLE_TIME_MEDIUM = 15000; 
GSvideoBar.CYCLE_TIME_LONG = 30000; 

// cycle mode 

GSvideoBar.CYCLE_MODE_RANDOM = 1; 
GSvideoBar.CYCLE_MODE_LINEAR = 2; 

GSvideoBar.MAX_CACHE_LIFETIME = 50; 
GSvideoBar.MIN_CACHE_LIFETIME = 2; 
GSvideoBar.DEFAULT_CACHE_LIFETIME = 2; 
GSvideoBar.MAX_ERROR_COUNT = 4; 
GSvideoBar.DEFAULT_QUERY = "VW GTI"; 

GSvideoBar.THUMBNAILS_SMALL = 1; 
GSvideoBar.THUMBNAILS_MEDIUM = 2; 

// floating player option 

GSvideoBar.PLAYER_ROOT_FLOATING = "floating"; 

GSvideoBar.prototype.processArguments = function(barRoot, opt_playerRoot, 
                                                 opt_options) { 
  this.floatingPlayerBox = null; 
  this.barRoot = barRoot; 
  this.playerRoot = opt_playerRoot; 
  this.statusRoot = null; 
  this.externalMaster = null; 
  this.verticalMode = true; 
  this.thumbSize = GSvideoBar.THUMBNAILS_MEDIUM; 
  this.autoExecuteMode = false; 
  this.executeList = new Array(); 
  this.cycleTime = GSvideoBar.CYCLE_TIME_MEDIUM; 
  this.cycleMode = GSvideoBar.CYCLE_MODE_RANDOM; 
  this.cycleNext = 0; 
  this.cycleTimer = null; 
  this.cacheLifetime = GSvideoBar.DEFAULT_CACHE_LIFETIME; 

  // set defaults that are changable via options 
  this.resultSetSize = GSearch.SMALL_RESULTSET; 
  this.ST_ALL_DONE = GSearch.strings["im-done"]; 

  if (opt_options) { 
    // option.largetResultSet 
    if (opt_options.largeResultSet && opt_options.largeResultSet == true ) { 
      this.resultSetSize = GSearch.LARGE_RESULTSET; 
    } else { 
      this.resultSetSize = GSearch.SMALL_RESULTSET; 
    } 

    if ( opt_options.master ) { 
      this.externalMaster = opt_options.master; 
    } 

    if (opt_options.horizontal && opt_options.horizontal == true ) { 
      this.verticalMode = false; 
    } else { 
      this.verticalMode = true; 
    } 

    if (opt_options.thumbnailSize) { 
      if (opt_options.thumbnailSize == GSvideoBar.THUMBNAILS_MEDIUM ) { 
        this.thumbSize = GSvideoBar.THUMBNAILS_MEDIUM; 
      } else if ( opt_options.thumbnailSize == GSvideoBar.THUMBNAILS_SMALL ) { 
        this.thumbSize = GSvideoBar.THUMBNAILS_SMALL; 
      } else { 
        this.thumbSize = GSvideoBar.THUMBNAILS_MEDIUM; 
      } 
    } 

    if (opt_options.string_allDone) { 
      this.ST_ALL_DONE = opt_options.string_allDone; 
    } 

    // the auto execute list contains 
    // a cycleTime value, a cycleMode value, and an array 
    // of searchExpressions 
    if (opt_options.autoExecuteList) { 

      // if specified and valid, then use it, otherwise 
      // use default set above 
      if (opt_options.autoExecuteList.cycleTime) { 
        var cycleTime = opt_options.autoExecuteList.cycleTime; 
        if (cycleTime == GSvideoBar.CYCLE_TIME_EXTRA_SHORT || 
            cycleTime == GSvideoBar.CYCLE_TIME_SHORT || 
            cycleTime == GSvideoBar.CYCLE_TIME_MEDIUM || 
            cycleTime == GSvideoBar.CYCLE_TIME_LONG ) { 
          this.cycleTime = cycleTime; 
        } 
      } 

      if (opt_options.autoExecuteList.cycleMode) { 
        var cycleMode = opt_options.autoExecuteList.cycleMode; 
        if (cycleMode == GSvideoBar.CYCLE_MODE_RANDOM || 
            cycleMode == GSvideoBar.CYCLE_MODE_LINEAR) { 
          this.cycleMode = cycleMode; 
        } 
      } 

      // now grab the list... 
      if (opt_options.autoExecuteList.executeList && 
          opt_options.autoExecuteList.executeList.length > 0 ) { 

        // grab from the list 
        for (var i=0; i < opt_options.autoExecuteList.executeList.length; i++) { 
          this.executeList.push( 
            this.newListItem(opt_options.autoExecuteList.executeList[i])); 
        } 
        this.autoExecuteMode = true; 
        this.currentIndex = 0; 
        if (opt_options.autoExecuteList.statusRoot) { 
          this.statusRoot = opt_options.autoExecuteList.statusRoot; 
        } 
      } 
    } 

  } 

} 

GSvideoBar.prototype.resetAutoExecuteListItems = function(newList) { 

  if (this.autoExecuteMode && newList.length > 0) { 

    // stop the timer... 
    if (this.cycleTimer) { 
      clearTimeout(this.cycleTimer); 
      this.cycleTimer = null; 
    } 

    // clear the status area 
    if (this.statusRoot) { 
      this.removeChildren(this.statusRoot); 
    } 

    // nuke the old list 
    this.executeList = new Array(); 

    // build the new list 
    for (var i=0; i < newList.length; i++) { 
      this.executeList.push(this.newListItem(newList[i])); 
    } 
    this.currentIndex = 0; 

    if (this.statusRoot) { 
      this.populateStatusRoot(); 
    } 

    if ( this.executeList.length == 1) { 
      this.switchToListItem(0); 
    } else { 
      this.cycleTimeout(); 
    } 
  } 
} 

GSvideoBar.prototype.setGlobals = function() { 
  this.br_AgentContains_cache_ = {}; 

  // subserstructure boxes 

  this.CL_PLAYERBOX = "playerBox_gsvb"; 
  this.CL_PLAYING = "playerBox_gsvb playing_gsvb"; 
  this.CL_IDLE = "playerBox_gsvb idle_gsvb"; 
  this.CL_FLOATING_BOX = "floatingPlayerBox_gsvb"; 
  this.CL_FLOATING_BRANDING = "floatingBranding_gsvb"; 
  this.CL_FLOATING_BOX_PLAYING = "floatingPlayerBox_gsvb playing_gsvb"; 
  this.CL_FLOATING_BOX_IDLE = "floatingPlayerBox_gsvb idle_gsvb"; 
  this.CL_FLOATING_PLAYER = "floatingPlayer_gsvb"; 
  this.CL_FLOATING_PLAYER_PLAYING = "floatingPlayer_gsvb playing_gsvb"; 
  this.CL_FLOATING_PLAYER_IDLE = "floatingPlayer_gsvb idle_gsvb"; 
  

  this.CL_PLAYERINNERBOX = "playerInnerBox_gsvb"; 
  this.CL_VIDEOBARBOX = "videoBarBox_gsvb"; 
  this.CL_VIDEOBARBOXFULL = "videoBarBox_gsvb full_gsvb"; 
  this.CL_VIDEOBARBOXEMPTY = "videoBarBox_gsvb empty_gsvb"; 

  // major app states 

  this.CL_ACTIVE = "active_gsvb"; 

  // player 

  this.CL_PLAYER = "player_gsvb"; 
  this.CL_ALLDONE = "alldone_gsvb"; 
  this.CL_TITLE = "title_gsvb"; 

  // results 

  this.CL_RESULTSBOX = "resultsBox_gsvb"; 
  this.CL_BRANDINGBOX = "brandingBox_gsvb"; 
  this.CL_RESULTTABLE_VERTICAL = "resultTable_gsvb vertical_gsvb"; 
  this.CL_RESULTTABLE_HORIZONTAL = "resultTable_gsvb horizontal_gsvb"; 
  this.CL_RESULTCELL = "resultCell_gsvb"; 
  this.CL_RESULTDIV = "resultDiv_gsvb"; 
  this.CL_RESULTDIV_SMALL = "resultDiv_gsvb smallResultDiv_gsvb"; 

  // status 

  this.CL_STATUSBOX = "statusBox_gsvb"; 
  this.CL_STATUSITEM = "statusItem_gsvb"; 
  this.CL_STATUSITEM_SELECTED = "statusItem_gsvb statusItemSelected_gsvb"; 

  this.smallResultBoxHeight = 39; 
  this.resultBoxHeight = 77; 
} 

GSvideoBar.prototype.buildSuperStructure = function() { 

  // build the player box if we are a master, if not 
  // link up to the master's player 
  if (this.externalMaster == null) { 
    if ( this.playerRoot == GSvideoBar.PLAYER_ROOT_FLOATING ) { 
      this.floatingPlayerBox = this.createDiv(null, this.CL_FLOATING_BOX_IDLE); 
      this.playerRoot = this.createDiv(null, this.CL_FLOATING_PLAYER_IDLE); 
      document.body.appendChild(this.floatingPlayerBox); 
      document.body.appendChild(this.playerRoot); 
      if (this.br_IsMac()) { 
        // disable opacity on mac 
        this.floatingPlayerBox.style.opacity = "1.00"; 
      } 
    } else { 
      this.removeChildren(this.playerRoot); 
    } 
    this.playerBox = this.createDiv(null, this.CL_PLAYERBOX); 
    this.playerAllDone = this.createDiv(this.ST_ALL_DONE, this.CL_ALLDONE); 
    this.playerAllDone.onclick = this.methodClosure(this, this.stopVideo, []); 
    this.playerInnerBox = this.createDiv(null, this.CL_PLAYERINNERBOX); 

    this.playerBox.appendChild(this.playerAllDone); 
    this.playerBox.appendChild(this.playerInnerBox); 
    this.playerRoot.appendChild(this.playerBox); 
    this.cssSetClass(this.playerBox, this.CL_IDLE); 
  } 
  this.player = null; 

  // create the videoBar box 
  this.removeChildren(this.barRoot); 
  this.barBox = this.createDiv(null, this.CL_VIDEOBARBOX); 
  this.barRoot.appendChild(this.barBox); 

  // add results box and branding box 
  this.resultsBox = this.createDiv(null, this.CL_RESULTSBOX); 
  this.barBox.appendChild(this.resultsBox); 
  this.cssSetClass(this.barBox, this.CL_VIDEOBARBOXEMPTY); 

  // clear and optionally populate the status area 
  if (this.statusRoot) { 
    this.populateStatusRoot(); 
  } 

} 

GSvideoBar.prototype.buildSearchControl = function() { 
  this.vs = new GvideoSearch(); 
  this.vs.setResultSetSize(this.resultSetSize); 
  this.vs.setSearchCompleteCallback(this, GSvideoBar.prototype.searchComplete, [true]); 

  this.vsBypass = new GvideoSearch(); 
  this.vsBypass.setResultSetSize(this.resultSetSize); 
  this.vsBypass.setSearchCompleteCallback(this, GSvideoBar.prototype.searchComplete, [false]); 
} 

GSvideoBar.prototype.execute = function(query) { 
  this.vsBypass.execute(query); 
} 

GSvideoBar.prototype.executeInternal = function(query) { 
  this.vs.execute(query); 
} 

GSvideoBar.prototype.clearAllResults = function() { 
  this.cssSetClass(this.barBox, this.CL_VIDEOBARBOXEMPTY); 
} 

GSvideoBar.prototype.searchComplete = function(fromListItem) { 
  var results = null; 
  if (fromListItem) { 
    var currentListItem = this.executeList[this.currentIndex]; 
    if (this.vs.results && this.vs.results.length > 0) { 
      // populate cache 
      currentListItem.results = new Array(); 
      currentListItem.cacheCount = 1; 
      currentListItem.errorCount = 0; 
      for (var i = 0; i < this.vs.results.length; i++) { 
        currentListItem.results.push(this.vs.results[i]); 
      } 
      results = currentListItem.results; 
    } else { 
      currentListItem.errorCount++; 

      // if the error is due to a bad search term, then 
      // nuke right away 
      if (this.vs.completionStatus == 200) { 
        currentListItem.errorCount = GSvideoBar.MAX_ERROR_COUNT + 1; 
      } 
    } 
  } else { 
    // normal .execute called, no caching... 
    if (this.vsBypass.results && this.vsBypass.results.length > 0) { 
      results = this.vsBypass.results; 
    } 
  } 
  this.processResults(results); 
} 

GSvideoBar.prototype.processResults = function(results) { 

  if ( results && results.length > 0) { 
    this.cssSetClass(this.barBox, this.CL_VIDEOBARBOXFULL); 
    this.removeChildren(this.resultsBox); 

    var cell; 
    var table; 
    var row = null; 
    if (this.verticalMode) { 
      table = this.createTable(this.CL_RESULTTABLE_VERTICAL); 
    } else { 
      table = this.createTable(this.CL_RESULTTABLE_HORIZONTAL); 
    } 
    table.setAttribute("align", "center"); 

    for (var i = 0; i < results.length; i++) { 

      var res = results[i]; 

      var imageScaler; 
      var resultBoxHeight; 
      var resultClass = null; 
      if (this.thumbSize == GSvideoBar.THUMBNAILS_MEDIUM ) { 

        // full size image 
        imageScaler = {width:100,height:75}; 
        resultBoxHeight = this.resultBoxHeight; 
        resultClass = this.CL_RESULTDIV; 
      } else { 

        // small size image 
        imageScaler = {width:50,height:37}; 
        resultBoxHeight = this.smallResultBoxHeight; 
        resultClass = this.CL_RESULTDIV_SMALL; 
      } 
      var scaled = GSearch.scaleImage(res.tbWidth, res.tbHeight, imageScaler); 
      var img = this.createImage(res.tbUrl, scaled.width, scaled.height, null); 

      if (this.externalMaster) { 
        img.onclick = this.methodClosure(this.externalMaster, this.externalMaster.playVideo, [res]); 
      } else { 
        img.onclick = this.methodClosure(this, this.playVideo, [res]); 
      } 

      // manually set the top padding 
      if ((resultBoxHeight - scaled.height) > 0) { 
        var padTop = Math.round((resultBoxHeight - scaled.height)/2); 
        img.setAttribute("vspace", padTop); 
      } 

      // compute duration 
      var seconds = res.duration; 
      var minutes = parseInt(seconds/60); 
      var durationString; 
      if (minutes > 0) { 
        durationString = minutes + "m"; 
        var remainder = seconds%60; 
        if (remainder > 20) { 
          durationString += " " + remainder + "s"; 
        } 
      } else { 
        durationString = seconds + "s"; 
      } 

      var toolTip = res.titleNoFormatting + " ( " + durationString + " )"; 
      var div = this.createDiv(null, resultClass); 
      div.title = toolTip; 
      div.appendChild(img); 

      // create a new row for each result when in vertical mode 
      // otherwise, jam everything into a single row. 
      if (this.verticalMode) { 
        row = this.createTableRow(table); 
      } else { 
        if (row == null) { 
          row = this.createTableRow(table); 
        } 
      } 
      cell = this.createTableCell(row, this.CL_RESULTCELL); 
      cell.setAttribute("align", "center"); 
      cell.appendChild(div); 
    } 

    // now add in the branding... 
    row = this.createTableRow(table); 
    var brandingOrientation; 
    if (this.verticalMode) { 
      cell = this.createTableCell(row, this.CL_RESULTCELL); 
      brandingOrientation = GSearch.VERTICAL_BRANDING; 
    } else { 
      cell = this.createTableCell(row, this.CL_RESULTCELL); 
      if (this.br_IsIE()) { 
        cell.setAttribute("colSpan", results.length); 
      } else { 
        cell.setAttribute("colspan", results.length); 
      } 
      brandingOrientation = GSearch.HORIZONTAL_BRANDING; 
    } 
    GSearch.getBranding(cell, brandingOrientation, "http://www.youtube.com"); 
    this.brandingCell = cell; 

    this.resultsBox.appendChild(table); 
  } else { 
    this.cssSetClass(this.barBox, this.CL_VIDEOBARBOXEMPTY); 
  } 
} 

GSvideoBar.prototype.playVideo = function(result) { 

  this.stopVideo(); 
  if (this.autoExecuteMode && this.cycleTimer) { 
    clearTimeout(this.cycleTimer); 
    this.cycleTimer = null; 
  } 
  if (result.playUrl && result.playUrl != "") { 
    this.cssSetClass(this.playerBox, this.CL_PLAYING); 
    if (this.floatingPlayerBox) { 
      this.cssSetClass(this.floatingPlayerBox, this.CL_FLOATING_BOX_PLAYING); 
      this.cssSetClass(this.playerRoot, this.CL_FLOATING_PLAYER_PLAYING); 
    } 
    this.player = GvideoSearch.createPlayer(result, this.CL_PLAYER); 
    this.playerInnerBox.appendChild(this.player); 

    // the title 
    var title = this.createDivLink(result.url, result.title, null, this.CL_TITLE); 
    this.playerInnerBox.appendChild(title); 

    if (this.floatingPlayerBox) { 
      var playerBounds = GSvideoBar.nodeBounds(this.playerRoot); 
      var bounds = GSvideoBar.nodeBounds(this.barRoot); 
      var x; 
      var y; 
      if (this.verticalMode) { 
        x = bounds.x - playerBounds.width; 
        y = bounds.y + bounds.height / 2 - playerBounds.height / 2; 
        var brandingBounds = GSvideoBar.nodeBounds(this.brandingCell); 
        y = y - brandingBounds.height / 2; 
        if (x < 10) { 
          x = bounds.x + bounds.width; 
        } 
      } else { 
        x = bounds.x + bounds.width / 2 - playerBounds.width / 2; 
        y = bounds.y - playerBounds.height; 
        if (y < 10) { 
          y = bounds.y + bounds.height; 
        } 
      } 

      this.playerRoot.style.top = y + "px"; 
      this.playerRoot.style.left = x + "px"; 

      this.floatingPlayerBox.style.top = y - 10 + "px"; 
      this.floatingPlayerBox.style.left = x - 10 + "px"; 
      boxWidth = (playerBounds.width + 20) + "px"; 
      this.floatingPlayerBox.style.width = boxWidth; 
      this.floatingPlayerBox.style.height = (playerBounds.height + 20) + "px"; 
    } 
    google.loader.recordStat('vbp', '1'); 
  } 
} 

GSvideoBar.prototype.stopVideo = function() { 
  this.cssSetClass(this.playerBox, this.CL_IDLE); 
  if (this.floatingPlayerBox) { 
    this.cssSetClass(this.floatingPlayerBox, this.CL_FLOATING_BOX_IDLE); 
    this.cssSetClass(this.playerRoot, this.CL_FLOATING_PLAYER_IDLE); 
  } 
  this.removeChildren(this.playerInnerBox); 
  if (this.player) { 
    delete(this.player); 
    this.player = null; 
  } 
  if (this.autoExecuteMode && this.executeList.length > 1) { 
    this.clearTimer(); 
    this.cycleTimer = setTimeout(this.cycleTimeClosure, this.cycleTime); 
  } 
} 

GSvideoBar.prototype.clearTimer = function() { 
  if (this.cycleTimer) { 
    clearTimeout(this.cycleTimer); 
    this.cycleTimer = null; 
  } 
} 

GSvideoBar.prototype.cycleTimeout = function() { 
  // select a new video 
  // execute a search 
  // restart the timer 
  if ( this.player == null ) { 
    // if there is only a single item in the execute list, 
    // run it 
    if ( this.executeList.length == 1) { 
      this.switchToListItem(0); 
    } else { 
      var index = 0; 
      if (this.cycleMode == GSvideoBar.CYCLE_MODE_RANDOM) { 
        var max = this.executeList.length - 1; 
        index = Math.round(max * Math.random()); 
      } else if (this.cycleMode == GSvideoBar.CYCLE_MODE_LINEAR){ 
        index = this.cycleNext; 
        this.cycleNext++; 
        if (this.cycleNext >= this.executeList.length) { 
          this.cycleNext = 0; 
        } 
      } 

      this.switchToListItem(index); 
      this.clearTimer(); 
      this.cycleTimer = setTimeout(this.cycleTimeClosure, this.cycleTime); 
    } 
  } 
} 

/** 
 * Autoexecute List Item Support 
*/ 
GSvideoBar.prototype.newListItem = function(q) { 
  var listItem = new Object(); 
  listItem.node = null; 
  listItem.query = q; 
  listItem.results = new Array(); 
  listItem.errorCount = 0; 
  listItem.cacheCount = 0; 
  return listItem; 
} 
  

GSvideoBar.prototype.switchToListItem = function(i) { 
  // reset selcted class of previous item 
  // note, first time through this sets 
  // node 0 
  if (this.executeList[this.currentIndex].node) { 
    this.cssSetClass(this.executeList[this.currentIndex].node, 
                     this.CL_STATUSITEM); 

  } 
  this.currentIndex = i; 
  if (this.executeList[this.currentIndex].node) { 
    this.cssSetClass(this.executeList[this.currentIndex].node, 
                     this.CL_STATUSITEM_SELECTED); 

  } 
  var queryTerm = this.executeList[this.currentIndex].query; 
  var cacheResults = false; 
  var currentListItem = null; 
  currentListItem = this.executeList[this.currentIndex]; 

  // if the error count of an item has reached max, reset query term 
  if (currentListItem.errorCount > GSvideoBar.MAX_ERROR_COUNT) { 
    currentListItem.errorCount = 0; 
    queryTerm = GSvideoBar.DEFAULT_QUERY; 
    currentListItem.query = queryTerm; 
  } 

  // if the listItem has no cached results, OR if 
  // we have used the cached results several times 
  // already, initiate a real search 
  if (currentListItem.cacheCount == 0 || 
      currentListItem.cacheCount > this.cacheLifetime ) { 
    currentListItem.cacheCount = 0; 
    this.executeInternal(queryTerm); 
  } else { 
    currentListItem.cacheCount++; 
    this.processResults(currentListItem.results); 
  } 
} 

GSvideoBar.prototype.populateStatusRoot = function() { 
  this.removeChildren(this.statusRoot); 
  this.statusBox = this.createDiv(null, this.CL_STATUSBOX); 
  this.statusRoot.appendChild(this.statusBox); 

  if ( this.executeList.length > 0) { 
    for (var i=0; i < this.executeList.length; i++ ) { 
      var listItem = this.executeList[i]; 
      var displayTerm = listItem.query; 

      // if we are looking at our special feed: terms, strip 
      // feed: from the display 
      var m = displayTerm.match(/feed:(top100|top100new)$/); 
      if (m && m.length == 2) { 
        displayTerm = m[1]; 
      } 
      var div = this.createDiv(displayTerm, this.CL_STATUSITEM); 

      // add click handler... 
      div.onclick = this.methodClosure(this, 
                                       GSvideoBar.prototype.switchToListItem, 
                                       [i] ); 
      listItem.node = div; 
      this.statusBox.appendChild(div); 
      this.statusBox.appendChild(document.createTextNode(" ")); 
    } 
  } 
} 

/** 
 * Static Helper Method 
*/ 
GSvideoBar.methodCallback = function(object, method) { 
  return function() { 
    return method.apply(object, arguments); 
  } 
} 

/** 
 * Class methods 
*/ 

GSvideoBar.prototype.methodClosure = function(object, method, opt_argArray) { 
  return function() { 
    return method.apply(object, opt_argArray); 
  } 
} 

GSvideoBar.prototype.createDiv = function(opt_text, opt_className) { 
  var el = document.createElement("div"); 
  if (opt_text) { 
    el.innerHTML = opt_text; 
  } 
  if (opt_className) { el.className = opt_className; } 
  return el; 
} 

GSvideoBar.prototype.removeChildren = function(parent) { 
  while (parent.firstChild) { 
    parent.removeChild(parent.firstChild); 
  } 
} 

GSvideoBar.prototype.removeChild = function(parent, child) { 
  parent.removeChild(child); 
} 

GSvideoBar.prototype.cssSetClass = function(el, className) { 
  el.className = className; 
} 

GSvideoBar.prototype.createTable = function(opt_className) { 
  var el = document.createElement("table"); 
  if (opt_className) { el.className = opt_className; } 
  return el; 
} 

GSvideoBar.prototype.createTableRow = function(table, opt_className) { 
  var tr = table.insertRow(-1); 
  if (opt_className) { tr.className = opt_className; } 
  return tr; 
} 

GSvideoBar.prototype.createTableCell = function(tr, opt_className) { 
  var td = tr.insertCell(-1); 
  if (opt_className) { td.className = opt_className; } 
  return td; 
} 

GSvideoBar.prototype.createDivLink = function(href, text, opt_target, opt_className) { 
  var div = this.createDiv(null, opt_className); 
  var el = document.createElement("a"); 
  el.href = href; 
  el.appendChild(document.createTextNode(text)); 
  if (opt_className) { 
    el.className = opt_className; 
  } 
  if (opt_target) { 
    el.target = opt_target; 
  } 
  div.appendChild(el); 
  return div; 
} 

GSvideoBar.prototype.createImage = function(src, opt_w, opt_h, opt_className) { 
  var el = document.createElement("img"); 
  el.src = src; 
  if (opt_w) { el.width = opt_w; } 
  if (opt_h) { el.height = opt_h; } 
  if (opt_className) { el.className = opt_className; } 
  return el; 
} 

GSvideoBar.prototype.getNodeWidth = function(node) { 
  return node.offsetWidth; 
} 

GSvideoBar.prototype.br_AgentContains_ = function(str) { 
  if (str in this.br_AgentContains_cache_) { 
    return this.br_AgentContains_cache_[str]; 
  } 

  return this.br_AgentContains_cache_[str] = 
    (navigator.userAgent.toLowerCase().indexOf(str) != -1); 
} 

GSvideoBar.prototype.br_IsIE = function() { 
  return this.br_AgentContains_('msie'); 
} 

GSvideoBar.prototype.br_IsMac = function() { 
  return this.br_AgentContains_('macintosh') || 
         this.br_AgentContains_('mac_powerpc'); 
} 

GSvideoBar.prototype.br_IsKonqueror = function() { 
  return this.br_AgentContains_('konqueror'); 
} 

GSvideoBar.prototype.br_IsOpera = function() { 
  return this.br_AgentContains_('opera'); 
} 

GSvideoBar.prototype.br_IsSafari = function() { 
  return this.br_AgentContains_('safari') || this.br_IsKonqueror(); 
} 

GSvideoBar.prototype.br_IsNav = function() { 
  return !this.br_IsIE() && 
         !this.br_IsSafari() && 
         this.br_AgentContains_('mozilla'); 
} 

GSvideoBar.prototype.br_IsWin = function() { 
  return this.br_AgentContains_('win'); 
} 

GSvideoBar.nodeBounds = function(obj) { 
  var result = {}; 

  function fixRectForScrolling(r) { 

    // Need to take into account scrolling offset of ancestors (IE already does 
    // this) 
    for (var o = obj.offsetParent; 
         o && o.offsetParent; 
         o = o.offsetParent) { 
      if (o.scrollLeft) { 
        r.x -= o.scrollLeft; 
      } 
      if (o.scrollTop) { 
        r.y -= o.scrollTop; 
      } 
    } 
  } 

  // Mozilla 
  if (obj.ownerDocument && obj.ownerDocument.getBoxObjectFor) { 
    var box = obj.ownerDocument.getBoxObjectFor(obj); 
    result.x = box.x; 
    result.y = box.y; 
    result.width = box.width; 
    result.height = box.height; 
    fixRectForScrolling(result); 
    return result; 
  } 

  // IE 
  if (obj.getBoundingClientRect) { 
    var refWindow; 
    if (obj.ownerDocument && obj.ownerDocument.parentWindow) { 
      refWindow = obj.ownerDocument.parentWindow; 
    } else { 
      refWindow = window; 
    } 

    var rect = obj.getBoundingClientRect(); 
    result.x = rect.left + GSvideoBar.GetIEScrollLeft(refWindow); 
    result.y = rect.top + GSvideoBar.GetIEScrollTop(refWindow); 
    result.width = rect.right - rect.left; 
    result.height = rect.bottom - rect.top; 
    return result; 
  } 

  // Fallback to recursively computing this 
  var left = 0; 
  var top = 0; 
  for (var o = obj; o.offsetParent; o = o.offsetParent) { 
    left += o.offsetLeft; 
    top += o.offsetTop; 
  } 

  result.x = left; 
  result.y = top; 
  result.width = obj.offsetWidth; 
  result.height = obj.offsetHeight; 

  fixRectForScrolling(result); 
  return result; 
} 

// Get the y position scroll offset. 
GSvideoBar.GetIEScrollTop = function(win) { 
  if ("compatMode" in win.document && win.document.compatMode == "CSS1Compat") { 
    return win.document.documentElement.scrollTop; 
  } else { 
    return win.document.body.scrollTop; 
  } 
} 

// Get the x position scroll offset. 
GSvideoBar.GetIEScrollLeft = function(win) { 
  if ("compatMode" in win.document && win.document.compatMode == "CSS1Compat") { 
    return win.document.documentElement.scrollLeft; 
  } else { 
    return win.document.body.scrollLeft; 
  } 
}