/*! $Id: global.js 6055 2009-09-11 11:05:54Z bhillebrand $ */
/*global $: false, window: false, modelName: false, modelYear: false, doPassVar: false, write: false */

/*
 * mdsRegistry object (js data storage)
 * The mdsRegistry object provides an easy to use interface
 * to make arbitrary data globally available in a per-module
 * (js script or plugin) context.
 *
 * The mdsRegistry object's only method is
 *    mdsRegistry.getInstance(sModuleId)
 * which will return a singleton registry instance for the module
 * specified by sModuleId. 
 * Each registry object then knows the methods:
 *
 * add(data) [or add(key, value))
 *    register data by passing either a key/value object
 *    or seperate parameters for key and value
 * get(key)
 *    return the registered data for property 'key'
 *
 * NOTE: The key/sModuleId parameters have to meet the requirements
 * 		 for valid property identifiers
 */
window.mdsRegistry = (function () {
	return {
		getInstance: function (sModuleId) {
			var data = {};

			this[sModuleId] = this[sModuleId] || {
				/* registry instance prototype */
				module: sModuleId,
				add: function (key, value) {
					if (typeof key === 'object') {
						$.extend(data, key);
					} else if (typeof key === 'string') {
						data[key] = value;
					}
					/* allow add() chains (jquery style) */
					return this;
				},
				get: function (key) {
					return key ? 
							data[key] || null :
							data;
				}
			}
			return this[sModuleId];
		}
	};
})();
/*
 * Global ieLte6 Helper:
 * Used to determine whether or not the userAgent is IE less than or equal 6
 * by checking the boolean flag window.ieLte6Helper.isLte6
 * Also provides the method for setting the fix classes for buggy positioning
 * of position: absolute elements inside offsetParents with odd innerWidth/Height
 * The helper is used by the oCtaHelper object
 */
window.ieLte6Helper = (function () {
	return {
		isLte6: ((/MSIE (\d+\.\d+);/).test(navigator.userAgent) && (RegExp.$1) * 1.0 <= 6),
		cornerPositionFix: function (obj) {
			if (!this.isLte6) {
				return;
			}
			obj = obj || $(".rCorners");
			obj.each(function () {
				$(this).children(".corner")
				.toggleClass("oddHeightFix", $(this).innerHeight() % 2 !== 0)
				.toggleClass("oddWidthFix",  $(this).innerWidth() % 2 !== 0);
			})
		}
	};
})();

