/**
 * Custom and extended OBJECTS and jQUERY plugins
 */

/**
 * Easy namespacing setup
 */
String.prototype.namespace = function(separator) {
	var ns = this.split(separator || '.'), p = window, i;
	for (i = 0; i < ns.length; i++) {
		p = p[ns[i]] = p[ns[i]] || {};
	}
};

/**
 * Sets jQuery animation easing default to easInOutQuad
 */
jQuery.extend(jQuery.easing, {
	def : 'easeInOutQuad',
	easeInOutQuad : function(x, t, b, c, d) {
		if ((t /= d / 2) < 1)
			return c / 2 * t * t + b;
		return -c / 2 * ((--t) * (t - 2) - 1) + b;
	}
});

/**
 * Scrolls the page top to the top of an element, using an offset, speed and
 * easing function as options
 */
jQuery.fn.extend( {
	scrollTo : function(offset, speed, easing) {
		return this.each( function() {
			var targetOffset = $(this).offset().top + offset || 0;
			$('html,body').animate( {
				scrollTop : targetOffset
			}, speed, easing);
		});
	}
});

/**
 * Turns a combination of a 'view-switcher' element and a set of id'd elements
 * into a clickable item The 'view-switcher' div should be made up of <a>
 * elements with their 'rel' attribute pointing to the jQuery expression that
 * selects the elements that need to be shown onClick. Setting an <a> to
 * class="active" will make it the default view on page init. The container of
 * the trigger elements should have a unique id.
 * 
 * @Author: Edo Nijmeijer
 */
( function($) {
	//
	// plugin definition
	//
	$.fn.viewSwitcher = function(options) {

		// establish options, falling back to defaults
		currentOptions = $.extend( {}, $.fn.viewSwitcher.defaults, options);

		// iterate over all passed in objects
		return this.each( function() {
			$this = $(this);
			containingParentId = $this.attr("id");
			$viewTriggerSets[containingParentId] = $("a", $this);
			// remove outline
				$viewTriggerSets[containingParentId].css("outline", "none");
				syncViewStatusTriggerStatus($viewTriggerSets[containingParentId]);

				$viewTriggerSets[containingParentId].each( function() {
					$this = $(this);
					$this.click( function() {
						return handleTriggerClick($(this));
					});
				});
			});
	};

	//
	// private variables (but for the plugin as a whole)
	//
	var $viewTriggerSets = {};
	var currentOptions;

	//
	// private functions
	//
	function syncViewStatusTriggerStatus($viewTriggers) {
		$viewTriggers.each( function() {
			// hide views that are not marked as 'active'
				$this = $(this);
				if (!$this.hasClass(currentOptions.activeTriggerClass)) {
					$($this.attr(currentOptions.linkAttrib)).hide();
				} else {
					$($this.attr(currentOptions.linkAttrib)).show();
				}
			});
	}
	function getContainingParentId($trigger) {
		return $trigger.parent(currentOptions.triggerContainer).attr("id");
	}

	function handleTriggerClick($trigger) {
		var $allViewTriggers = $viewTriggerSets[getContainingParentId($trigger)];
		$allViewTriggers.removeClass(currentOptions.activeTriggerClass);
		$trigger.addClass(currentOptions.activeTriggerClass);
		syncViewStatusTriggerStatus($allViewTriggers);
		return false;
	}

	//
	// defaults, ready to be overridden by plugin-user
	//
	$.fn.viewSwitcher.defaults = {
		triggerContainer : "div",
		activeTriggerClass : "active",
		linkAttrib : "rel"
	};

	//
	// end of closure
	//
})(jQuery);

/**
 * Turns a <select> element into a custom-stylable version of a <div> with an
 * embedded set of
 * <li>s to replace the <select> and <option>s
 * 
 * @Author: Edo Nijmeijer
 */
