/* === znl.js === */

jQuery.noConflict();

(function($) {
	$.extend( {
		
		config: (function() {
			// Put config settings in configObj (private):
			var confObj = {
				quickSelect: {
					selected:					"geselecteerd",
					"Kies sector…":				"sectoren",
					"Kies beschikbaarheid…":	"dagen",
					"Kies regio…":				"regio's",
					"Kies opleiding…":			"opleidingen",
					"Kies variant…":			"varianten"
				},
				tabMapSearch: {
					label: "Zoek op kaart",
					id: "zoeken_kaart",
					qsParams: {page: "kaart"},
					afterId: "link_zoeken_naam"
				},
				mapSearch: {
					wrapperId: "mapSearch",
					hash: {
						map: "#map_search",
						searched: "#map_searched"
					},
					formId: "mapForm",
					zoom: 8,
					bounds: {
						north: 51.78069143675544,
						east: 6.237144695800794,
						south: 50.74324402539872,
						west: 5.566120373291028
					},
					infoWindow: {
						contentClassName: "infoContent",
						lists: [	// order + list headers
							{"vacatures": "Vacatures"},
							{"stages": "Stageplaatsen"},
							{"vrijwilligers": "Vrijwilligersvacatures"}
						]
					},
					dev: false // development
				},
				capEmailValidation: {
					formExpr: "#achter.cap #inhoud form",
					emailFieldExpr: "input[name='afzender_email'], input[name='cv[email]'], input[name='mail[to]']",
					mailPattern: /^[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i,
					trimPattern: /^\s*(\S*)\s*$/,
					errorMsg: "Vul een geldig e-mailadres in!"
				}
			};
			
			// Private methods:
			var extend = function(conf, callbacks) {
				if (!conf || typeof conf !== "object") { return; }
				var proceed;
				for (var key in conf) {
					proceed = true;
					if (callbacks) {
						// Call appropriate callback function, if specified:
						if (confObj[key] && callbacks.onAlter) { proceed = callbacks.onAlter(key, conf[key], confObj[key]); }
						else if (!confObj[key] && callbacks.onAdd) { proceed = callbacks.onAdd(key, conf[key]); }
					}
					// Set value, unless callback function returned false:
					if (proceed || proceed == null) { confObj[key] = conf[key]; }
				}
			};
			var get = function(key) {
				return key ? confObj[key] : confObj;
			};
			
			// Interface:
			return {extend: extend, get: get};
		})(),
		
		initDropDown: function() {
			var menu = $("#hoofdMenu");
			if (menu.length < 1) { return; }
			
			menu.find("ul.nav>li").hover(
				function(e) {
					$(this).addClass("jsHover");
				},
				function(e) {
					$(this).removeClass("jsHover");
				}
			);
		},
		
		initTabMenu: function() {
			function tabRef($tabLink) {
				var tabLinkId = $tabLink.attr("id"),
					$tab = null;
				if (tabLinkId) {
					var tabId = tabLinkId.replace(/^link_(.*)$/, "$1"),
						$tab = $("#" + tabId);
				}
				return $tab;
			}
			
			var $tabs = $("#tabMenu ul.tabSwitch"),
				mapSearchTab = $.config.get("tabMapSearch"),
				hashConf = $.config.get("mapSearch").hash,
				currentHash = window.location.hash;
				
			if ($tabs.hasClass("mapSearch")) {
				$.addMapSearchTab($tabs);
			}
			
			var $currentTabLink = $tabs.find("li.tabMenuAan");
			$currentTabLink = $currentTabLink.length ? $currentTabLink : $tabs.find("li:first-child");
			var $currentTab = tabRef($currentTabLink);
			
			$tabs.find("li").each(function() {
				var $tabLink = $(this),
					$tab = tabRef($tabLink),
					hash = "#",
					gm = window.google && window.google.maps,
					map;
				if ($tab) {
					$tabLink.click(function(e) {
						e.preventDefault();
						if (!$tabLink.hasClass("tabMenuAan")) {
							$currentTabLink.removeClass("tabMenuAan");
							$tabLink.addClass("tabMenuAan");
							$currentTab.hide();
							$tab.show();
							if (hashConf && $tabLink.attr("id") == "link_" + mapSearchTab.id) {
								hash = currentHash == hashConf.searched ? currentHash : hashConf.map;
							}
							window.location.hash = hash;
							$currentTab = $tab;
							$currentTabLink = $tabLink;
							
							// in case there's a Google Map:
							if (gm) {
								$.initSearchMap();
							}
						}
					});
				}
			});
			
			if (currentHash == hashConf.map || currentHash == hashConf.searched) {
				$("#link_" + mapSearchTab.id).click();
				$.initSearchMap();
			}
		},
		
		addMapSearchTab: function($tabs) {
			var mapSearchTab = $.config.get("tabMapSearch"),
				hashConf = $.config.get("mapSearch").hash,
				$prevTab,
				location = window.location,
				qs = "",
				page,
				pattern = /[\?&]+(p(?:age)?|alias)\=([^&]*)/g,
				params = mapSearchTab.qsParams || {},
				selected = "",
				href = "",
				tab;
				
			if (mapSearchTab && mapSearchTab.id /*&& $("#link_" + mapSearchTab.id).length > 0*/) {
				$prevTab = mapSearchTab.afterId ? $("#" + mapSearchTab.afterId) : $tabs.find("li:last-child");
				$prevTab = $prevTab.length ? $prevTab : $tabs.find("li:last-child");
				
				qs = location.search;
				while ((page = pattern.exec(qs)) != null) {
					if (page[1] == "p" || page[1] == "alias") {
						params[page[1]] = page[2];
					} else if (page[1] == "page" && page[2] == "kaart") {
						selected = ' class="tabMenuAan"';
					}
				}
				href = location.pathname + "?" + $.param(params) + hashConf.map;
				tab = document.createDocumentFragment().innerHTML = '<li id="link_' + mapSearchTab.id + '"' + selected + '><a href="' + href + '">' + mapSearchTab.label + '</a></li>';
				
				if ($prevTab.length) {
					$prevTab.after(tab);
				} else {
					$tabs.append(tab);
				}
			}
		},
		
		maps: {},
		infoWinOpen: {},
		
		initSearchMap: function() {
			var mapConf = $.config.get("mapSearch"),
				gm = window.google && window.google.maps,
				mapOptions = {},
				map,
				bounds,
				wrapper,
				devLog,
				$form;
			
			// is configuration available and is the map not yet initiated?
			if (gm && mapConf && mapConf.wrapperId && $.maps && !$.maps[mapConf.wrapperId]) {
				wrapper = document.getElementById(mapConf.wrapperId);
				if (!$(wrapper).is("div:hidden")) {
					bounds = mapConf.bounds;
					bounds.sw = new gm.LatLng(bounds.south, bounds.west);
					bounds.ne = new gm.LatLng(bounds.north, bounds.east);
					bounds.box = new gm.LatLngBounds(bounds.sw, bounds.ne);
					if (wrapper && bounds.box) {
						mapOptions.zoom = mapConf.zoom || 1;
						mapOptions.center = bounds.box.getCenter();
						mapOptions.mapTypeId = google.maps.MapTypeId.ROADMAP;
						
						map = new gm.Map(wrapper, mapOptions);
						$.maps[mapConf.wrapperId] = {map: map, center: mapOptions.center};
						
						/* --- for development only --- */
						if (mapConf.dev && (/\.sebastian\.nl/i).test(window.location.hostname)) {
							devLog = (function() {
								return (typeof console != "undefined" && console.log) ? console.log : alert;
							}());
							
							gm.event.addListener(map, "click", function(pos) {
								devLog("latLng: " + pos.latLng.toString());
							});
							
							gm.event.addListener(map, "zoom_changed", function() {
								devLog("zoom: " + map.getZoom());
							});
						}
					
						$form = $(wrapper).closest("form");
						$.initMarkerUpdate(map, $form);
						$.initMapFinalState(mapConf, $form);
					}
				}
			}
		},
		
		initMarkerUpdate: function(map, $form) {
			var mapConf = $.config.get("mapSearch"),
				hashConf = mapConf.hash,
				infoConf = mapConf.infoWindow,
				gm = google.maps,
				markers = [],
				//infoWinOpen = {},
				xhr,
				xhrOptions = {
					dataType: "json",
					type: $form.attr("method"),
					url: $form.attr("action"),
					success: function(data, status, xhr) {
						updateMarkers(data);
						window.location.hash = hashConf.searched;
					},
					beforeSend: function(ajaxObj) {
						if (xhr) {
							xhr.abort();
						}
						xhr = ajaxObj;
					}
				},
				hash = window.location.hash;
				
			function removeMarkers() {
				if ($.infoWinOpen.win) {
					$.infoWinOpen.win.close();
				}
				for (var i = 0, length = markers.length; i < length; i += 1) {
					markers[i].setMap(null);
				}
				markers = [];
			}
			
			function createMarker(loc) {
				var marker = new gm.Marker({
					position: new gm.LatLng(parseFloat(loc.lat), parseFloat(loc.lng)),
					map: map,
					title: loc.naam || loc.naam_fallback
				});
				markers.push(marker);
				return marker;
			}
			
			function createInfoWindow(loc, marker, locId) {
				var contentHTML = "",
					addressHTML = "",
					descrHTML = "",
					linkHTML = "",
					lists = infoConf.lists,
					infoWindow;
					
				function createLists() {
					var list,
						listName,
						listOrder = [],
						listHeaders = {},
						listsLength,
						showHeaders,
						itemsHTML = "",
						listItem,
						listsHTML = "";
						
					for (var i = 0, length = lists.length; i < length; i += 1) {
						//list = lists[i];
						for (listName in lists[i]) {
							if (loc[listName]) {
								listOrder.push(listName);
								listHeaders = $.extend(listHeaders, lists[i]);
							}
						}
					}
					
					listsLength = listOrder.length;
					showHeaders = listsLength > 1 ? true : false;
					for (var i = 0; i < listsLength; i += 1) {
						listName = listOrder[i],
						list = loc[listName];
						if (typeof list === "object") {
							for (var lnk in list) {
								listItem = list[lnk];
								itemsHTML += '<li><a href="' + listItem.url + '">' + listItem.titel + '</a></li>';
							}
							if (itemsHTML) {
								listsHTML += '<br />';
								if (showHeaders) {
									listsHTML += '<h4>' + listHeaders[listName] + '</h4>';
								}
								listsHTML += '<ul>' + itemsHTML + '</ul>';
								itemsHTML = "";
							}
						} else {
							itemsHTML += '<li>' + listHeaders[listName] + ': ' + list + '</li>';
						}
					}
					if (!listsHTML && itemsHTML) {
						listsHTML += '<br /><ul class="totals">' + itemsHTML + '</ul>';
					}
					
					return listsHTML;
				}
				
				if (loc.adres) {
					addressHTML = loc.adres;
					if (addressHTML && (loc.postcode || loc.plaats)) {
						addressHTML += '<br />' + loc.postcode;
						if (loc.postcode && loc.plaats) {
							addressHTML += '&nbsp; ';
						}
					}
				}
				addressHTML += loc.plaats;
				
				if (loc.omschrijving) {
					descrHTML = '<br /><p>' + loc.omschrijving + '</p>';
				}
				
				if (loc.url) {
					linkHTML = '<br /><p><a href="' + loc.url + '">Meer informatie</a></p>';
				}
				
				contentHTML += '<div class="' + infoConf.contentClassName + '">' +
						'<h3>' + marker.getTitle() + '</h3>' +
						'<p>' + addressHTML + '</p>' +
						descrHTML +
						createLists() +
						linkHTML +
					'</div>';
				
				// create infoWindow
				infoWindow = new gm.InfoWindow({
					content: contentHTML
				});
				
				function openInfoWindow() {
					if ($.infoWinOpen.win) {
						$.infoWinOpen.win.close();
					}
					infoWindow.open(map, marker);
					$.infoWinOpen = {
						win: infoWindow,
						loc: locId
					};
				}
				
				// connect infoWindow to marker
				gm.event.addListener(marker, "click", openInfoWindow);
				
				// reset $.infoWinOpen when infoWindow is closed
				gm.event.addListener(infoWindow, "closeclick", function() {
					$.infoWinOpen = {};
				});
				
				// open previously selected infoWindow
				if (loc.prevSelected && hash == hashConf.searched) {
					openInfoWindow();
				}
				
				// fix content height infoWindows
				gm.event.addListener(infoWindow, "domready", function() {
					setTimeout(function() {
						$("#" + mapConf.wrapperId + " div." + infoConf.contentClassName).parent().css("overflow", "").parent().css("overflow", "");
					}, 0);
				});
				
				return infoWindow;
			}
				
			function updateMarkers(data) {
				var marker,
					infoWindow;
				
				// remove previous markers
				removeMarkers();
				
				if (!(data instanceof Array)) {
					// add new markers
					for (var loc in data) {
						marker = createMarker(data[loc]);
						infoWindow = createInfoWindow(data[loc], marker, loc);
					}
				}
			}
			
			function getData(settings) {
				settings.data = $form.serialize();
				$.ajax(settings);
			}
			
			function getLastSearch(settings) {
				var url = settings.url,
					options = $.extend({}, settings, {
						url: url + (/\?/.test(url) ? "&" : "?") + "getPrevReq=1",
						success: function(data, status, xhr) {
							if (data && data.length) {
								var expr = "input:checkbox[name='" + data.join("'], input:checkbox[name='") + "']";
								$form
									.find("input:checkbox").removeAttr("checked")
									.filter(expr).attr("checked","checked");
							}
						},
						complete: function() {
							getData(xhrOptions);
						}
					});
				$.ajax(options);
			}
				
			$form.find("input:checkbox").click(function() {
				setTimeout(function() {
					getData(xhrOptions);
				}, 0);
			});
			
			if (hash == hashConf.searched) {
				getLastSearch(xhrOptions);
			} else {
				getData(xhrOptions);
			}
		},
		
		initMapFinalState: function(mapConf, $form) {
			var url = $form.attr("action"),
				xhrSettings = {
					dataType: "json",
					type: "get",
					asynch: false
				};
			
			// save location id server side + update hash
			$("div." + mapConf.infoWindow.contentClassName + " a").live("click", function() {
				if ($.infoWinOpen.loc) {
					xhrSettings.data = { loc: $.infoWinOpen.loc };
					xhrSettings.url = url;	// reset url
					$.ajax(xhrSettings);
				}
				window.location.hash = mapConf.hash.searched;
			});
		},
		
		initCheckAll: function() {
			var $filterChecks = $("#uitgebreidzoeken #mapForm input:checkbox.checkboxen"),
				$checkAlls = $filterChecks.filter("input[name^='optie_all[']");
			
			if ($checkAlls.length) {
				// setting default + resetting old skool event handlers"
				$filterChecks.attr("checked", "checked");
				window.checkall = window.allcheck = window.checkall2 = window.allcheck2 = window.checkallgen = window.allcheckgen = function() {};
				
				
				function check($elem, set) {
					set ? $elem.attr("checked", "checked") : $elem.removeAttr("checked");
				}
				
				$checkAlls.each(function() {
					var $this = $(this),
						$form = $this.closest("form"),
						groups,
						groupMatch = this.name.match(/^optie_all\[(\d*)\]$/),
						groupId;
	
					if (groupMatch) {
						groupId = groupMatch[1];
						groups = {
							$checkAll: $this,
							$checks: $form.find("input[name^='optie[" + groupId + "][']")
						}
						$form.data(groupId, groups);
					}
				});
				
				$filterChecks.live("click", function(e) {
					var $this = $(this),
						groupMatch = this.name.match(/^optie(?:_all)?\[(\d*)\]/),
						$form = $this.closest("form"),
						groupId,
						group,
						$checked;
						
					if (groupMatch) {
						groupId = groupMatch[1];
						group = $form.data(groupId);
						
						if (group) {
							if ($this.is("input[name^='optie_all[']")) {
								check(group.$checks, group.$checkAll.is("input:checked"));
							} else if ($this.is("input[name^='optie[']")) {
								$checked = group.$checks.filter("input:checked");
								check(group.$checkAll, ($checked.length == group.$checks.length));
							}
						}
					}
				});
			}
		},
		
		initQuickSelect: function() {
			var quickSelect = $(".quickSelect");
			if (quickSelect.length < 1) { return; }
			
			var itemContent = quickSelect.find("div.itemContent");
			var tabs = itemContent.find("ul.tabs li");
			var out;
			
			// switching tabs:
			tabs.click(function(e) {
				e.preventDefault();
				var tab = $(this).attr("id");
				var prevTab = itemContent.data("tab");
				if (prevTab) { itemContent.removeClass(prevTab); }
				itemContent
					.addClass(tab)
					.data("tab", tab);
			});
			
			// open first tab:
			itemContent
				.addClass("jsEnabled")
				.find("ul.tabs li:first")
				.click();
				
			var selects = itemContent.find("ul.select li");
			function looseFocus() {
				clearTimeout(out);
				out = null;
				selects.each(function(){
					$(this).removeClass("jsSelect");
					adjustFooter(parent, true);
				});
			};
			
			function adjustFooter(parent, resetHeight) {
				var container = $("#container");
				if (resetHeight) {
					container.height("auto");
				} else {
					var pageHeight = container.innerHeight();
					var flyout = parent.find("fieldset").eq(0);
					var flyoutTop = flyout.offset().top;
					var flyoutHeight = flyout.innerHeight();
					if (pageHeight < flyoutTop + flyoutHeight + 40) {
						container.height(flyoutTop + flyoutHeight + 40);
					}
				}
			};
			
			// pulldown:
			selects
				.hover(
					function() {
						if ($(this).hasClass("jsSelect")) {
							clearTimeout(out);
							out = null;
						}
					},
					function() {
						out = setTimeout(looseFocus, 250);
					}
				);
				
			var label = selects.find("h3 a");
			label
				.each(function() {
					var jThis = $(this);
					var labelText = jThis.text();
					jThis.closest("li").data("origLabel", labelText.replace("&hellip;", "…"));
				})
				.click(function(e) {
					e.preventDefault();
					var parent = $(this).closest("li");
					if (!parent.hasClass("jsSelect")) {
						looseFocus();
						parent.addClass("jsSelect");
						adjustFooter(parent);
					}
					else {
						looseFocus();
					}
				});
				
			// close pulldown:
			selects
				.find("p.close")
				.click(function(e){
					e.preventDefault();
					looseFocus();
				});
				
			$(document.body).click(function(e){
				if (!$(e.target).is(".quickSelect ul.select li *")) {
					looseFocus();
				}
			});
			
			// update label text:
			selects
				.find("input:checkbox")
				.click(function(){
					var jThis = $(this);
					var select = jThis.closest("li");
					var checkedSiblings = select.find("input:checked");
					var checks = checkedSiblings.length;
					var labelText;
					//alert(select.data("origLabel"));
					if (checks == 0) {
						labelText = select.data("origLabel");
					} else if (checks == 1) {
						labelText = checkedSiblings.eq(0).parent().text();
					} else {
						var quickSelectObj = $.config.get("quickSelect");
						var origLabel = select.data("origLabel");
						labelText = checks + " " + quickSelectObj[origLabel] + " " + quickSelectObj.selected;
					}
					if (labelText.length > 30) {
						labelText = labelText.slice(0,27) + "&hellip;";
					}
					select.find("h3 a").text(labelText);
				});
		},
		
		initOpleidingen: function() {
			var institutes = $("#instituteOverview");
			var oplLists = institutes.find("div.opleidingen_lijst");
			if (oplLists.length === 0) { return; }
			
			oplLists.prev().wrapInner('<a href="#" class="toggleOplList"></a>');
			
			institutes
				.addClass("jsExpandable")
				.click(function(e) {
					var jTarget = $(e.target);
					if (jTarget.is("a.toggleOplList")) {
						e.preventDefault();
						jTarget.closest("li").toggleClass("jsExpand");
					}
				});
			
		},
		
		zxpHovers: function() {
			$("#zxp #mainContent div.optie, #zxp #fontSize a").hover(function() {
				$(this).addClass("jsHover");
			}, function() {
				$(this).removeClass("jsHover");
			});
		},
		
		zxpSelectAll: function() {
			$("#zxp input:checkbox").click(function() {
				var $this = $(this);
				if ($this.hasClass("selectall")) {
					// Als de "select all" checkbox wordt gebruikt
					if (!$this.is(':checked')) {
						// Zet alle checkboxes uit
						$this.removeAttr('checked').siblings("input").removeAttr('checked');
					} else {
						// Zet alle checkboxes aan
						$this.attr('checked', 'checked').siblings("input").attr('checked', 'checked');
					}
				} else {
					// Alle overige checkboxes
					if (!$this.is(":checked")) {
						// Als er een normale checkbox wordt uigeschakeld
						$this.removeAttr('checked').siblings("input.selectall").removeAttr('checked');
					} else {
						// Als er een normale checkbox wordt ingeschakeld
						var turnon = true;
						
						$this.siblings("input:not(.selectall)").each(function () {
							var $target = $(this);
							
							if (!$target.is(":checked")) {
								// Als er een checkbox is gevonden die niet aan staat
								turnon = false;
								return false;
							}
						});

						if (turnon) {
							$this.siblings("input.selectall").attr('checked', 'checked');
						}
					}
				}
			});
		},
		
		zxpIE6Tabs: function (id) {
			$target = $("#" + id + " li");
			$target.hover(function () {
				if ($(this).hasClass('selected')) {
					return false;
				} else {
					$(this).addClass('ie6hover');
				}
			},
			function() {
				$(this).removeClass('ie6hover');
			});
		},
		
		initEmailValidatieCap: function() {
			var validConf = $.config.get("capEmailValidation"),
				$capForms = $(validConf.formExpr),
				$addresses,
				mailPattern = validConf.mailPattern,
				trimPattern = validConf.trimPattern;
				
			$capForms.submit(function(e) {
				$(this).find(validConf.emailFieldExpr)
					.each(function() {
						var $address = $(this),
							address = $address.val();
						address = address.replace(trimPattern, "$1");
						$address.val(address);
						if (!mailPattern.test(address)) {
							e.preventDefault();
							alert(validConf.errorMsg);
							$address.focus();
							return false;
						}
					});
			});
		},

		CAPinlogBoxSwap: function() {
			
		var $CAPinlogBox = $("#CAPinlogBox");
	
			if($CAPinlogBox.length){
	
				$CAPinlogBox.addClass('hidden');
				
				$('a#inlogLink').click(function(e){
					e.preventDefault();
					
					$(this).addClass('hidden');
					$(".inlogLinkTekst").addClass('hidden');
					$CAPinlogBox.removeClass('hidden');
					
				});
		
			}
		}
		
	} );
	
	
} )(jQuery);

jQuery( function( $ ) {
	
	// extend $.config with window.config (if any):
	$.config.extend(window.config);
	
	// dropdown menu:
	$.initDropDown();
	
	// tab menu:
	$.initTabMenu();
	
	// quick selects:
	$.initQuickSelect();
	
	// initCheckAll
	//$.initCheckAll();
	
	// expand/collapse opleidingen:
	$.initOpleidingen();
	
	// zorgXperience:
	$.zxpHovers();
	
	// zorgXperience select all checkboxes:
	$.zxpSelectAll();
	
	$.zxpIE6Tabs('zxpNav');
	// map search:
	//$.initSearchMap(); // ondergebracht bij $.initTabMenu();
	
	// initEmailValidatieCap
	$.initEmailValidatieCap();
	
	// Inlogboxen Aanmeldpunt
	$.CAPinlogBoxSwap();
	
} );
