/* Begin JK Mega-Menu Script */
/* jQuery Mega Menu v1.02
* Last updated: June 29th, 2009. This notice must stay intact for usage 
* Author: JavaScript Kit at http://www.javascriptkit.com/
* Visit http://www.javascriptkit.com/script/script2/jScale/ for full source code
*/

jQuery.noConflict();

var jkmegamenu={

effectduration: 200, //duration of animation, in milliseconds
delaytimer: 200, //delay after mouseout before menu should be hidden, in milliseconds

//No need to edit beyond here
megamenulabels: [],
megamenus: [], //array to contain each block menu instances
zIndexVal: 1000, //starting z-index value for drop down menu
$shimobj: null,

addshim:function($){
	$(document.body).append('<IFRAME id="outlineiframeshim" src="'+(location.protocol=="https:"? 'blank.htm' : 'about:blank')+'" style="display:none; left:0; top:0; z-index:999; position:absolute; filter:progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=0)" frameBorder="0" scrolling="no"></IFRAME>')
	this.$shimobj=$("#outlineiframeshim")
},

alignmenu:function($, e, megamenu_pos){
	var megamenu=this.megamenus[megamenu_pos]
	var $anchor=megamenu.$anchorobj
	var $menu=megamenu.$menuobj
	var menuleft=($(window).width()-(megamenu.offsetx-$(document).scrollLeft())>megamenu.actualwidth)? megamenu.offsetx : megamenu.offsetx-megamenu.actualwidth+megamenu.anchorwidth //get x coord of menu
	//var menutop=($(window).height()-(megamenu.offsety-$(document).scrollTop()+megamenu.anchorheight)>megamenu.actualheight)? megamenu.offsety+megamenu.anchorheight : megamenu.offsety-megamenu.actualheight
	var menutop=megamenu.offsety+megamenu.anchorheight  //get y coord of menu
	$menu.css({left:menuleft+"px", top:menutop+"px"})
	this.$shimobj.css({width:megamenu.actualwidth+"px", height:megamenu.actualheight+"px", left:menuleft+"px", top:menutop+"px", display:"block"})
},

showmenu:function(e, megamenu_pos){
	var megamenu=this.megamenus[megamenu_pos]
	var $menu=megamenu.$menuobj
	var $menuinner=megamenu.$menuinner
	if ($menu.css("display")=="none"){
		this.alignmenu(jQuery, e, megamenu_pos)
		$menu.css("z-index", ++this.zIndexVal)
		$menu.show(this.effectduration, function(){
			$menuinner.css('visibility', 'visible')
		})
	}
	else if ($menu.css("display")=="block" && e.type=="click"){ //if menu is hidden and this is a "click" event (versus "mouseout")
		this.hidemenu(e, megamenu_pos)
	}
	return false
},

hidemenu:function(e, megamenu_pos){
	var megamenu=this.megamenus[megamenu_pos]
	var $menu=megamenu.$menuobj
	var $menuinner=megamenu.$menuinner
	$menuinner.css('visibility', 'hidden')
	this.$shimobj.css({display:"none", left:0, top:0})
	$menu.hide(this.effectduration)
},

definemenu:function(anchorid, menuid, revealtype){
	this.megamenulabels.push([anchorid, menuid, revealtype])
},

render:function($){
	for (var i=0, labels=this.megamenulabels[i]; i<this.megamenulabels.length; i++, labels=this.megamenulabels[i]){
		if ($('#'+labels[0]).length!=1 || $('#'+labels[1]).length!=1) //if one of the two elements are NOT defined, exist
			return
		this.megamenus.push({$anchorobj:$("#"+labels[0]), $menuobj:$("#"+labels[1]), $menuinner:$("#"+labels[1]).children('ul:first-child'), revealtype:labels[2], hidetimer:null})
		var megamenu=this.megamenus[i]	
		megamenu.$anchorobj.add(megamenu.$menuobj).attr("_megamenupos", i+"pos") //remember index of this drop down menu
		megamenu.actualwidth=megamenu.$menuobj.outerWidth()
		megamenu.actualheight=megamenu.$menuobj.outerHeight()
		megamenu.offsetx=megamenu.$anchorobj.offset().left
		megamenu.offsety=megamenu.$anchorobj.offset().top
		megamenu.anchorwidth=megamenu.$anchorobj.outerWidth()
		megamenu.anchorheight=megamenu.$anchorobj.outerHeight()
		$(document.body).append(megamenu.$menuobj) //move drop down menu to end of document
		megamenu.$menuobj.css("z-index", ++this.zIndexVal).hide()
		megamenu.$menuinner.css("visibility", "hidden")
		megamenu.$anchorobj.bind(megamenu.revealtype=="click"? "click" : "mouseenter", function(e){
			var menuinfo=jkmegamenu.megamenus[parseInt(this.getAttribute("_megamenupos"))]
			clearTimeout(menuinfo.hidetimer) //cancel hide menu timer
			return jkmegamenu.showmenu(e, parseInt(this.getAttribute("_megamenupos")))
		})
		megamenu.$anchorobj.bind("mouseleave", function(e){
			var menuinfo=jkmegamenu.megamenus[parseInt(this.getAttribute("_megamenupos"))]
			if (e.relatedTarget!=menuinfo.$menuobj.get(0) && $(e.relatedTarget).parents("#"+menuinfo.$menuobj.get(0).id).length==0){ //check that mouse hasn't moved into menu object
				menuinfo.hidetimer=setTimeout(function(){ //add delay before hiding menu
					jkmegamenu.hidemenu(e, parseInt(menuinfo.$menuobj.get(0).getAttribute("_megamenupos")))
				}, jkmegamenu.delaytimer)
			}
		})
		megamenu.$menuobj.bind("mouseenter", function(e){
			var menuinfo=jkmegamenu.megamenus[parseInt(this.getAttribute("_megamenupos"))]
			clearTimeout(menuinfo.hidetimer) //cancel hide menu timer
		})
		megamenu.$menuobj.bind("click mouseleave", function(e){
			var menuinfo=jkmegamenu.megamenus[parseInt(this.getAttribute("_megamenupos"))]
			menuinfo.hidetimer=setTimeout(function(){ //add delay before hiding menu
				jkmegamenu.hidemenu(e, parseInt(menuinfo.$menuobj.get(0).getAttribute("_megamenupos")))
			}, jkmegamenu.delaytimer)
		})
	} //end for loop
	if(/Safari/i.test(navigator.userAgent)){ //if Safari
		$(window).bind("resize load", function(){
			for (var i=0; i<jkmegamenu.megamenus.length; i++){
				var megamenu=jkmegamenu.megamenus[i]
				var $anchorisimg=(megamenu.$anchorobj.children().length==1 && megamenu.$anchorobj.children().eq(0).is('img'))? megamenu.$anchorobj.children().eq(0) : null
				if ($anchorisimg){ //if anchor is an image link, get offsets and dimensions of image itself, instead of parent A
					megamenu.offsetx=$anchorisimg.offset().left
					megamenu.offsety=$anchorisimg.offset().top
					megamenu.anchorwidth=$anchorisimg.width()
					megamenu.anchorheight=$anchorisimg.height()
				}
			}
		})
	}
	else{
		$(window).bind("resize", function(){
			for (var i=0; i<jkmegamenu.megamenus.length; i++){
				var megamenu=jkmegamenu.megamenus[i]	
				megamenu.offsetx=megamenu.$anchorobj.offset().left
				megamenu.offsety=megamenu.$anchorobj.offset().top
			}
		})
	}
	jkmegamenu.addshim($)
}

}