( function($) {
	//
	// plugin definition
	//
	$.fn.customiseSelect = function(options) {

		// establish options, falling back to defaults
		currentOptions = $.extend( {}, $.fn.customiseSelect.defaults, options);

		// iterate over all passed in objects
		return this.each( function() {
			$this = $(this);
			var $opts = $("option", $this);
			var $hiddenReplacement = $(document.createElement("input")).attr("type", "hidden").attr("id", $this[0].id);
			var currentSelectionVal = $this.val();
			var currentSelectionText = $(":selected", $opts).text() || $opts.eq(0).text();
			if (!currentSelectionVal)
				currentSelectionVal = $opts.eq(0).val();
			$hiddenReplacement.val(currentSelectionVal);

			var $containerDiv = $(document.createElement("div")).addClass(currentOptions.anchorClass).html(
					"<span class=\"selectedText\">" + currentSelectionText + "</span>");
			var $dropDown = $(document.createElement("ul")).addClass(currentOptions.listClass);
			$opts.each( function() {
				var $this = $(this);
				var $item = $(document.createElement("li"));
				var $hiddenValue = $(document.createElement("input")).attr("type", "hidden").val($this.val());
				$item.html($this.text());
				$item.click(handleItemClick);
				$item.append($hiddenValue);
				$dropDown.append($item);
			});
			$containerDiv.append($hiddenReplacement);
			$containerDiv.append($dropDown);
			$containerDiv.mousedown(openMenu);

			$this.after($containerDiv);
			$this.hide();

		});
	};

	//
	// private variables (for all plugin instances!)
	//
	var currentOptions;

	//
	// private functions
	//
	function openMenu(event) {
		var $list = $("." + currentOptions.listClass, this);
		$list.slideDown(250, function() {
			addHoverClasses($list);
			// make sure dropdown closes when clicking outside it
				$("body").mousedown( function(event) {
					// don't do anything if part of the dropdown was clicked
						if ($("." + currentOptions.listClass + " li").index($(event.target)) < 0) {
							closeMenu($(this));
						}
					});
			});
	}
	function closeMenu($containerDiv) {
		$("body").unbind("mousedown");
		$("." + currentOptions.listClass + " li", $containerDiv).unbind("mouseover").unbind("mouseout");
		$("." + currentOptions.listClass, $containerDiv).slideUp(250);
	}
	function addHoverClasses($list) {
		var $listItems = $("li", $list);
		$listItems.removeClass("hover");
		$listItems.mouseover( function() {
			$(this).addClass("hover");
		}).mouseout( function() {
			$(this).removeClass("hover");
		});
		if ($(".hover", $listItems).length == 0)
			$listItems.eq(0).addClass("hover");
	}
	function handleItemClick(event) {
		event.stopPropagation();
		var $this = $(this);
		var $containerDiv = $(this.parentNode.parentNode);
		var clickedItemVal = $("input:hidden", $this).val();
		var clickedItemtext = $this.text();
		$("input:hidden", $containerDiv).eq(0).val(clickedItemVal);
		$(".selectedText", $containerDiv).text(clickedItemtext);
		closeMenu($containerDiv);
		if (currentOptions.functionOnChange) {
			currentOptions.functionOnChange(clickedItemVal, $this);
		}
	}

	//
	// defaults, ready to be overridden by plugin-user
	//
	$.fn.customiseSelect.defaults = {
		anchorClass : "cs-base",
		listClass : "cs-options-list",
		functionOnChange: undefined
	};

	//
	// end of closure
	//
})(jQuery);

/**
 * Adds 'borders' (corners and optional sidepanels) to an element. The actual
 * visual representation should be handled by css (which makes sure that sizes,
 * paths and positioning are kept there)
 * 
 * @Author: Edo Nijmeijer
 */