$(document).ready(function () {
	/***
	 * Global Search Field
	 */
	(function () {
		var defaultValue = $("#searchInput").addClass("default").val();
		$("#globalSearch").hover(
			function () {
				$(this).parent().addClass("searchHover");
			}, function () {
				$(this).parent().removeClass("searchHover");
			}
		);
		$("#searchInput").focus(function () {
			if ($(this).val() === defaultValue) {
				$(this).val("").removeClass("default");
			}
		}).blur(function () {
			if (!$(this).val()) {
				$(this).val(defaultValue);
			}
			if ($(this).val() === defaultValue) {
				$(this).addClass("default");
			}
		});
	})();

	/* NOTE:
	 * if it is page and/or country specific, it should NOT
	 * be in global.js ! -> removed
	 * (a selector like .tabIndex forces JS to test
	 * EVERY ELEMENT ON ANY PAGE for the className, which is
	 * a huge overhead in this case! try #wrpID .class and set the ID
	 * only on pages that need it)
	 
	// UK Fleet page specific - tabbing
	$(".tabItem").click(function () {
		var idx = $(".tabItem").index(this),
			ct = $(".tabMainContent:eq(" + idx + ")");

		$(ct).siblings().hide();
		$(ct).show();
		$(this).siblings().removeClass("tabbed");
		$(this).addClass("tabbed");
	});
	*/

	/**
	 * CTA buttons object create:
	* Initializes all buttons that are already in the DOM
	* if display != none, all others have to use the refresh methods described below.
	* (Init/refresh appends corners where needed, applies the size className
	* and makes all grouped buttons equal in height and/or width, depending on their classNames
	* (see below) for each group.
	* Grouped buttons that are to be initialized on DOM ready need to have classNames indicating
	* they are grouped, and their group number: "grouped groupN" where N is the group number, starting
	* at 1. There may be no missing group numbers, for the init process will stop if groupN+1 is not found.
	*
	* Button groups that are refreshed manually with refreshGroup() may lack those classNames - the method will
	* treat all buttons passed to it as a single group.
	*
	* Default behaviour is to make all buttons of a group equal in height. Width adjustment is triggered
	* by giving the buttons in a group either one of the two optional classes "groupWidth" (additional width adjustment)
	* or "groupWidthOnly" (width adjustment only). It is possible to mix those two classNames inside a group.
	*
	* Provides a global object: 'oCtaHelper', supporting the methods:
	*
	 * oCtaHelper.refreshGroup(buttons)
	 *     Update all buttons passed by the buttons parameter
	 *     buttons may be a DOM node (or an array of nodes),
	 *     a css selector or a jQuery selection of buttons
	 *     Passed buttons will be treated as a single group.
	 *
	 * oCtaHelper.refresh(buttons)
	 *     Update all buttons passed by the buttons param
	 *     buttons may be a button DOM-node (or an array of them),
	 *     or the jquery selection of one or more buttons
	 *
	 * oCtaHelper.setType(oButton, sTypeClass)
	 *     changes the button type from ctaX to ctaY for all button classnames there may be. 
	 *     Always use this method - DO NOT REPLACE THE CLASSNAMES MANUALLY - since some
	 *     classNames you may not be aware of are set under certain conditions (e.g. ieLte6 fix classes
	 *     such as .ctaXsizeN).
	 *     buttons may be a button DOM-node (or an array of them),
	 *     or the jquery selection of one or more buttons
	 *     sTypeClass is the className of the new buttonType (e.g. cta3)
	 *
	 */

	/*
	 * IE6 SUPPORT INFO:
	 * All items in between the "IE6 SUPPORT" / "END IE6 SUPPORT" comments
	 * may simply be removed if support for IE6 (and lower) is no longer desired
	 */
	$(window).load(function () {
		window.ieLte6Helper.cornerPositionFix();
	});
	window.oCtaHelper = (function () {
		/* Initialize some variables */
		var sGroupName,
			isLte6,
			$allButtons     = $("a.button"), /* extending the selector may have serious impact on the performance */
			$groupedBtns    = $allButtons.filter(".grouped"),
			$singleButtons  = $allButtons.not(".grouped"),
			sCornerWrappers = '' +
				'<span class="corner topLeft"></span>\n' +
				'<span class="corner bottomLeft"></span>\n' +
				'<span class="corner topRight"></span>\n' +
				'<span class="corner bottomRight"></span>\n';

		function setSizeClass($buttons) {
			var aSizeSteps = [25, 40, 60, 90, 130, 200];
			$buttons.each(function () {
				var $currentButton = $(this),
				sSizeClassName = '',
				iSizeIndex = 1;

				while (iSizeIndex <= aSizeSteps.length && $currentButton.innerHeight() > aSizeSteps[iSizeIndex - 1]) {
					iSizeIndex += 1;
				}
				sSizeClassName = 'size' + iSizeIndex;
				$currentButton.get(0).className = $currentButton.get(0).className.replace(/ +size\d+/g, ''); /* only works if sizeX is NOT the first className */
				$currentButton.addClass(sSizeClassName);

				/* IE6 SUPPORT */
				if (window.ieLte6Helper.isLte6) {
					window.ieLte6Helper.cornerPositionFix($currentButton);
					/** set ieLte6 sizeclasses **/
					$currentButton.get(0).className = $currentButton.get(0).className.replace(/ +cta\d+size\d+/g, '');
					/* and set the new one */
					if (/ *(cta\d+) */.test($currentButton.get(0).className)) {
						$currentButton.addClass(RegExp.$1 + sSizeClassName);
					}
				}
				/* END IE6 SUPPORT */
			});
		}

		function applyCorners($button) {
			/* append corners to a single button (if button is not static) */
			if (!$button.hasClass(".static") && !$button.children(".topLeft, .topRight, bottomLeft, .bottomRight").addClass("corner").length) {
				$button.append(sCornerWrappers);
			}
		}
		function setPaddings($button, iSizeDifference, sPaddingType) {
			var sPaddingName, iAddPadding1 = 0, iAddPadding2 = 0;

			if (iSizeDifference % 2) {
				iAddPadding1 = (iSizeDifference - 1) / 2;
				iAddPadding2 = iAddPadding1 + 1;
			} else {
				iAddPadding1 = iAddPadding2 = iSizeDifference / 2;
			}
			sPaddingName = sPaddingType === 'height' ? "paddingTop" : "paddingLeft";
			$button.css(sPaddingName, parseInt($button.css(sPaddingName), 10) + iAddPadding1 + "px");

			sPaddingName = sPaddingType === 'height' ? "paddingBottom" : "paddingRight";
			$button.css(sPaddingName, parseInt($button.css(sPaddingName), 10) + iAddPadding2 + "px");
		}
		function updateButtonGroup($buttons) {
			var iGroupHeight = 0,
				iGroupWidth  = 0;

			$buttons.each(function () {
				var $currentButton = $(this);
				if (!$currentButton.hasClass('groupWidthOnly')) {
					iGroupHeight = Math.max(iGroupHeight, $currentButton.height());
				}
				if ($currentButton.is('.groupWidth, .groupWidthOnly')) {
					iGroupWidth  = Math.max(iGroupWidth,  $currentButton.width());
				}
			}).each(function () {
				var $currentButton = $(this);
				/* resize paddings to make height = groupHeight */
				if (!$currentButton.hasClass('groupWidthOnly')) {
					setPaddings($currentButton, iGroupHeight - $currentButton.height(), 'height');

				}
				/* resize paddings to make width = groupWidth */
				if ($currentButton.is('.groupWidth, .groupWidthOnly')) {
					setPaddings($currentButton, iGroupWidth - $currentButton.width(), 'width');
				}
				/* set all size related classNames */
				applyCorners($currentButton);
				setSizeClass($currentButton);
			});
		}

		/* resize all button groups (starting at group1, incrementing the group number until groupN can not be found) */
		sGroupName = "group1";

		/* If the current group classname exists */
		while ($groupedBtns.hasClass(sGroupName)) {
			updateButtonGroup($groupedBtns.filter("." + sGroupName));
			sGroupName = "group".concat(sGroupName.match(/group(\d+)/)[1] * 1 + 1);
		}
		applyCorners($singleButtons);
		setSizeClass($singleButtons);

		return {
			refreshGroup: function ($buttonGroup) {
				var $standardButton = $('<a class="button jsStandardButton"></a>').appendTo('body').hide();
				if (!$buttonGroup || !$buttonGroup.jquery) {
					$buttonGroup = $($buttonGroup);
				}

				/* Reset the paddings top/bottom. creates a testbutton, gets its paddings
				and removes it. Resets the group's padding to those values */
				$buttonGroup.css({
					paddingLeft:   $standardButton.css("paddingLeft"),
					paddingRight:  $standardButton.css("paddingRight"),
					paddingTop:    $standardButton.css("paddingTop"),
					paddingBottom: $standardButton.css("paddingBottom")
				});
				$standardButton.remove();
				updateButtonGroup($buttonGroup);
			},
			setType: function (oButtons, sTypeClass) {
				return $(oButtons).each(function () {
					this.className = this.className.replace(/cta\d+/g, sTypeClass);
				});
			},
			refresh: function (oButtons) {
				$(oButtons).each(function () {
					var $currentButton = $(this);
					applyCorners($currentButton);
					setSizeClass($currentButton);
				});
			}
		};
	})();
	
	/***
 	 * Section Slider
	 */
	(function () {
		$('ul.jsSectionSlider').each(function () {
			var $allSections = $("li.section", this),
				bIsAccordion = $(this).hasClass("jsAccordion");

			/* init slider: slide collapse all sectionContents... */
			$allSections.addClass('closed').children(".sectionContent").hide()
			.slice(0, 1).slideDown("slow", function () {
				/* ... and expand the first one when done*/
				$(this).closest("li").removeClass("closed");
			});

			/* Bind expand/collapse single sections events */
			$allSections.find(".sectionHead").css({cursor: 'pointer'}).click(function (event) {
				var $currentSection = $(this).closest("li");
				if (bIsAccordion) {
					/* add accordion behaviour (close all other sections) */
					$currentSection.siblings(":not(.closed)").addClass("closed").children(".sectionContent").slideUp("slow");
				}
				$currentSection.toggleClass("closed").children(".sectionContent").slideToggle("slow");
			});
		});
	})();
});