jQuery(document).ready(function($){
	jkmegamenu.render($)
})

/* End JK Mega-Menu Script */







/* Begin Menu Script */

//Contents for menu
// Flash
//v1.7
// Flash Player Version Detection
// Detect Client Browser type
// Copyright 2005-2007 Adobe Systems Incorporated.  All rights reserved.
var isIE  = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
var isWin = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
var isOpera = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;

function ControlVersion()
{
	var version;
	var axo;
	var e;

	// NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry

	try {
		// version will be set for 7.X or greater players
		axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
		version = axo.GetVariable("$version");
	} catch (e) {
	}

	if (!version)
	{
		try {
			// version will be set for 6.X players only
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
			
			// installed player is some revision of 6.0
			// GetVariable("$version") crashes for versions 6.0.22 through 6.0.29,
			// so we have to be careful. 
			
			// default to the first public version
			version = "WIN 6,0,21,0";

			// throws if AllowScripAccess does not exist (introduced in 6.0r47)		
			axo.AllowScriptAccess = "always";

			// safe to call for 6.0r47 or greater
			version = axo.GetVariable("$version");

		} catch (e) {
		}
	}

	if (!version)
	{
		try {
			// version will be set for 4.X or 5.X player
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
			version = axo.GetVariable("$version");
		} catch (e) {
		}
	}

	if (!version)
	{
		try {
			// version will be set for 3.X player
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
			version = "WIN 3,0,18,0";
		} catch (e) {
		}
	}

	if (!version)
	{
		try {
			// version will be set for 2.X player
			axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
			version = "WIN 2,0,0,11";
		} catch (e) {
			version = -1;
		}
	}
	
	return version;
}

// JavaScript helper required to detect Flash Player PlugIn version information
function GetSwfVer(){
	// NS/Opera version >= 3 check for Flash plugin in plugin array
	var flashVer = -1;
	
	if (navigator.plugins != null && navigator.plugins.length > 0) {
		if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
			var swVer2 = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
			var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
			var descArray = flashDescription.split(" ");
			var tempArrayMajor = descArray[2].split(".");			
			var versionMajor = tempArrayMajor[0];
			var versionMinor = tempArrayMajor[1];
			var versionRevision = descArray[3];
			if (versionRevision == "") {
				versionRevision = descArray[4];
			}
			if (versionRevision[0] == "d") {
				versionRevision = versionRevision.substring(1);
			} else if (versionRevision[0] == "r") {
				versionRevision = versionRevision.substring(1);
				if (versionRevision.indexOf("d") > 0) {
					versionRevision = versionRevision.substring(0, versionRevision.indexOf("d"));
				}
			}
			var flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
		}
	}
	// MSN/WebTV 2.6 supports Flash 4
	else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
	// WebTV 2.5 supports Flash 3
	else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
	// older WebTV supports Flash 2
	else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
	else if ( isIE && isWin && !isOpera ) {
		flashVer = ControlVersion();
	}	
	return flashVer;
}

