
(function() { // BeginSpryComponent

if (typeof Spry == "undefined" || !Spry.Widget || !Spry.Widget.MenuBar2)
{
	alert("SpryMenuBarIEWorkaroundsPlugin.js requires SpryMenu.js!");
	return;
}

var isIE6 = (window.ActiveXObject && !window.XMLHttpRequest);
if (isIE6)
	Spry.Utils.addClassName(document.documentElement, "SpryIsIE6");
var isIE = window.ActiveXObject ? true : false;

var IEWP = Spry.Widget.MenuBar2.IEWorkaroundsPlugin = {
	config: {
		pluginOptionsProp:      "IEWP",
		enablePlugin:           undefined, // true or false, if undefined, defaults to true for IE6-IE8
		stripWhiteSpace:        false,
		useDivs:                undefined, // defaults to true for all IE, false for other browsers.
		useCombinedClassNames:  undefined,	// defaults to true for IE6, false for other IE and other browsers
		miContainerZIndex:      undefined,
		miContainerHoverZIndex: 1000
	},

	initialize: function(mb)
	{
		var opts = mb.setOptions({}, IEWP.config);

		if (mb[opts.pluginOptionsProp])
			mb.setOptions(opts, mb[opts.pluginOptionsProp]);
		
		opts.useDivs = (opts.useDivs != undefined) ? opts.useDivs : isIE;
		opts.useCombinedClassNames = (opts.useCombinedClassNames != undefined) ? opts.useCombinedClassNames : isIE6;

		mb[opts.pluginOptionsProp] = opts;

		// If the enabled property is undefined, we will automatically
		// enable the plugin if running on IE.

		var enabled = (opts.enablePlugin != undefined) ? opts.enablePlugin : isIE;
		if (enabled)
			mb.addObserver(this);
	},

	getOptions: function(mb)
	{
		return mb[IEWP.config.pluginOptionsProp];
	},

	getMenuItemContainer: function(mb, sm)
	{
		return sm ? Spry.Utils.getAncestor(sm, "." + mb.menuItemContainerClass) : null;
	},

	showSubMenuIFrame: function(mb, sm)
	{
		if (!sm.ieIFrame)
		{
			var iframe = document.createElement("iframe");
			iframe.tabIndex = '-1';
			iframe.src = 'javascript:""';
			iframe.frameBorder = '0';
			iframe.scrolling = 'no';
			iframe.style.opacity = "0.01";
			iframe.style.filter = "alpha(opacity=1)";
			iframe.style.position = "absolute";
			sm.ieIFrame = iframe;
		}
	
		var iframe = sm.ieIFrame;
		iframe.style.top = sm.offsetTop + "px";
		iframe.style.left = sm.offsetLeft + "px";
		iframe.style.width = sm.offsetWidth + "px";
		iframe.style.height = sm.offsetHeight + "px";
		sm.parentNode.insertBefore(iframe, sm);
	},

	hideSubMenuIFrame: function(mb, sm)
	{
		if (sm)
		{
			var iframe = sm.ieIFrame;
			if (iframe)
			{
				var p = iframe.parentNode;
				if (p) p.removeChild(iframe);
			}
		}
	},

	stripTextNodes: function(ele)
	{
		var c = ele.firstChild;
		while (c)
		{
			var n = c;
			c = c.nextSibling;
			if (n.nodeType == 3) // Node.TEXT_NODE
				ele.removeChild(n);
		}
	},

	getMenuItemClasses: function(mb, mi)
	{
		// MenuItem[First|Last]?[WithSubMenu]?[Hover]?

		var results = [];

		var posArr = [ "" ];
		if (mb.hasClassName(mi, mb.menuItemFirstClass))
			posArr.push("First");
		if (mb.hasClassName(mi, mb.menuItemLastClass))
			posArr.push("Last");

		var hasSubMenu = mb.hasClassName(mi, mb.menuItemWithSubMenuClass);

		var miClass = mb.menuItemClass;

		for (var i = 0; i < posArr.length; i++)
		{
			var c = miClass + posArr[i];
			results.push(c);
			if (hasSubMenu)
				results.push(c + "WithSubMenu");
		}

		return results;
	},

	getMenuItemHoverClasses: function(mb, mi)
	{
		var results = IEWP.getMenuItemClasses(mb, mi);
		for (var i = 0; i < results.length; i++)
			results[i] += "Hover";
		return results;
	},

	onPostTransformMarkup: function(mb, evt)
	{
		var opts = IEWP.getOptions(mb);

		if (opts.stripWhiteSpace)
		{
			var uls = Spry.$$("ul", mb.element);
			for (var i = 0; i < uls.length; i++)
			{
				var ul = uls[i];
				IEWP.stripTextNodes(ul);
				var eles = mb.getElementChildren(ul);
				for (var j = 0; j < eles.length; j++)
					IEWP.stripTextNodes(eles[j]);
			}
		}

		// IE6 has some issues with gaps between menu items. We can easily fix
		// menu items with no submenus by either stripping the whitespace in and
		// around <ul> and <li> elements, or we can use a zoom:1 property on the <li>
		// elements, but that doesn't fix the gap problem when dealing with menu items
		// that have submenus. To work around this and ease the styling hacks/pains, we
		// can also convert ul/li elements to divs.

		if (opts.useDivs)
		{
			var uls = Spry.$$("ul", mb.element);
			for (var i = 0; i < uls.length; i++)
			{
				var ul = uls[i];
				var div = document.createElement("div");
				if (ul.id) div.id = div.id;
				if (ul.className) div.className = ul.className;
				var children = [];
				var c = ul.firstChild;
				while (c)
				{
					var n = c;
					if (n.nodeName.toLowerCase() == "li")
					{
						n = document.createElement("div");
						if (c.id) n.id = c.id;
						if (c.className) n.className = c.className;
						mb.appendChildNodes(n, mb.extractChildNodes(c));
					}
					children.push(n);
					c = c.nextSibling;
				}
				var p = ul.parentNode;
				p.insertBefore(div, ul);
				p.removeChild(ul);
				mb.appendChildNodes(div, children);
			}
		}

		if (opts.useCombinedClassNames)
		{
			var mis = Spry.$$("." + mb.menuItemClass, mb.element);
			for (var i = 0; i < mis.length; i++)
			{
				var mi = mis[i];
				var classes = IEWP.getMenuItemClasses(mb, mi);
				for (var j = 0; j < classes.length; j++)
					mb.addClassName(mi, classes[j]);
			}
		}
	},

	onPostAddHoverClass: function(mb, evt)
	{
		var opts = IEWP.getOptions(mb);
		if (!opts.useCombinedClassNames)
			return;

		var mi = evt.menuItem;
		var classNames = IEWP.getMenuItemHoverClasses(mb, mi);
		for (var i = 0; i < classNames.length; i++)
			mb.addClassName(mi, classNames[i]);
	},

	onPostRemoveHoverClass: function(mb, evt)
	{
		var opts = IEWP.getOptions(mb);
		if (!opts.useCombinedClassNames)
			return;

		var mi = evt.menuItem;
		var classNames = IEWP.getMenuItemHoverClasses(mb, mi);
		for (var i = 0; i < classNames.length; i++)
			mb.removeClassName(mi, classNames[i]);
	},

	onPreHideSubMenuHierarchy: function(mb, evt)
	{
		var smh = evt.subMenus;
		if (smh && smh.length)
		{
			var opts = IEWP.getOptions(mb);

			for (var i = 0; i < smh.length; i++)
			{
				IEWP.hideSubMenuIFrame(mb, smh[i]);
				if (opts.miContainerHoverZIndex)
				{
					var mic = IEWP.getMenuItemContainer(mb, smh[i]);
					if (mic)
						mic.style.zIndex = (opts.miContainerZIndex ? miContainerZIndex : "" ) + "";
				}
			}
		}
	},

	onPostShowSubMenuHierarchy: function(mb, evt)
	{
		var smh = evt.subMenus;
		if (smh && smh.length)
		{
			var opts = IEWP.getOptions(mb);
			for (var i = 0; i < smh.length; i++)
			{
				IEWP.showSubMenuIFrame(mb, smh[i]);
				if (opts.miContainerHoverZIndex)
				{
					var mic = IEWP.getMenuItemContainer(mb, smh[i]);
					if (mic)
						mic.style.zIndex = opts.miContainerHoverZIndex + "";
				}
			}
		}
	}
};

// We want to add our plugin to the default configuration for MenuBar2 if it is included!

Spry.Widget.MenuBar2.config.plugIns.push(Spry.Widget.MenuBar2.IEWorkaroundsPlugin);

})(); // EndSpryComponent