/* Query Functions */
/* Splitting a query string into its values.
 * Returns object (default) or array (values only) if second parameter is set to true
 */
function splitQueryString(url, arr) {
	var s, f, o, i, e;

	if (url) {
		s = url.substring(url.indexOf("?") + 1, url.length);
		f = s.split("&");
		o = arr ? [] : {};

		for (i = 0; i < f.length; i += 1) {
			e = f[i].split("=");
			if (arr) {
				o.push(e[1]);
			} else {
				o[e[0]] = e[1];
			}
		}
		return o;
	}
}


// Write prices in soccercards from JSON:
// First deactivate all teasers "Already from" in case file couldn't be loaded or the file has an error:
function writeModelPricesInSoccercards(filename)
{
	var file = "/" + filename + ".json",
		alreadyFromTranslation = $(".soccercard > li > .boxTop > .wrapper > .teaser").html();
	$(".soccercard > li > .boxTop > .wrapper > .teaser").empty();
	$.getJSON(file,
		function (data) {
			$.each(data.models, function (i, item) {
				if (item && item.model) { //IE Bugfix: "'model' is null or not an object"
					$("#sc_minprice_" + item.model).append(alreadyFromTranslation + "<span class='price nobr'>" + item.minprice + "</span>");
				}
			});
		}
	);
}