// When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available
function DetectFlashVer(reqMajorVer, reqMinorVer, reqRevision)
{
	versionStr = GetSwfVer();
	if (versionStr == -1 ) {
		return false;
	} else if (versionStr != 0) {
		if(isIE && isWin && !isOpera) {
			// Given "WIN 2,0,0,11"
			tempArray         = versionStr.split(" "); 	// ["WIN", "2,0,0,11"]
			tempString        = tempArray[1];			// "2,0,0,11"
			versionArray      = tempString.split(",");	// ['2', '0', '0', '11']
		} else {
			versionArray      = versionStr.split(".");
		}
		var versionMajor      = versionArray[0];
		var versionMinor      = versionArray[1];
		var versionRevision   = versionArray[2];

        	// is the major.revision >= requested major.revision AND the minor version >= requested minor
		if (versionMajor > parseFloat(reqMajorVer)) {
			return true;
		} else if (versionMajor == parseFloat(reqMajorVer)) {
			if (versionMinor > parseFloat(reqMinorVer))
				return true;
			else if (versionMinor == parseFloat(reqMinorVer)) {
				if (versionRevision >= parseFloat(reqRevision))
					return true;
			}
		}
		return false;
	}
}

function AC_AddExtension(src, ext)
{
  if (src.indexOf('?') != -1)
    return src.replace(/\?/, ext+'?'); 
  else
    return src + ext;
}

function AC_Generateobj(objAttrs, params, embedAttrs) 
{ 
  var str = '';
  if (isIE && isWin && !isOpera)
  {
    str += '<object ';
    for (var i in objAttrs)
    {
      str += i + '="' + objAttrs[i] + '" ';
    }
    str += '>';
    for (var i in params)
    {
      str += '<param name="' + i + '" value="' + params[i] + '" /> ';
    }
    str += '</object>';
  }
  else
  {
    str += '<embed ';
    for (var i in embedAttrs)
    {
      str += i + '="' + embedAttrs[i] + '" ';
    }
    str += '> </embed>';
  }

  document.write(str);
}

function AC_FL_RunContent(){
  var ret = 
    AC_GetArgs
    (  arguments, ".swf", "movie", "clsid:d27cdb6e-ae6d-11cf-96b8-444553540000"
     , "application/x-shockwave-flash"
    );
  AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
}

function AC_SW_RunContent(){
  var ret = 
    AC_GetArgs
    (  arguments, ".dcr", "src", "clsid:166B1BCA-3F9C-11CF-8075-444553540000"
     , null
    );
  AC_Generateobj(ret.objAttrs, ret.params, ret.embedAttrs);
}

function AC_GetArgs(args, ext, srcParamName, classid, mimeType){
  var ret = new Object();
  ret.embedAttrs = new Object();
  ret.params = new Object();
  ret.objAttrs = new Object();
  for (var i=0; i < args.length; i=i+2){
    var currArg = args[i].toLowerCase();    

    switch (currArg){	
      case "classid":
        break;
      case "pluginspage":
        ret.embedAttrs[args[i]] = args[i+1];
        break;
      case "src":
      case "movie":	
        args[i+1] = AC_AddExtension(args[i+1], ext);
        ret.embedAttrs["src"] = args[i+1];
        ret.params[srcParamName] = args[i+1];
        break;
      case "onafterupdate":
      case "onbeforeupdate":
      case "onblur":
      case "oncellchange":
      case "onclick":
      case "ondblClick":
      case "ondrag":
      case "ondragend":
      case "ondragenter":
      case "ondragleave":
      case "ondragover":
      case "ondrop":
      case "onfinish":
      case "onfocus":
      case "onhelp":
      case "onmousedown":
      case "onmouseup":
      case "onmouseover":
      case "onmousemove":
      case "onmouseout":
      case "onkeypress":
      case "onkeydown":
      case "onkeyup":
      case "onload":
      case "onlosecapture":
      case "onpropertychange":
      case "onreadystatechange":
      case "onrowsdelete":
      case "onrowenter":
      case "onrowexit":
      case "onrowsinserted":
      case "onstart":
      case "onscroll":
      case "onbeforeeditfocus":
      case "onactivate":
      case "onbeforedeactivate":
      case "ondeactivate":
      case "type":
      case "codebase":
      case "id":
        ret.objAttrs[args[i]] = args[i+1];
        break;
      case "width":
      case "height":
      case "align":
      case "vspace": 
      case "hspace":
      case "class":
      case "title":
      case "accesskey":
      case "name":
      case "tabindex":
        ret.embedAttrs[args[i]] = ret.objAttrs[args[i]] = args[i+1];
        break;
      default:
        ret.embedAttrs[args[i]] = ret.params[args[i]] = args[i+1];
    }
  }
  ret.objAttrs["classid"] = classid;
  if (mimeType) ret.embedAttrs["type"] = mimeType;
  return ret;
}
















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

/**
 * @fileoverview A feed gadget based on the AJAX Feed API.
 * @author dcollison@google.com (Derek Collison)
 */

/**
 * GFdynamicFeedControl
 * @param {String} feed The feed URL.
 * @param {String|Object} container Either the id string or the element itself.
 * @param {Object} options Options map.
 * @constructor
 */

