﻿if (typeof (Tangora) == 'undefined') var Tangora = {};
Tangora.Layout = new LayoutController();

function LayoutController()
{
    var _convertedLayouts = [];
	this.RegisteredLayouts = [];
	this.RegisteredLiquidLayouts = [];

	this.RegisterLayout = function (id, balanceMode, balancedColumns, blocklistMode)
	{
		if (!balanceMode) balanceMode = 'Automatic';
		if (!balancedColumns) balancedColumns = null;
		if (!blocklistMode) blocklistMode = false;
		this.RegisteredLayouts.push({ id: id, balanceMode: balanceMode, balancedColumns: balancedColumns, blocklistMode: blocklistMode });
	}

	this.RegisterLiquidLayout = function (id, blocklistMode)
	{
		var version = parseInt(this.GetIEVersion(), 10);
		var register = (version > 0 && version < 8);
		if (!register && document.documentMode && document.documentMode == 7) register = true;
		if (register)
		{
			this.RegisteredLiquidLayouts.push({ id: id, blocklistMode: blocklistMode });
		}
    }

    // ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    // NOTE:
    // When IE7 and below encounters a version 2.0 layout (display:table) a conversion is carried out to transform the layout to a version 1.0 layout (floated divs).
    // In this conversion the column balancing script is being run as default unless, the user has explicitly added the sitelayout to Tangora.Layout.CancelDefaultFallbackColumnBalancing().

// ***********************************************************************************
// TEMP: 
// Commented out - new resize script eliminates the need for this?
// Search for SEARCH: CONVERSION_API to comment back in or remove when proven unneeded
// ***********************************************************************************

//    var _firstResizeRun = true;
//    var _fallbackBalancedColumns = [];              // contains columns that must be balanced manually
//    var _cancelledDefaultFallbackSitelayouts = [];  // contains sitelayouts that should bypass the default column balancing of a version 2.0 -> 1.0 conversion
//    
//    // Public exposed: Use this method to bypass the default column balancing of a version 2.0 -> 1.0 conversion
//    this.CancelDefaultFallbackColumnBalancing = function (sitelayoutId)
//    {
//        _cancelledDefaultFallbackSitelayouts.push(sitelayoutId);
//    }
//     
//    // Public exposed: Columns can be added and balanced individually via this method which also implicitly sets the sitelayout to bypass the default column balancing of a version 2.0 -> 1.0 conversion
//    this.AddFallbackBalancedColumn = function (sitelayoutId, columnId)
//    {
//        _cancelledDefaultFallbackSitelayouts.push(sitelayoutId);
//        _fallbackBalancedColumns.push([sitelayoutId, columnId]);
//    }

//    // Checks if the default version 2.0 -> 1.0 column balancing should be applied (defaults to true)
//    function applyDefaultFallbackBalancing(sitelayoutId)
//    {
//        for (var i = 0; i < _cancelledDefaultFallbackSitelayouts.length; i++)
//        {
//            if (_cancelledDefaultFallbackSitelayouts[i] == sitelayoutId) return false;
//        }
//        return true;
//    }

//    // Makes sure individual balanced columns get balanced
//    function initFallbackBalancing(sitelayoutId, blocklistMode)
//    {
//        var cols = [];
//        var fbc = _fallbackBalancedColumns;
//        for (var i = 0; i < fbc.length; i++)
//        {
//            if (fbc[i][0] == sitelayoutId)
//            {
//                cols.push(fbc[i][1]);
//            }
//        }
//        if (cols.length > 0)
//        {
//            // if any columns are to be balanced manually, simply add them to the registered layouts array...
//            Tangora.Layout.RegisteredLayouts.push({ id: sitelayoutId, balanceMode: 'Manual', balancedColumns: cols, blocklistMode: blocklistMode });
//        }
//    }
    // ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


	this.StartupScripts = function ()
	{
		// Ensure highlights in visual designer layouts
		highlightSearchwords();
	}


	this.IE6Patch = function ()
	{
		// Sets heights according to min-height
		var divs = document.getElementsByTagName('div');
		for (var i = 0; i < divs.length; i++)
		{
			var minHeight = Tangora.Layout.GetStyle(divs[i], 'min-height');
			var hasHeight = typeof (divs[i].style.height) != 'undefined' && divs[i].style.height != null && divs[i].style.height.length > 0 && divs[i].style.height != 'auto';
			if (minHeight != 'auto' && !hasHeight)
			{
				divs[i].style.height = Tangora.Layout.GetStyle(divs[i], 'min-height');
				divs[i].style.overflowY = 'visible';
			}
		}
	}

	this.IE6Hover = function ()
	{
		// Adds hover class to li-elements for css-hover navigations to work in IE6.
		var lis = document.getElementsByTagName("li");
		for (var i = 0; i < lis.length; i++)
		{
			if (lis[i].className.indexOf('navigationlistitem') != -1)
			{
				lis[i].onmouseover = function ()
				{
					this.className += ' ie6hover';
				}
				lis[i].onmouseout = function ()
				{
					this.className = this.className.replace(new RegExp(' ie6hover\\b'), '');
				}
			}
		}

		// Sets correct navigation-styles, depending on horizontal or vertical navigation.
		// We need to do this post-processing because IE6 doesn't support multiple classnames,
		// so later-loaded navigation stylesheets may target level1 with undesired styles.

		// First find the navigation type of level 1 in the css-hover hierarchy:
		var navtype = '';
		var divs = document.getElementsByTagName('div');
		var wrapper = null;
		for (var i = 0; i < divs.length; i++)
		{
			if (divs[i].className.indexOf('sfnavlevel1') != -1)
			{
				navtype = divs[i].className.replace('sfnavlevel1', '').replace(/\s/g, '');
				wrapper = divs[i].firstChild;
				break;
			}
		}

		// Then find out if it id a vertical style navigation adn what the navigation item width is:
		var vertical = false;
		var width = '150px'
		if (navtype != '')
		{
			for (var i = 0; i < document.styleSheets.length; i++)
			{
				if (document.styleSheets[i].href.indexOf(navtype + '/navigation.css') != -1)
				{
					for (var j = 0; j < document.styleSheets[i].rules.length; j++)
					{
						if (document.styleSheets[i].rules[j].selectorText.toLowerCase() == 'div.sfnavlevel1 .navigationwrapper')
						{
							if (/float\s*:\s*left/i.test(document.styleSheets[i].rules[j].style.cssText))
							{
								vertical = true;
							}
						}
						if (document.styleSheets[i].rules[j].selectorText.toLowerCase() == 'div.sfnavlevel1 li .navigationwrapper')
						{
							if (/width\s*:\s*(\d*)(%|em|px|pt)/i.test(document.styleSheets[i].rules[j].style.cssText))
							{
								width = RegExp.$1 + RegExp.$2;
							}
						}
					}
					break;
				}
			}
		}

		// Finally set the correct styles of level 1:
		var css = '';
		if (vertical)
		{
			css += 'div.sfnavlevel1 .navigationwrapper { clear:none; float:left; width:100%; }\n';
			css += 'div.sfnavlevel1 div.navigationwrapper ul.navigationlist li.navigationlistitem a,\n';
			css += 'div.sfnavlevel1 ul.navigationlist li.navigationlistitem { float:left; width:100%; }\n';
			css += 'div.sfnavlevel1 div.sfnavlevel2 { clear:none; }\n';
		}
		else
		{
			css += 'div.sfnavlevel1 .navigationwrapper { clear:both; float:none; width:auto; }\n';
			css += 'div.sfnavlevel1 div.navigationwrapper ul.navigationlist li.navigationlistitem a,';
			css += 'div.sfnavlevel1 ul.navigationlist li.navigationlistitem { float:left; }\n';
			css += 'div.sfnavlevel1 div.sfnavlevel2 ul.navigationlist li.navigationlistitem { width:' + width + '; }\n';
			css += 'div.sfnavlevel1 div.sfnavlevel2 { clear:left; }\n';
		}
		if (wrapper)
		{
			var styleElement = document.createElement('style');
			styleElement.setAttribute('type', 'text/css');
			styleElement.styleSheet.cssText = css;
			var head = document.getElementsByTagName('head')[0];
			head.appendChild(styleElement);
		}
	}

	this.GetIEVersion = function ()
	{
		// Some IE useragent contains both MSIE 6.0 & MSIE 7.0, so we get the highest version...
		var version = '0.0';
		var maxversion = '0.0';
		try
		{
			var ua = navigator.userAgent;
			var start = new Date().getTime();
			while (/msie\s\d*\.\d*/gi.test(ua))
			{
				ua = ua.substr(RegExp.lastIndex);
				version = RegExp.lastMatch.replace(/[^\d\.]/gi, '');
				if (parseInt(version, 10) > parseInt(maxversion, 10)) maxversion = version;
				if (new Date().getTime() - start > 100) break;
			}
		}
		catch (err) { }
		return maxversion;
	}

	this.Initialize = function () {
	    if (typeof (Tangora.Events) != 'undefined') {
	        Tangora.Events.AddHandler(window, 'onload', this.Resize);
	        Tangora.Events.AddHandler(window, 'onload', this.StartupScripts);

	        var version = parseInt(this.GetIEVersion(), 10);
	        if (version > 0) {
	            if (version == 6) {
	                Tangora.Events.AddHandler(window, 'onload', this.IE6Patch);
	                Tangora.Events.AddHandler(window, 'onload', this.IE6Hover);
	            }
	            if (version < 8) {
	                Tangora.Events.AddHandler(window, 'onresize', this.ResizeDelay);
	            }
	        }

	        // IE7 needs a little help to render the breadcrumb correctly...
	        Tangora.Browser.GetType(); // this line is needed to load Tangora.Browser
	        if (Tangora.Browser.IE && Tangora.Browser.Version == '7.0') {
	            try {
	                if (location.href == top.location.href) $ts.addEvent(window, 'DOMContentLoaded', function () { $chain('UL.breadcrumb LI').setStyle('display', 'inline') });
	                else $ts.addEvent(window, 'load', function () { $chain('UL.breadcrumb LI').setStyle('display', 'inline') });
	            }
	            catch (e) {
	                $ts.addEvent(window, 'load', function () { $chain('UL.breadcrumb LI').setStyle('display', 'inline') });
	            }
	        }
	    }
	    else // Manager - EditWebPage
	    {
	        Tangora.Core.AddHandler(window, 'load', this.Resize);
	        Tangora.Core.AddHandler(window, 'resize', this.Resize);
	    }
	}

	// resize delay is needed because IE fires resize events continuously so we will wait until no events has been dispatched for half a second 
	var resizeTimeout = null;
	this.ResizeDelay = function ()
	{
		clearTimeout(resizeTimeout);
		resizeTimeout = setTimeout(Tangora.Layout.Resize, 500);
	}

	this.Resize = function ()
	{
	    // For debugging:
	    if (/tangoralayoutresize=false/i.test(location.href) || Tangora.ByPassResizeScript)
	    {
	        return;
	    }

	    var tl = Tangora.Layout;

	    // SEARCH: CONVERSION_API
        //	    if (_firstResizeRun)
	    //	    {
	    //	        _firstResizeRun = false;
	    //	        var rll = tl.RegisteredLiquidLayouts;
	    //	        for (var i = 0; i < rll.length; i++)
	    //	        {
	    //	            initFallbackBalancing(rll[i].id, rll[i].blocklistMode);
	    //	        }
	    //	    }
	    // -------------------------------------------------------


	    // returns all layouts in the page sorted according to hierarchy, lowest first, top last.
	    function getSortedLayouts()
	    {
	        var layouts = [];
	        var divs = document.getElementsByTagName('div');

	        // get all version 1.0 layouts
	        for (var i = 0; i < tl.RegisteredLayouts.length; i++)
	        {
	            var tlr = tl.RegisteredLayouts[i];
	            if (tlr.blocklistMode)
	            {
	                for (var j = 0; j < divs.length; j++)
	                {
	                    if (divs[j].className == tlr.id)
	                    {
	                        layouts.push({ version: '1.0', elm: divs[j], id: tlr.id, balanceMode: tlr.balanceMode, balancedColumns: tlr.balancedColumns, blocklistMode: tlr.blocklistMode });
	                    }
	                }
	            }
	            else
	            {
	                layouts.push({ version: '1.0', elm: document.getElementById(tlr.id), id: tlr.id, balanceMode: tlr.balanceMode, balancedColumns: tlr.balancedColumns, blocklistMode: tlr.blocklistMode });
	            }
	        }

	        // get all version 2.0 layouts
	        for (var i = 0; i < tl.RegisteredLiquidLayouts.length; i++)
	        {
	            var tlr = tl.RegisteredLiquidLayouts[i];
	            if (tlr.blocklistMode)
	            {
	                for (var j = 0; j < divs.length; j++)
	                {
	                    if (divs[j].className == tlr.id)
	                    {
	                        layouts.push({ version: '2.0', elm: divs[j], id: tlr.id, balanceMode: 'Automatic', balancedColumns: null, blocklistMode: tlr.blocklistMode });
	                    }
	                }
	            }
	            else
	            {
	                layouts.push({ version: '2.0', elm: document.getElementById(tlr.id), id: tlr.id, balanceMode: 'Automatic', balancedColumns: null, blocklistMode: tlr.blocklistMode });
	            }

	        }

	        // method for sorting the layouts hierarchially
	        function getTop()
	        {
	            var layout = null;
	            for (var i = 0; i < layouts.length; i++)
	            {
	                layout = layouts[i];
	                for (var j = 0; j < layouts.length; j++)
	                {
	                    if (i == j) continue;
	                    var divs = layouts[j].elm.getElementsByTagName('div');
	                    for (var k = 0; k < divs.length; k++)
	                    {
	                        if (divs[k] == layout.elm)
	                        {
	                            layout = null;
	                            break;
	                        }
	                    }
	                    if (!layout) break;
	                }
	                if (layout)
	                {
	                    layouts.splice(i, 1);
	                    break;
	                }
	            }
	            return layout;
	        }

	        var hierarchy = [];
	        var top = getTop();
	        while (top)
	        {
	            hierarchy.push(top);
	            top = getTop();
	        }
	        hierarchy.reverse();

	        return hierarchy;
	    }

	    if (tl.RegisteredLiquidLayouts.length > 0)
	    {
	        // version 2.0 layouts are present so we need to take the order of sorting into account...

	        var layouts = getSortedLayouts();
	        for (var i = 0; i < layouts.length; i++)
	        {
	            var layout = layouts[i];
	            if (layout.version == '1.0')
	            {
                    // --------------------------------------------------------------------
	                // HDN 10.06.2011:
	                // The conversion is run on version 1 layouts too (when layout 2 versions are present) because in some cases the version 2 styles will hit the version 1 styles.
	                // We have decided to let the resize script deal with this for now, instead of starting a css specificity war...
	                tl.ConvertLiquidLayout(layout.elm);
	                // --------------------------------------------------------------------

	                tl.AdjustColumns(layout.elm, layout.balanceMode, layout.balancedColumns, layout.blocklistMode); 
	            }
	            else if (layout.version == '2.0')
	            {
	                tl.ConvertLiquidLayout(layout.elm);
	                //SEARCH: CONVERSION_API
	                //if (applyDefaultFallbackBalancing(layout.id))
	                //{
	                    tl.AdjustColumns(layout.elm, layout.balanceMode, layout.balancedColumns, layout.blocklistMode);
	                //}
	            }
	        }
	    }
	    else
	    {
	        // no version 2.0 layouts - we run the column balancing script the ususal way...

	        for (var i = 0; i < tl.RegisteredLayouts.length; i++)
	        {
	            var tlr = tl.RegisteredLayouts[i];
	            if (tlr.balanceMode == 'Manual' && tlr.balancedColumns == null) continue; // No columns to balance
	            if (tlr.blocklistMode)
	            {
	                // In blocklistmode the layout id is set as classname to avoid id-clashes so we have to find the wrapper(s) by the class name
	                var divs = document.getElementsByTagName('div');
	                for (var j = 0; j < divs.length; j++)
	                {
	                    if (divs[j].className == tlr.id)
	                    {
	                        tl.AdjustColumns(divs[j], tlr.balanceMode, tlr.balancedColumns, tlr.blocklistMode);
	                    }
	                }
	            }
	            else
	            {
	                tl.AdjustColumns(document.getElementById(tlr.id), tlr.balanceMode, tlr.balancedColumns, tlr.blocklistMode);
	            }
	        }
	    }


	    // In IE6, IE7 there is a bug that incorrectly repositions all absolute/relative positioned elements if their container height is changed.
	    // Container-heights do change in AdjustColumns, so below hack is needed to force absolute positioned elements back in place.
	    // The flag Tangora.FixIEPositionAbsoluteBug should be set to true in the headsection of the layout. 
	    if (Tangora.FixIEPositionAbsoluteBug && navigator.userAgent.indexOf('MSIE') != -1)
	    {
	        var elms = document.body.getElementsByTagName('*');
	        for (var i = 0; i < elms.length; i++)
	        {
	            var pos = tl.GetStyle(elms[i], 'position');
	            if (pos != null)
	            {
	                elms[i].style.position = 'static';
	                if (pos.toLowerCase() == 'absolute')
	                {
	                    elms[i].style.position = 'absolute';
	                }
	                else if (pos.toLowerCase() == 'relative')
	                {
	                    elms[i].style.position = 'relative';
	                }
	            }
	        }
	    }
	}

	this.AdjustColumns = function (wrapper, balanceMode, balancedColumns, blocklistMode)
	{
		if (wrapper)
		{
			var coll = this.GetColumnSets(wrapper);
			for (var i = 0; i < coll.length; i++)
			{
				this.EnsureColumnHeights(coll[i], balanceMode, balancedColumns, blocklistMode);
			}
		}
	}

	this.GetStyle = function (elm, attribute)
	{
		if (elm.currentStyle)
		{
			r = elm.currentStyle[this.CssCamelCase(attribute)];
		}
		else if (document.defaultView && document.defaultView.getComputedStyle)
		{
			var styles = document.defaultView.getComputedStyle(elm, null);
			if (styles) r = styles.getPropertyValue(attribute);
		}
		return r;
	}

	this.EnsureColumnHeights = function (colset, balanceMode, balancedColumns, blocklistMode)
	{
	    var cols = this.GetColumns(colset);
	    // reset columnset wrapper height
	    colset.style.height = '';
	    // first, iterate all columns in this columnset and find the max height
	    var maxH = 0;
	    for (var k = 0; k < cols.length; k++)
	    {
	        // adjust any inner columns before measuring this column
	        this.AdjustColumns(cols[k], balanceMode, balancedColumns, blocklistMode);
	        // Height is reset according to the font-size.
	        var fontSize = this.GetStyle(cols[k], 'font-size');
	        if (navigator.userAgent.indexOf('MSIE 6.0') == -1 || this.GetStyle(cols[k], 'height') == 'auto')
	        {
	            if (typeof (cols[k].converted) != 'undefined')
	            {
	                // This specific case takes care of IE7 and columns that has been converted from version 2.0 to 1.0 layouts.
	                cols[k].style.height = 'auto';
	            }
	            else
	            {
	                cols[k].style.height = (fontSize == '0pt') ? '0px' : '';
	            }
	        }
	        // Get column offsetheight and check if it's larger than the current max height 
	        var h = cols[k].offsetHeight;
	        if (h > maxH) maxH = h;
	    }
	    // now, iterate all columns again and set their height to max height
	    for (var l = 0; l < cols.length; l++)
	    {
	        // the page uses the standards mode box model, so we have to subtract all affecting styles,
	        // ie. border-top/-bottom, margin-top/-bottom and padding-top/-bottom, from max height before setting it
	        var subt = this.GetHeightSubtracts(cols[l]);
	        var newH = maxH - subt;
	        if (newH < 0) newH = 0;
	        if (balanceMode != 'Manual' || isBalancedColumn(cols[l]))
	        {
	            cols[l].style.height = newH + 'px';
	        }
	    }
	    colset.style.height = maxH + 'px';

	    function isBalancedColumn(col)
	    {
	        if (!balancedColumns) return false;
	        for (var h = 0; h < balancedColumns.length; h++)
	        {
	            if (!blocklistMode && col.id == balancedColumns[h]) return true;
	            else if (blocklistMode && col.className.indexOf(balancedColumns[h]) != -1) return true;
	        }
	        return false;
	    }
	}

	this.GetColumnSets = function (wrapper)
	{
		return this.GetChildNodes(wrapper, 'div', 'layoutcolumnset');
	}

	this.GetColumns = function (colset)
	{
		return this.GetChildNodes(colset, 'div', 'layoutcolumn');
	}

	this.GetChildNodes = function (parentElement, childTagName, childClassName)
	{
		var coll = [];
		for (var i = 0; i < parentElement.childNodes.length; i++)
		{
			var chld = parentElement.childNodes[i];
			if (chld.nodeType != 3 && chld.tagName && chld.tagName.toLowerCase() == childTagName.toLowerCase() && chld.className.indexOf(childClassName) > -1 && chld.parentNode == parentElement) coll.push(chld);
		}
		return coll;
	}

	this.GetHeightSubtracts = function (elm)
	{
		var affectingStyles = ['border-top-width', 'border-bottom-width', 'padding-top', 'padding-bottom', 'margin-top', 'margin-bottom'];
		return Tangora.Layout.GetSubtracts(elm, affectingStyles);
	}

	this.GetWidthSubtracts = function (elm, marginsOnly)
	{
		var affectingStyles = ['border-left-width', 'border-right-width', 'padding-left', 'padding-right', 'margin-left', 'margin-right'];
		if (marginsOnly) affectingStyles = ['margin-left', 'margin-right'];
		return Tangora.Layout.GetSubtracts(elm, affectingStyles);
	}

	this.GetSubtracts = function (elm, affectingStyles)
	{
		var r = 0;
		for (var i = 0; i < affectingStyles.length; i++)
		{
			var style = affectingStyles[i];
			var borderStyleWatch = (style.indexOf('border') > -1) ? this.CssCamelCase(style.substr(0, style.lastIndexOf('-')) + 'Style') : null;
			if (elm.currentStyle)
			{
				var n;
				if (borderStyleWatch && elm.currentStyle[borderStyleWatch] == 'none') n = 0;
				else n = parseInt(elm.currentStyle[this.CssCamelCase(style)]);
				if (!isNaN(n)) r += n;
			}
			else if (document.defaultView && document.defaultView.getComputedStyle)
			{
				var currStyle = document.defaultView.getComputedStyle(elm, null);
				if (currStyle)
				{
					var n = parseInt(currStyle.getPropertyValue(style));
					if (!isNaN(n)) r += n;
				}
			}
		}
		return r;
	}

	this.CssCamelCase = function (s)
	{
		var r = '';
		var lastWasHyphen = false;
		for (var i = 0; i < s.length; i++)
		{
			var c = s.substr(i, 1);
			if (c == '-')
			{
				lastWasHyphen = true;
			}
			else if (lastWasHyphen)
			{
				r += c.toUpperCase();
				lastWasHyphen = false;
			}
			else
			{
				r += c;
			}
		}
		return r;
	}

	this.SetBrowserSpecificStylesheet = function (file, conditions, andOr)
	{
		function compareVersion(v1, v2, operator)
		{
			var a = parseFloat(v1);
			var b = parseFloat(v2)
			switch (operator)
			{
				case 'equal': return a == b; break;
				case 'not_equal': return a != b; break;
				case 'less_than': return a < b; break;
				case 'greater_than': return a > b; break;
				case 'less_than_or_equal': return a <= b; break;
				case 'greater_than_or_equal': return a >= b; break;
			}
		}

		var show = false;
		for (var i = 0; i < conditions.length; i++)
		{
			var cnd = conditions[i];
			var browser = navigator.userAgent;
			var version = '';
			if (cnd.Browser)
			{
				switch (cnd.Browser)
				{
					case 'Internet Explorer':
						if (/msie\s(\d+\.\d)/i.test(browser))
						{
							if (cnd.Version == 'all') show = true;
							else show = compareVersion(RegExp.$1, cnd.Version, cnd.Operator);
						}
						break;
					case 'FireFox':
						if (/firefox\/(\d+\.\d)/i.test(browser))
						{
							if (cnd.Version == 'all') show = true;
							else show = compareVersion(RegExp.$1, cnd.Version, cnd.Operator);
						}
						break;
					case 'Safari':
						if (/safari/i.test(browser) && !/chrome/i.test(browser))
						{
							if (cnd.Version == 'all') show = true;
							else if (/version\/(\d+\.\d)/i.test(browser)) show = compareVersion(RegExp.$1, cnd.Version, cnd.Operator);
							else show = compareVersion('2.0', cnd.Version, cnd.Operator); // safari version 2.0 and below does not have version number in useragent string
						}
						break;
					case 'Chrome':
						if (/chrome\/(\d+\.\d)/i.test(browser))
						{
							if (cnd.Version == 'all') show = true;
							else show = compareVersion(RegExp.$1, cnd.Version, cnd.Operator);
						}
						break;
					case 'Opera':
						if (/opera/i.test(browser))
						{
							if (cnd.Version == 'all') show = true;
							else if (/version\/(\d+\.\d)/i.test(browser)) show = compareVersion(RegExp.$1, cnd.Version, cnd.Operator);
							else if (/opera\/(\d+\.\d)/i.test(browser)) show = compareVersion(RegExp.$1, cnd.Version, cnd.Operator);
						}
						break;
				}
			}
			else if (cnd.Regex)
			{
				var regex = new RegExp(cnd.Regex, "gi");
				show = regex.test(browser);
			}
			if (!show && andOr == 'and') break;
			if (show && andOr == 'or') break;
		}
		if (show)
		{
			document.write('<link rel="stylesheet" type="text/css" href="' + file + '">');
		}
	}

// -----------------------------------------------------------

	this.ConvertLiquidLayout = function (layout)
	{
	    var isConverted = false;
	    for (var i = 0; i < _convertedLayouts.length; i++)
	    {
	        if (_convertedLayouts[i] == layout)
	        {
	            isConverted = true;
	            break;
	        }
	    }
	    if (isConverted) return;
	    else _convertedLayouts.push(layout);


	    var tl = Tangora.Layout;

	    function convertColumnSetsFromTableToFloat(wrapper)
	    {
	        var colsets = tl.GetColumnSets(wrapper);
	        for (var i = 0; i < colsets.length; i++)
	        {
	            // the columnset
	            var colset = colsets[i];
	            colset.style.display = 'block';
	            colset.style.clear = 'both';
	            colset.style.width = 'auto';

	            // each column in columnset
	            var cols = tl.GetColumns(colset);
	            for (var j = 0; j < cols.length; j++)
	            {
	                var col = cols[j];
	                col.style.display = 'block';
	                col.style.overflow = 'hidden';
	                col.style.styleFloat = 'left';

	                // To convert a version 2.0 height to a version 1.0 height we must subtract paddings etc, as version 2.0 uses border-box and version 1.0 uses content-box.
	                var colheight = tl.GetStyle(col, 'height');
	                if (/^(\d+)px$/i.test(colheight))
	                {
	                    colheight = Math.max(0, parseInt(RegExp.$1, 10) - tl.GetHeightSubtracts(col)) + 'px';
	                }
	                else
	                {
	                    colheight = 'auto';
	                }

	                col.style.height = colheight;
	                col.style.minHeight = Math.max(0, (col.offsetHeight - tl.GetHeightSubtracts(col))) + 'px';
	                col.converted = true; // this expando tells the column balancing script that this column needs to get a different treatment...
	                convertColumnSetsFromTableToFloat(col);
	            }

	            // the float breaker
	            var fb = tl.GetChildNodes(colset, 'div', 'layoutfloatbreaker')[0];
	            if (fb)
	            {
	                fb.style.display = 'block';
	                fb.style.clear = 'both';
	                fb.style.width = 'auto';
	            }
	        }
	    }

	    convertColumnSetsFromTableToFloat(layout);


	    var width = tl.GetStyle(layout, 'width');
	    if (width.indexOf('%') != -1)
	    {
	        // first run (page load) stores original percent
	        layout.orgpct = parseInt(width, 10);
	    }
	    if (typeof (layout.orgpct) != 'undefined')
	    {
	        // first and additional runs (page load and refreshes) width is calculated as the original percentage of the available space
	        var container = layout.parentNode;
	        while (container != null && container.offsetWidth == 0)
	        {
	            container = container.parentNode;
	        }
	        var subtracts = parseInt(tl.GetStyle(layout, 'padding-left'), 10) + parseInt(tl.GetStyle(layout, 'padding-right'));
	        if (container)
	        {
	            subtracts += parseInt(tl.GetStyle(container, 'padding-left'), 10) + parseInt(tl.GetStyle(container, 'padding-right'));
	        }
	        var offsetWidth = container.offsetWidth * (layout.orgpct / 100);
	        layout.style.width = Math.max(0, offsetWidth - subtracts) + 'px';

	    }

	    tl.ConvertLiquidColumns(layout);
	}

	this.ConvertLiquidColumns = function (wrapper)
	{
	    var tl = Tangora.Layout;
	    var colsets = tl.GetColumnSets(wrapper);
	    for (var i = 0; i < colsets.length; i++)
	    {
	        var colset = colsets[i];
	        var cols = tl.GetColumns(colset);

	        // colset should use all available width
	        colset.style.width = wrapper.style.width;

	        // in first run (page load) the columns still have their original percentage width - we store it in an expando for later retreval
	        for (var j = 0; j < cols.length; j++)
	        {
	            var col = cols[j];
	            var colwidth = tl.GetStyle(col, 'width');
	            if (colwidth.indexOf('%') != -1)
	            {
	                col.orgpct = parseInt(colwidth, 10);
	            }
	        }

	        var usedpx = 0;
	        var usedpct = 0;
	        var pctcols = [];
	        for (var j = 0; j < cols.length; j++)
	        {
	            var col = cols[j];
	            if (typeof (col.orgpct) != 'undefined')
	            {
	                // percentage based column
	                usedpct += col.orgpct;
	                pctcols.push(col);
	            }
	            else
	            {
	                // pixel based column
	                var colwidth = parseInt(tl.GetStyle(col, 'width'), 10);
	                usedpx += colwidth;
	                col.style.width = Math.max(0, colwidth - tl.GetWidthSubtracts(col)) + 'px';
	            }
	        }

	        var colsetWidth = parseInt(colset.style.width, 10);
	        if (isNaN(colsetWidth)) colsetWidth = colset.clientWidth;
	        if (isNaN(colsetWidth)) colsetWidth = colset.offsetWidth;

	        // The percentage based columns should be 100% of what is left after the width of the pixel based columns has been subtracted...
	        var leftover = colsetWidth - usedpx;
	        var pct2px = leftover / usedpct;
	        var pxconverted = 0;

	        for (var j = 0; j < pctcols.length; j++)
	        {
	            var col = pctcols[j];
	            var pxlwidth = Math.round(col.orgpct * pct2px);
	            if (j < pctcols.length - 1)
	            {
	                col.style.width = Math.max(0, pxlwidth - tl.GetWidthSubtracts(col)) + 'px';
	                pxconverted += pxlwidth;
	            }
	            else
	            {
	                // last column takes up all available pixels
	                col.style.width = Math.max(0, (leftover - pxconverted) - tl.GetWidthSubtracts(col)) + 'px';
	            }
	        }

	        // recursive stuff
	        for (var j = 0; j < cols.length; j++)
	        {
	            tl.ConvertLiquidColumns(cols[j]);
	        }
	    }
	}

	this.Initialize();
}