/*
 * Set a cookie
 */
function setCookie(sParamName, sParamValue, iDaysToExpire, sPath) {
	var date = new Date();
	if (!sParamName) {
		return;
	}
	sParamValue   = sParamValue || null;
	sPath         = sPath || '/';
	iDaysToExpire = parseInt(iDaysToExpire, 10) || 365;

	//date.setTime(date.getTime() + (iDaysToExpire * 24 * 60 * 60000));
	date.setTime(date.getTime() + (iDaysToExpire * 86400000));
	document.cookie = sParamName + "=" + sParamValue + "; expires=" + date.toGMTString() + "; path=" + sPath;
}

/*
 * Find the value of sParamName in a cookie and return it.
 */
function getCookieParam(sParamName) {
	if (document.cookie) {
		var re = new RegExp(sParamName + '=([^;$]*)');
		return re.test(document.cookie) ? re.exec(document.cookie)[1] : false;
	}
	return false;
}

/**
 * dealer search box START
 */
$(document).ready(function () {
	var sDealerSearchDefaultVal = $("#searchItem").val();

	$("#searchItem").val(getCookieParam("searchItem") || sDealerSearchDefaultVal);
	/**
	 * if the dealer search box is not yet inside the metaNAvi li
	 * that triggers the search box, go ahead and put it there.
	 * Also make shure that the list item in question is positioned relative (acting as offsetParent)
	 */
	if (!$("#dealerSearchWrp").is("#metaNavi > li.dealerSearch #dealerSearchWrp")) {
		$("#metaNavi > li.dealerSearch").css({position: 'relative'}).append($("#dealerSearchWrp"));
	}

	$("#metaNavi .dealerSearch > a").click(function (event) {
		var	$dSearch = $("#dealerSearchWrp"),
			offsetX;

		$("#searchItem").removeClass("warning");
		$dSearch.show();

		/* if the dealer search box would get cut off on the right
		   (viewport too small) -> reposition it to the left */
		offsetX  = $dSearch.offset().left;

		if (offsetX + $dSearch.outerWidth() > $(window).width()) {
			$("#dealerSearchWrp").css({left: parseInt($dSearch.css("left"), 10) - offsetX - $dSearch.outerWidth() + $(window).width() + 'px'});
		}
		return false;
	});

	$("#searchItem").closest("form").submit(function (event) {
		var $searchItem = $("#searchItem");

		if ($searchItem.val() &&  $searchItem.val() !== sDealerSearchDefaultVal) {
			/* if input is not empty set the cookie and submit the form */
			setCookie("searchItem", $searchItem.val());
		} else {
			/* show the error and do not submit otherwise */
			$searchItem.addClass("warning");
			event.preventDefault();
		}
	});

	$("#dealerSearchWrp .closeAction").click(function () {
		$("#dealerSearchWrp").hide();
	});

	/* disable the link and submit the form instead */
	$("#dealerSearchWrp a.button").click(function (event) {
		event.preventDefault();
		$("#dealerSearchForm").submit();
	});

	$("#searchItem").focus(function () {
		if ($(this).val() === sDealerSearchDefaultVal) {
			$(this).val("");
		}
	});

	$("#searchItem").blur(function () {
		if ("" === $(this).val()) {
			$(this).val(sDealerSearchDefaultVal);
		}
	});

});
/* END dealer search box END */