function GFdynamicFeedControl(feedUrls, container, options) {
  // node elements.
  this.nodes = {};
  this.collapseElements = [];
  
  // the feeds.
  this.feeds = [];
  this.results = [];

  if (typeof feedUrls == 'string') {
    this.feeds.push({url:feedUrls});
  } else if (typeof feedUrls == 'object') {
    for (var i=0; i<feedUrls.length; i++) {
      var entry = feedUrls[i];
      var o = {};
      var feedUrl;
      if (typeof entry == 'string') {
        o.url = feedUrls[i];
      } else if (typeof entry == 'object') {
        o = feedUrls[i];
	if (o && o.title) {
	  var s = o.title;
	  o.title = s.replace(/</g,'&lt;').replace(/>/g, '&gt;');
	}
      }
      this.feeds.push(o);
    }
  }

  if (typeof container == "string") {
    container = document.getElementById(container);
  }
  this.parseOptions_(options);
  this.setup_(container);
}

/*
 * Default time in milliseconds for the feed to be reloaded.
 * @type Number
 */
GFdynamicFeedControl.DEFAULT_NUM_RESULTS = 4;
/*
 * Default time in milliseconds for the feed to be reloaded.
 * @type Number
 */
GFdynamicFeedControl.DEFAULT_FEED_CYCLE_TIME = 1800000;
/*
 * Default display time in milliseconds for each entry.
 * @type Number
 */
GFdynamicFeedControl.DEFAULT_DISPLAY_TIME = 5000;
/*
 * Default fadeout transition time in milliseconds for each entry.
 * @type Number
 */
GFdynamicFeedControl.DEFAULT_FADEOUT_TIME = 1000;
/*
 * Default time between transition steps in milliseconds
 * @type Number
 */
GFdynamicFeedControl.DEFAULT_TRANSISTION_STEP = 40;
/*
 * Default hover time in milliseconds for each entry.
 * @type Number
 */
GFdynamicFeedControl.DEFAULT_HOVER_TIME = 100;

/**
 * Setup default option map and apply overrides from constructor.
 * @param {Object} options Options map.
 * @private
 */
GFdynamicFeedControl.prototype.parseOptions_ = function(options) {
  // Default Options
  // TODO(dcollison) - implement Feed Cycle.
  this.options = {
    numResults : GFdynamicFeedControl.DEFAULT_NUM_RESULTS,
    feedCycleTime : GFdynamicFeedControl.DEFAULT_FEED_CYCLE_TIME,
    linkTarget : google.feeds.LINK_TARGET_BLANK,
    displayTime : GFdynamicFeedControl.DEFAULT_DISPLAY_TIME,
    transitionTime : GFdynamicFeedControl.DEFAULT_TRANSISTION_TIME,
    transitionStep : GFdynamicFeedControl.DEFAULT_TRANSISTION_STEP,
    fadeOutTime: GFdynamicFeedControl.DEFAULT_FADEOUT_TIME,
    scrollOnFadeOut : true,
    pauseOnHover : true,
    hoverTime : GFdynamicFeedControl.DEFAULT_HOVER_TIME,
    autoCleanup : true,
    transitionCallback : null,
    feedTransitionCallback : null,
    feedLoadCallback : null,
    collapseable : false,
    sortByDate : false,
    horizontal : false,
    stacked : false,
    title : null
  };

  if (options) {
    for (var o in this.options) {
      if (typeof options[o] != 'undefined') {
        this.options[o] = options[o];
      }
    }
  }
  
  // Cant be collapseable unless stacked
  if(!this.options.stacked) {
    this.options.collapseable = false;
  }
  
  // Override strange/bad options
  this.options.displayTime = Math.max(200, this.options.displayTime);
  this.options.fadeOutTime = Math.max(0, this.options.fadeOutTime);

  // Calculated
  var ts = this.options.fadeOutTime / this.options.transitionStep;
  this.fadeOutDelta = Math.min(1, (1.0/ts));

  // Flag to start
  this.started = false;
};

/**
 * Basic setup.
 * @private
 */
GFdynamicFeedControl.prototype.setup_ = function(container) {
  if (container == null) return;
  this.nodes.container = container;

  // Browser fun.
  if (window.ActiveXObject) {
    this.ie = this[window.XMLHttpRequest ? 'ie7' : 'ie6'] = true;
  } else if (document.childNodes && !document.all && !navigator.taintEnabled) {
    this.safari = true;
  } else if (document.getBoxObjectFor != null) {
    this.gecko = true;
  }
  // The feedControl instance for generating entry HTML.
  this.feedControl = new google.feeds.FeedControl();
  this.feedControl.setLinkTarget(this.options.linkTarget);

  // The feeds
  this.expected = this.feeds.length;
  this.errors = 0;

  for (var i = 0; i < this.feeds.length; i++) {
    var feed = new google.feeds.Feed(this.feeds[i].url);
    feed.setResultFormat(google.feeds.Feed.JSON_FORMAT);
    feed.setNumEntries(this.options.numResults);
    feed.load(this.bind_(this.feedLoaded_, i));
  }
};

/**
 * Helper method to bind this instance correctly.
 * @param {Object} method function/method to bind.
 * @return {Function}
 * @private
 */