( function($) {
	//
	// plugin object definition
	//
	var AddBorders = function(element, options) {

		$element = $(element);
		// establish options, falling back to defaults
		var options = $.extend( {}, $.fn.addBorderElements.defaults, options);

		var obj = this;

		this.getOptions = function() {
			// public method. Call by getting the object off the elements 'data' and calling it
			return options;
		};

		if (!options.forInternetExplorerOnly || (options.forInternetExplorerOnly && $.browser.msie)) {
			// insert needed elements
			var $firstContainerChild = $element.children().eq(0);

			var cTL, cTR, cBL, cBR, sT, sR, sB, sL, elementArray = $("corners");

			cTL = $(document.createElement("div")).addClass(
					options.baseCornerClass + " " + options.baseCornerClass + options.topClass + options.leftClass);
			cTR = $(document.createElement("div")).addClass(
					options.baseCornerClass + " " + options.baseCornerClass + options.topClass + options.rightClass);
			cBL = $(document.createElement("div")).addClass(
					options.baseCornerClass + " " + options.baseCornerClass + options.bottomClass + options.leftClass);
			cBR = $(document.createElement("div")).addClass(
					options.baseCornerClass + " " + options.baseCornerClass + options.bottomClass + options.rightClass);

			elementArray = elementArray.add(cTL).add(cTR).add(cBL).add(cBR);

			if (options.type == $.fn.addBorderElements.CORNERS_AND_SIDES) {

				$element.css( {
					"overflow" : "visible"
				});

				sT = $(document.createElement("div")).addClass(
						options.baseSideClass + " " + options.baseSideClass + options.topClass);
				sR = $(document.createElement("div")).addClass(
						options.baseSideClass + " " + options.baseSideClass + options.rightClass);
				sB = $(document.createElement("div")).addClass(
						options.baseSideClass + " " + options.baseSideClass + options.bottomClass);
				sL = $(document.createElement("div")).addClass(
						options.baseSideClass + " " + options.baseSideClass + options.leftClass);
				elementArray = elementArray.add(sT).add(sR).add(sB).add(sL);

				if ($.browser.msie && $.browser.version < 7) {
					sT.add(sB).width($element.outerWidth());
					sL.add(sR).height($element.outerHeight());
					$element.resize( function() {
						$this = $(this);
						var $hors = $("." + options.baseSideClass + options.topClass + ", ." + options.baseSideClass
								+ options.bottomClass, $this);
						var $verts = $("." + options.baseSideClass + options.leftClass + ", ." + options.baseSideClass
								+ options.rightClass, $this);
						$hors.width($this.outerWidth());
						$verts.height($this.outerHeight());
					});

				}
				if ($.browser.msie && $.browser.version == 8) {
					//$element.height($element.innerHeight())
				}
			}

			elementArray.insertBefore($firstContainerChild);
		}

	};

	//
	// plugin definition
	//
	$.fn.extend( {
		addBorderElements : function(options) {
			// iterate over all passed in objects
			return this.each( function() {
				var element = $(this);

				// do not allow double instantiation
					if (element.data("addBorderElements"))
						return;

					// create instance
					var _addBorderElements = new AddBorders(this, options);
					// store object in element's data for later reference
					element.data("addBorderElements", _addBorderElements);
				});
		}
	});

	//
	// defaults, ready to be overridden by plugin-user
	//
	$.fn.addBorderElements.defaults = {
		baseCornerClass : "corner",
		baseSideClass : "side",
		topClass : "T",
		bottomClass : "B",
		leftClass : "L",
		rightClass : "R",
		forInternetExplorerOnly : true,
		type : $.fn.addBorderElements.CORNERS_ONLY
	};
	$.fn.addBorderElements.CORNERS_ONLY = 1;
	$.fn.addBorderElements.CORNERS_AND_SIDES = 2;
	//
	// end of closure
	//
})(jQuery);

/*
 * GLOBALS
 */

if (!window.console) {
	console = {};
	console.log = function(txt) {
		window.status = txt;
		return;
	};
	console.info = function(txt) {
		console.log(txt);
	};
	console.error = function(txt) {
		console.log(txt);
	};
	console.debug = function(txt) {
		console.log(txt);
	};
	console.warn = function(txt) {
		console.log(txt);
	};
}

//set up namespace for globals
("nza.globals").namespace();

/*
 * START global constants 
 */

nza.globals.equalHeightMonitorInterval = 250;
nza.globals.defaultSearchKeyword = "Hier uw zoekterm";
nza.globals.carouselSwitchInterval = 10000;

/* END global constants */

/* 
 * START dynamically (pre)initialized global variables 
 */
nza.globals.ieVersion;
nza.globals.isHandheld;
nza.globals.carouselTimer;

/* END dynamically (pre)initialized global variables */

/* 
 * START helper objects, caches 
 */

/* END helper objects, caches */