GFdynamicFeedControl.prototype.bind_ = function(method) {
  var self = this;
  var opt_args = [].slice.call(arguments, 1);
  return function() {
    var args = opt_args.concat([].slice.call(arguments));
    return method.apply(self, args);
  }
};

/**
 * Callback associated with the AJAX Feed api after load.
 * @param {Object} result Loaded result.
 * @private
 */
GFdynamicFeedControl.prototype.feedLoaded_ = function(index, result) {
  if (this.options.feedLoadCallback) {
    this.options.feedLoadCallback(result);
  }
  if (result.error) {
    // Ignore failed feeds for the most part.
    // The user has control through the feedLoadCallback above
    // if they choose to do something more createive.
    // Only complain if we can't load anything.
    if (++this.errors >= this.expected) {
      this.nodes.container.innerHTML = 'Feed' + ((this.expected > 1)?'s ':' ') +
                                       'could not be loaded.';
    }
    return;
  }
  // Override of title option.
  if (this.feeds[index].title) {
    result.feed.title = this.feeds[index].title;
  }
  this.results.push(result);

  if (!this.started) {
    this.createSubContainers_();
    this.displayResult_(0);
  } else if (!this.options.horizontal && this.options.stacked) {
    this.addResult_(this.results.length-1);
  }
};

/**
 * Insert blog in correct place
 * @private
 */
GFdynamicFeedControl.prototype.sortByDate_ = function(resultIndex, newTitle,
                                                      newList) {
  // if sorting by date, insert it into the correct spot
  var newEntryDate = this.results[resultIndex].feed.entries[0].publishedDate;
  var newEntryDateMS = Date.parse(newEntryDate);
  var insertIndex = null;

  for (var i = 0; i < this.results.length; i++) {
    var mostRecentPost = this.results[i].feed.entries[0].publishedDate;
    var mostRecentPostMS = Date.parse(mostRecentPost);
    if(newEntryDateMS > mostRecentPostMS) {
      insertIndex = i;
      break;
    }
  }

  // If it's most stale blog, just append as usual
  if(insertIndex == null) {
    this.nodes.root.appendChild(newTitle);
    this.nodes.root.appendChild(newList);
    this.createListEntries_(resultIndex, newList);
    return;
  }

  // If it is fresher than a blog, insert to correct position
  var insertBeforeIndex = 2 + (insertIndex * 2);
  var swapToIndex = insertBeforeIndex + 2;
  var tempSwap = null;
  var myResultIndex = resultIndex + 1;

  var sectionsToChange = this.nodes.root.childNodes;
  var nodeToInsertBefore = sectionsToChange[insertBeforeIndex];

  this.nodes.root.insertBefore(newTitle, nodeToInsertBefore);
  this.nodes.root.insertBefore(newList, nodeToInsertBefore);

  this.results.splice(insertIndex, 0, this.results[resultIndex]);
  this.results.splice(myResultIndex, 1);
  
  var nodesToChangeClick = sectionsToChange[swapToIndex].nextSibling.childNodes;
  
  this.createListEntries_(insertIndex, newList);

  // Keep freshest blog open first
  if(insertIndex == 0) {
    this.displayResult_(0);
  }

  insertIndex += 1;
  // Reset all of the onmousehover listeners to highlight corect index
  for (var i = swapToIndex; i < sectionsToChange.length; i += 2) {
    var nodesToChangeClick = sectionsToChange[i].nextSibling.childNodes;
    for (var j=0; j < nodesToChangeClick.length; j++) {
      nodesToChangeClick[j].onmouseover = this.bind_(this.listMouseOver_, 
                                                     insertIndex, j);
      nodesToChangeClick[j].onmouseout = this.bind_(this.listMouseOut_, 
                                                    insertIndex, j);
    }
    insertIndex++;
  }
};

/**
 * Setup to display the Result for stacked mode
 * @private
 */
GFdynamicFeedControl.prototype.addResult_ = function(resultIndex) {
  var result = this.results[resultIndex];
  var newTitle = this.createDiv_('gfg-subtitle');
  this.setTitle_(result.feed, newTitle);
  var newList = this.createDiv_('gfg-list');

  // add a collapseable button
  if(this.options.collapseable) {
    var collapseLink = document.createElement('div');
    newList.style.display = 'none';
    collapseLink.className = 'gfg-collapse-closed';
    newTitle.appendChild(collapseLink);
    collapseLink.onclick = this.toggleCollapse(this, newList, collapseLink);
    this.collapseElements.push({
      list : newList,
      collapse : collapseLink
    });
  }


  var clearFloat = document.createElement('div');
  clearFloat.className = 'clearFloat';
  newTitle.appendChild(clearFloat);

  // If not sorting by date, add them as usual
  if(!this.options.sortByDate) {
    this.nodes.root.appendChild(newTitle);
    this.nodes.root.appendChild(newList);
    this.createListEntries_(resultIndex, newList);
  } else {
    this.sortByDate_(resultIndex, newTitle, newList);
  }
  
};

/**
 * Setup to display the Result
 * @private
 */
GFdynamicFeedControl.prototype.displayResult_ = function(resultIndex) {
  this.resultIndex = resultIndex;
  var result = this.results[resultIndex];
  if (this.options.feedTransitionCallback) {
    this.options.feedTransitionCallback(result);
  }
  if (this.options.title) {
    this.setPlainTitle_(this.options.title);
  } else {
    this.setTitle_(result.feed);
  }
  this.clearNode_(this.nodes.entry);

  if (this.started && !this.options.horizontal && this.options.stacked) {
    this.entries = result.feed.entries;
  } else {
    this.createListEntries_(resultIndex, this.nodes.list);
  }
  this.displayEntries_();
}

/**
 * Set the Title to just plaintext
 * @private
 */
GFdynamicFeedControl.prototype.setPlainTitle_ = function(title, opt_element) {
  var el = opt_element || this.nodes.title;
  el.innerHTML = title;
}

/**
 * Set the Title
 * @private
 */
GFdynamicFeedControl.prototype.setTitle_ = function(resultFeed, opt_element) {
  var el = opt_element || this.nodes.title;
  this.clearNode_(el);
  var link = document.createElement('a');
  link.target = google.feeds.LINK_TARGET_BLANK;
  link.href = resultFeed.link;
  link.className = 'gfg-collapse-href';
  link.innerHTML = resultFeed.title;
  el.appendChild(link);
}

GFdynamicFeedControl.prototype.toggleCollapse = function(feedControl, 
                                                         listReference, 
                                                         collapseLink) {
  return function() {
    var els = feedControl.collapseElements;
    for (var i=0; i < els.length; i++) {
      var el = els[i];
      el.list.style.display = 'none';
      el.collapse.className = 'gfg-collapse-closed';
    }
    listReference.style.display = 'block';
    collapseLink.className = 'gfg-collapse-open';
  }
}

/**
 * Create the list Entries
 * @private
 */
GFdynamicFeedControl.prototype.createListEntries_ = function(resultIndex, node) {
  var entries = this.results[resultIndex].feed.entries;
  this.clearNode_(node);
  for (var i = 0; i < entries.length; i++) {
    this.feedControl.createHtml(entries[i]);
    var className = 'gfg-listentry ';
    className += (i%2)?'gfg-listentry-even':'gfg-listentry-odd';
    var listEntry = this.createDiv_(className);
    var link = this.createLink_(entries[i].link,
                                entries[i].title,
                                this.options.linkTarget);
    listEntry.appendChild(link);
    if (this.options.pauseOnHover) {
      listEntry.onmouseover = this.bind_(this.listMouseOver_, resultIndex, i);
      listEntry.onmouseout = this.bind_(this.listMouseOut_, resultIndex, i);
    }
    entries[i].listEntry = listEntry;
    node.appendChild(listEntry);
  }
  if (node == this.nodes.list) {
    this.entries = entries;
  }
}

/**
 * Begin to display the entries.
 * @private
 */
GFdynamicFeedControl.prototype.displayEntries_ = function() {
  this.entryIndex = 0;
  this.displayCurrentEntry_();
  this.setDisplayTimer_();
  this.started = true;
}

/**
 * Display next entry.
 * @private
 */
GFdynamicFeedControl.prototype.displayNextEntry_ = function() {
  // Check to see if we have been orphaned and need to cleanup..
  if (this.options.autoCleanup && this.isOrphaned_()) {
      this.cleanup_();
      return;
  }

  if (++this.entryIndex >= this.entries.length) {
    // End of list, see if we should rotate feeds..
    if (this.results.length > 1) {
      if (++this.resultIndex >= this.results.length) {
        this.resultIndex = 0;
      }
      this.displayResult_(this.resultIndex);
      return;
    } else {
      this.entryIndex = 0;
    }
  }

  if (this.options.transitionCallback) {
    this.options.transitionCallback(this.entries[this.entryIndex]);
  }
  this.displayCurrentEntry_();
  this.setDisplayTimer_();
}

/**
 * Display current entry.
 * @private
 */
GFdynamicFeedControl.prototype.displayCurrentEntry_ = function() {
  this.clearNode_(this.nodes.entry);
  this.current = this.entries[this.entryIndex].html;
  this.current.style.top = '0px';
  this.nodes.entry.appendChild(this.current);
  this.createOverlay_();
  
  // Expand the blog who's post is being displayed
  if(this.options.collapseable) {
    var feedTitle = null;
    
    for (var i=0; i < this.results.length; i++) {
      if(this.results[i].feed.entries == this.entries) {
        feedTitle = this.results[i].feed.title;
      }
    }

    var els = this.collapseElements;

    for (var i=0; i < els.length; i++) {
      var el = els[i];
      var divfeedTitle = el.collapse.previousSibling.innerHTML;
      var expandClicker = el.collapse;
      if(feedTitle == divfeedTitle) {
        if(this.ie) {
          expandClicker.click();
        } else {
          expandClicker.onclick();
        }

      }
    }
  }
  
  if (this.currentList) {
    var className = 'gfg-listentry ';
    className += (this.currentListIndex%2)?
        'gfg-listentry-even':'gfg-listentry-odd';
    this.currentList.className = className;
  }
  this.currentList = this.entries[this.entryIndex].listEntry;
  this.currentListIndex = this.entryIndex;
  var className = 'gfg-listentry gfg-listentry-highlight ';
  className += (this.currentListIndex%2)?
       'gfg-listentry-even':'gfg-listentry-odd';
  this.currentList.className = className;
}

/**
 * Simulated mouse hover events for list entries.
 * @private
 */
GFdynamicFeedControl.prototype.listMouseHover_ = function(resultIndex,
                                                          listIndex) {
  var result = this.results[resultIndex];
  var listEntry = result.feed.entries[listIndex].listEntry;
  listEntry.selectTimer = null;
  this.clearTransitionTimer_();
  this.clearDisplayTimer_();
  this.resultIndex = resultIndex;
  this.entries = result.feed.entries;
  this.entryIndex = listIndex;
  this.displayCurrentEntry_();
}

/**
 * Mouse over events for list entries.
 * @private
 */
GFdynamicFeedControl.prototype.listMouseOver_ = function(resultIndex,
                                                         listIndex) {
  var result = this.results[resultIndex];
  var listEntry = result.feed.entries[listIndex].listEntry;
  var cb = this.bind_(this.listMouseHover_, resultIndex, listIndex);
  listEntry.selectTimer = setTimeout(cb, this.options.hoverTime);
}

/**
 * Mouse out events for list entries.
 * @private
 */
GFdynamicFeedControl.prototype.listMouseOut_ = function(resultIndex, listIndex) {
  var result = this.results[resultIndex];
  var listEntry = result.feed.entries[listIndex].listEntry;
  if (listEntry.selectTimer) {
    clearTimeout(listEntry.selectTimer);
    listEntry.selectTimer = null;
  } else {
    this.setDisplayTimer_();
  }
}

/**
 * Mouse over events for main entry.
 * @private
 */
GFdynamicFeedControl.prototype.entryMouseOver_ = function(e) {
  this.clearDisplayTimer_();
  if (this.transitionTimer) {
    this.clearTransitionTimer_();
    this.displayCurrentEntry_();
  }
}

/**
 * Mouse out events for main entry.
 * @private
 */
GFdynamicFeedControl.prototype.entryMouseOut_ = function(e) {
  this.setDisplayTimer_();
}

/**
 * Create the overlay div. This hack is for IE and transparency effects.
 * @private
 */
GFdynamicFeedControl.prototype.createOverlay_ = function() {
  if (this.current == null) return;
  // Create div lazily and hold on to it..
  if (this.overlay == null) {
    var overlay = this.createDiv_('gfg-entry');
    overlay.style.position = 'absolute';
    overlay.style.top = '0px';
    overlay.style.left = '0px';
    this.overlay = overlay;
  }
  this.setOpacity_(this.overlay, 0);
  this.nodes.entry.appendChild(this.overlay);
}

/**
 * Sets the display timer.
 * @private
 */
GFdynamicFeedControl.prototype.setDisplayTimer_ = function() {
  if (this.displayTimer) {
    this.clearDisplayTimer_();
  }
  var cb = this.bind_(this.setFadeOutTimer_);
  this.displayTimer = setTimeout(cb, this.options.displayTime);
};

/**
 * Class helper method for the time now in milliseconds
 * @private
 */
GFdynamicFeedControl.timeNow = function() {
  var d = new Date();
  return d.getTime();
};

/**
 * Transition animation for fadeout. Cleanup when finished.
 * @private
 */
GFdynamicFeedControl.prototype.fadeOutEntry_ = function() {
  if (this.overlay) {
    var delta = this.fadeOutDelta;
    var ts = this.options.transitionStep;
    var now = GFdynamicFeedControl.timeNow();
    var tick = now - this.lastTick;
    this.lastTick = now;
    delta *= (tick/ts);

    var op = this.overlay.opacity + delta;
    // Overlay opacity
    this.setOpacity_(this.overlay, op);
    // Scroll down
    if (this.options.scrollOnFadeOut && (op > .5)) {
      var r = (op-.5)*2;
      var newTop = Math.round(this.current.offsetHeight * r);
      this.current.style.top = newTop + 'px';
    }
    if (op < 1) return;
  }
  // Finished.
  this.clearTransitionTimer_();
  this.displayNextEntry_();
};

/**
 * Sets the transition timer for fadeout.
 * @private
 */
GFdynamicFeedControl.prototype.setFadeOutTimer_ = function() {
  this.clearTransitionTimer_();
  this.lastTick = GFdynamicFeedControl.timeNow();
  var cb = this.bind_(this.fadeOutEntry_);
  this.transitionTimer = setInterval(cb, this.options.transitionStep);
};

/**
 * Clear the transition timer. Used to prevent leaks.
 * @private
 */
GFdynamicFeedControl.prototype.clearTransitionTimer_ = function() {
  if (this.transitionTimer) {
    clearInterval(this.transitionTimer);
    this.transitionTimer = null;
  }
};

/**
 * Clear the display timer.
 * @private
 */
GFdynamicFeedControl.prototype.clearDisplayTimer_ = function() {
  if (this.displayTimer) {
    clearTimeout(this.displayTimer);
    this.displayTimer = null;
  }
};

/**
 * Setup our own subcontainer to the user supplied container.
 * @private
 */
GFdynamicFeedControl.prototype.createSubContainers_ = function() {
  var nodes = this.nodes;
  var container = this.nodes.container;

  this.clearNode_(container);
  if (this.options.horizontal) {
    container = this.createDiv_('gfg-horizontal-container');
    nodes.root = this.createDiv_('gfg-horizontal-root');
    this.nodes.container.appendChild(container);
  } else {
    nodes.root = this.createDiv_('gfg-root');
  }
  nodes.title = this.createDiv_('gfg-title');
  nodes.entry = this.createDiv_('gfg-entry');
  nodes.list = this.createDiv_('gfg-list');
  nodes.root.appendChild(nodes.title);
  nodes.root.appendChild(nodes.entry);

  if (!this.options.horizontal && this.options.stacked) {
    var newTitle = this.createDiv_('gfg-subtitle');
    nodes.root.appendChild(newTitle);
    this.setTitle_(this.results[0].feed, newTitle);
    
    if(this.options.collapseable) {
      var collapseLink = document.createElement('div');
      collapseLink.className = 'gfg-collapse-open';
      newTitle.appendChild(collapseLink);
      collapseLink.onclick = this.toggleCollapse(this, nodes.list, collapseLink);
      this.collapseElements.push({
        list : nodes.list,
        collapse : collapseLink
      });
      nodes.list.style.display = 'block';
    }
    
    var clearFloat = document.createElement('div');
    clearFloat.className = 'clearFloat';
    newTitle.appendChild(clearFloat);
  }
  
  nodes.root.appendChild(nodes.list);
  container.appendChild(nodes.root);

  if (this.options.pauseOnHover) {
    nodes.entry.onmouseover = this.bind_(this.entryMouseOver_);
    nodes.entry.onmouseout = this.bind_(this.entryMouseOut_);
  }

  // Add Branding.
  if (this.options.horizontal) {
    nodes.branding = this.createDiv_('gfg-branding');
    google.feeds.getBranding(nodes.branding, google.feeds.VERTICAL_BRANDING);
    container.appendChild(nodes.branding);
  }
};

/**
 * Helper method to properly clear a node and its children.
 * @param {Object} node Node to clear.
 * @private
 */
GFdynamicFeedControl.prototype.clearNode_ = function(node) {
  if (node == null) return;
  var child;
  while ((child = node.firstChild)) {
    node.removeChild(child);
  }
};

/**
 * Helper method to create a div with optional class and text.
 * @param {String} opt_className Optional className for the div.
 * @param {String} opt_text Optional text for the innerHTML.
 * @private
 */
GFdynamicFeedControl.prototype.createDiv_ = function(opt_className, opt_text) {
  var el = document.createElement("div");
  if (opt_text) {
    el.innerHTML = opt_text;
  }
  if (opt_className) { el.className = opt_className; }
  return el;
};

/**
 * Helper method to create a link with href and text.
 * @param {String} href Href URL
 * @param {String} text text for the link.
 * @param {String} opt_target Optional link target.
 * @private
 */
GFdynamicFeedControl.prototype.createLink_ = function(href, text, opt_target) {
  var link = document.createElement('a');
  link.href = href;
  link.innerHTML = text;
  if (opt_target) {
    link.target = opt_target;
  }
  return link;
};

/**
 * Cleanup results on being orphaned.
 * @private
 */
GFdynamicFeedControl.prototype.clearResults_ = function() {
  for (var i=0; i < this.results.length; i++) {
    var result = this.results[i];
    var entries = result.feed.entries;
    for (var i = 0; i < entries.length; i++) {
      var entry = entries[i];
      entry.html = null;
      entry.listEntry.onmouseover = null;
      entry.listEntry.onmouseout = null;
      if (entry.listEntry.selectTimer) {
        clearTimeout(entry.listEntry.selectTimer);
        entry.listEntry.selectTimer = null;
      }
      entry.listEntry = null;
    }
  }
}

/**
 * Check for being orphaned.
 * @private
 */
GFdynamicFeedControl.prototype.isOrphaned_ = function() {
  var root = this.nodes.root;
  var orphaned = false;
  if (!root || !root.parentNode) {
    orphaned = true;
  } else if (this.options.horizontal && !root.parentNode.parentNode) {
    orphaned = true;
  }
  return orphaned;
}

/**
 * Cleanup on being orphaned.
 * @private
 */
GFdynamicFeedControl.prototype.cleanup_ = function() {
  this.started = false;
  // Timer Events.
  this.clearDisplayTimer_();
  this.clearTransitionTimer_();
  // Structures
  this.clearResults_();
  // Nodes
  this.clearNode_(this.nodes.root);
  this.nodes.container = null;
}

/**
 * Helper method to set opacity for nodes.. Also takes into account
 * visibility in general.
 * @param {Element} node element.
 * @param {Number} opacity alpha level.
 * @private
 */
GFdynamicFeedControl.prototype.setOpacity_ = function(node, opacity) {
  if (node == null) return;
  opacity = Math.max(0, Math.min(1, opacity));
  if (opacity == 0) {
    if (node.style.visibility != 'hidden') {
      node.style.visibility = 'hidden';
    }
  } else {
    if (node.style.visibility != 'visible') {
      node.style.visibility = 'visible';
    }
  }
  if (this.ie) {
    var normalized = Math.round(opacity*100);
    node.style.filter = 'alpha(opacity=' + normalized + ')';
  }
  node.style.opacity = node.opacity = opacity;
};

GFgadget = GFdynamicFeedControl;

