/* === utrechtzorg.js === */


(function($) {
	$.extend( {
		
		config: (function() {
			// Put config settings in configObj (private):
			var confObj = {

				searchForm:			{
									checkAll:	true,
									label:		"Alles selecteren",
									infoIcon:	"images/ic_info_u.gif"
								},
				nlMonths:			[ "januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december" ],
				tabMapSearch: {
					label: "Zoek op kaart",
					id: "zoek_op_kaart",
					fUrl: "/vacatures/zoek_op_kaart",
					afterId: "link_zoeken_op_naam"
				},
				mapSearch: {
					wrapperId: "mapSearch",
					hash: {
						map: "#map_search",
						searched: "#map_searched"
					},
					zoom: 10,
					bounds: {
						north: 52.19363027685404,
						east: 4.641638027709973,
						south: 51.895473564101415,
						west: 4.098501431030286
					},
					infoWindow: {
						contentClassName: "infoContent",
						lists: [	// order + list headers
							{"vacatures": "Vacatures"},
							{"stages": "Stageplaatsen"},
							{"vrijwilligers": "Vrijwilligersvacatures"}
						]
					},
					dev: false // development
				},
				contentTabs: {
					jsTabsClass: 'jsTabs',
					selectedClass: 'jsSelected',
					menu: {
						//insertRelSelector: '.tabContent',						// optional, default: first tab content
						//insertType: 'before',									// before|after|prepend|append, optional, default: before
						wrapperHTML: '<div class="tabNav" />',					// optional
						headerHTML: '<h2 class="offScreen">Tabnavigatie</h2>',	// optional
						firstTabClass: 'firstTab',								// optional
						defaultLabelPrefix: 'Stap'								// optional
					},
					content: {
						selector: '.tabContent',
						headerSelector: '.tabName',
						defaultRefPrefix: 'tabRef'
					},
					buttons: {
						//insertRelSelector: '',														// optional, default: tab content
						//insertType: 'append',															// before|after|prepend|append, optional, default: append
						submitSelector: 'div.zoekButton',													// optional, if provided th ematched element will be appended to the button wrapper
						wrapperHTML: '<div class="buttons" />',											// optional
						prevButtonHTML: '<div class="prev"><button type="button">Terug</button></div>',
						nextButtonHTML: '<div class="next"><button type="button">Verder</button></div>',
						selector: '.buttons .prev button, .buttons .next button'
					}
					
				}
			};
			
			// 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};
		})(),
		
		addMapSearchTab: function($tabs) {
			var mapSearchTab = $.config.get("tabMapSearch"),
				$prevTab,
				location = window.location,
				fURLpattern,
				qsPattern = /[\?&]+page\=([^&]*)/,
				qsPage,
				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");
				
				href = mapSearchTab.fUrl.replace(/\//g,"\/");
				fURLpattern = new RegExp("^" + href + "\/?");
				qsPage = qsPattern.exec(location.search);
				if (fURLpattern.test(location.pathname) || (qsPage != null && qsPage[1] == "kaart")) {
					selected = ' class="subsubmenuaan"';
				}
				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);
				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 += '<p>&nbsp;</p>';
								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() {
						var $infoContent = $("#" + mapConf.wrapperId + " div." + infoConf.contentClassName);
						if ($infoContent.height() < 200) {
							$infoContent.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;
			});
		},
		
		searchForms: function(expr) {
			var sfConfig = $.config.get("searchForm");
			if (!sfConfig || sfConfig.checkAll === false) { return; }
			
			var formDiv = $(expr);
			
			function checkAll(collection, check) {
				var checkBoxes = collection.find("input:checkbox");
				check ? checkBoxes.attr("checked", "checked") : checkBoxes.removeAttr("checked");
			}
			
			formDiv
				.each(function() {
					var jThis = $(this);
					var total = jThis.find("input:checkbox");
					var checked = total.filter("input:checked");
					var id = jThis.attr("id").substring(3).toLowerCase();
					var allID = "option_all." + id;
					var allName = "option_all[" + id + "]";
					var checkAllBox = '<li><label for="' + allID + '"><input type="checkbox" id="' + allID + '" name="' + allName + '" />' + sfConfig.label + '</label></li>';
					jThis
						.data("total", total.length)
						.data("checked", checked.length)
						.prepend(checkAllBox);
				})
				.click(function(e) {
					var target = $(e.target);
					if (target.is("label")) { target = target.find("input:checkbox"); }
					var jThis = $(this);
					var checkAllID = "option_all." + jThis.attr("id").substring(3).toLowerCase();
					var checked = !!target.attr("checked");	// convert to boolean
					if (target.attr("id") == checkAllID) {
						checkAll(jThis, checked);
					} else {
						checkAllID = checkAllID.replace(/\./, "\\\.");
						var others = jThis.find("input:checkbox:not(#" + checkAllID + ")");
						others = checked ? others.not(":checked") : others.filter(":checked");
						if (others.length == 0) {
							checkAll(jThis, checked);
						} else {
							$("#" + checkAllID).removeAttr("checked");
						}
					}
				});
				
			var infoIcon = sfConfig.infoIcon;
			if (infoIcon) {
				formDiv
					.addClass("jsInfo")
					.find("div.infoLayer")
					.prepend('<a href="#"><img src="' + infoIcon + '" alt="info" /></a>')
					.hover(
						function(e) {
							var jThis = $(this);
							jThis.addClass("jsHover");
							jThis.closest("li").addClass("jsHover");
						},
						function(e) {
							var jThis = $(this);
							jThis.removeClass("jsHover");
							jThis.closest("li").removeClass("jsHover");
						});
			}
		},
		
		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 > 24) {
						labelText = labelText.slice(0,21) + "…";
					}
					select.find("h3 a").text(labelText);
				});
		},
		
		emailDays: function() {
			var days = $("#searchForm.emailServiceProfile #dagen, #searchForm.cvProfile #dagen");
			days
				.keyup(function() {
					// validate value:
					var jThis = $(this);
					var val = jThis.val();
					var absIntVal = Math.abs(parseInt(val), 10);
					if (val != absIntVal && val != "") {
						val = absIntVal;
					}
					if (isNaN(val)) {
						val = 0;
					}
					if (val > 99) {
						val = 99;
					}
					jThis.val(val);
					
					calcDate(val);
				})
				.blur(function() {
					// validate value:
					var jThis = $(this);
					var val = jThis.val();
					if (val == "") {
						jThis.val("0");
					}
					calcDate(jThis.val());
				});
				
			function calcDate(period) {
				if (period >= 0) {
					var today = new Date();
					var futureDate = new Date(today.getTime() + 86400000 * period);	// 24 * 60 *60 * 1000 = 86400000 milliseconds in a day
					var dateTxt = futureDate.getDate() + " " + $.config.get("nlMonths")[futureDate.getMonth()] + " " + futureDate.getFullYear();
					var endDate = $("#verloopdatum");
					var finalDate = $("#finalDate");
					if (finalDate.length == 0) {
						endDate.before(', tot <span id="finalDate">' + dateTxt + '</span>');
						finalDate = $("#finalDate");
					}
					finalDate.text(futureDate.toLocaleDateString());
					endDate.val(dateTxt);
				}
			}
			
			function leadingZero(num) {
				return num < 10 ? "0" + num : num;
			}
			
			calcDate(days.val());
		},
		
		initHome: function() {
			var $square = $("#pleinPlaceHolder"),
				$areas = $square.find("area"),
				animOrder = [	// ids of areas == classes of #plein (sprite positioning in homepage.css)
					"pleinZorg",
					"pleinBeroepen",
					"pleinJeugdzorg",
					"pleinVrijwilligers",
					"pleinKinderopvang",
					"pleinOrganisaties",
					"pleinOpleidingen",
					"pleinVacaturebank",
					"pleinWelzijn",
					"pleinStraatnaam"
				],
				currentClass = "",
				duration = 1000,	// duration of highlight in ms
				seqs = 3,	// number of sequences
				i = 0,
				isHovered = false,
				highlight = function(className) {
					$square
						.removeClass(currentClass)
						.addClass(className);
					currentClass = className;
				};
			
			// hovers:
			$areas
				.hover(function() {
					var newClass = this.id;
					highlight(newClass);
					isHovered = true;
				},
				function() {
					$square.removeClass(currentClass);
					isHovered = false;
				});
			
			// animation:
			do {
				$.each(animOrder, function(index, className) {
					window.setTimeout(function() {
						if (!isHovered) {
							highlight(className);
						}
					}, duration * i++);
				});
			} while (--seqs > 0);
			
			window.setTimeout(function() {
				if (!isHovered) {
					$square.removeClass(currentClass);
				}
			}, duration * i++);
		},
		
		closeStickyFooter: function() {
			
			 $(".closeStickyFooter").click(function(e){
				 e.preventDefault();
				 $("#stickyFooter").hide();
			 });
		},

		// Dropdowns voor landingspagina's
		vacatureLanding: function() {
			
			var $hasDropdown = $(".vacatureLanding");
			var $dropdownUL = $(".vacatureLanding ul")
			var $dropdownH3 = $(".vacatureLanding h3")
		
			if($hasDropdown.length){
				
				// Alle dropdowns (ofwel ul's inklappen
				$dropdownUL.addClass('hidden');

				$dropdownH3.hover(
					function () {
						$(this).addClass("hover");
					},
					function () {
						$(this).removeClass("hover");
					}
				);
				 
				$dropdownH3.click(function(e){

					e.preventDefault();
	
					var $this = $(this);

					// Is de dropdownal uitgeklapt?
					var alUitgeklapt = $this.next('ul').hasClass('show');

					if (alUitgeklapt){
						// dropdown is al uitgeklapt, inklappen maar
						$this.next('ul').removeClass('show').addClass('hidden');
						$this.removeClass('selected');
					}else{
						// eerst alle andere dropdowns inklappen en dan de betreffende dropdown uitklappen
						$dropdownUL.removeClass('show').addClass('hidden');
						$dropdownH3.removeClass('selected');
						$this.next('ul').removeClass('hidden').addClass('show');
						$this.addClass('selected');
					}
				});
				
			}
			 
		},
		
		initTabs: function() {
			var tabConf = $.config.get('contentTabs'),
				menuConf = tabConf.menu,
				contentConf = tabConf.content,
				buttonConf = tabConf.buttons,
				contentClass = contentConf.selector,
				$tabContents = $(contentClass),
				$contentContainer,
				$tabMenu,
				$tabs,
				$tabItems,
				tabs = [],
				hash = window.location.hash,
				selected = 0,
				selectedClass = tabConf.selectedClass;
				
			function indexTabs(i) {
				var $tabHeader = $(contentConf.headerSelector, this),
					tabLabel = $tabHeader.text() || menuConf.defaultLabelPrefix + ' ' + (i + 1),
					tabRef = this.id || contentConf.defaultRefPrefix + i;
					
				if (!this.id) {
					this.id = tabRef;
				}
				
				if ('#' + tabRef == hash) {
					selected = i;
				}
				
				tabs.push({
					label: tabLabel,
					ref: tabRef
				});
			}
			
			function addTabNav() {
				var $insertRel,
					tab,
					menuHTML = '',
					tabClasses,
					tabClassHTML;
				
				for (var i = 0, length = tabs.length; i < length; i++) {
					tab = tabs[i];
					tabClasses = [];
					if (i == 0 && menuConf.firstTabClass) {
						tabClasses.push(menuConf.firstTabClass);
					}
					if (i == selected) {
						tabClasses.push(selectedClass);
					}
					tabClassHTML = tabClasses.length ? ' class="' + tabClasses.join(' ') + '"' : '';
					menuHTML += '<li' + tabClassHTML + '><a href="#' + tab.ref + '">' + tab.label + '</a></li>';
				}
				
				if (menuHTML) {
					menuHTML = menuConf.headerHTML + '<ul>' + menuHTML + '</ul>';
					$tabMenu = menuConf.wrapperHTML ? $(menuConf.wrapperHTML).append(menuHTML) : $(menuHTML);
					$insertRel = menuConf.insertRelSelector ? $(menuConf.insertRelSelector) : $tabContents.eq(0);
					$insertRel[menuConf.insertType || 'before']($tabMenu);
				} else {
					$tabMenu = $(null);
				}
				$tabs = $('li a', $tabMenu);
				$tabItems = $tabs.parent();
				
				$tabMenu.on('click', 'a', function(e) {
					e.preventDefault();
					switchTabs(selected, $tabs.index(this));
				});
			}
			
			function addStepButtons() {
				$tabContents.each(function(i) {
					var $this = $(this),
						$buttonWrapper = $(buttonConf.wrapperHTML),
						$prevButton,
						$nextButton,
						$insertRel = buttonConf.insertRelSelector ? $(buttonConf.insertRelSelector, this) : $this;
					
					if (i != 0) {
						$prevButton = $(buttonConf.prevButtonHTML);
						$prevButton.data('tabRef', i - 1);
						$buttonWrapper.prepend($prevButton);
					}				
					if (i != tabs.length - 1) {
						$nextButton = $(buttonConf.nextButtonHTML);
						$nextButton.data('tabRef', i + 1);
						$buttonWrapper.append($nextButton);
					}
					if (buttonConf.submitSelector) {
						$(buttonConf.submitSelector, this).appendTo($buttonWrapper);
					}
					$insertRel[buttonConf.insertType || 'append']($buttonWrapper);
				});
			}
			
			function switchTabs(fromIndex, toIndex) {
				if (toIndex != fromIndex) {
					$tabContents.eq(fromIndex).removeClass(selectedClass);
					$tabContents.eq(toIndex).addClass(selectedClass);
						
					$tabItems.eq(fromIndex).removeClass(selectedClass);
					$tabItems.eq(toIndex).addClass(selectedClass);
					
					selected = toIndex;
				}
				$tabContents.eq(toIndex).focus();
			}
			
			if ($tabContents.length > 1) {
				$tabContents
					.each(indexTabs)
					.eq(selected).addClass(selectedClass);
				addTabNav();
				
				if ($tabMenu.length) {
					addStepButtons();
					
					$contentContainer = $tabContents.parent();
					$contentContainer
						.addClass(tabConf.jsTabsClass)
						.on('click', buttonConf.selector, function(e) {
							switchTabs(selected, $(e.target).parent().data('tabRef'));
						});
						
					$tabContents.attr('tabindex', -1);
				}
			}
		},
		
		validateCV: function() {
			var validate = $.config.get('cvValidation'),
				$form = $('form[name="frmNieuweCV"]');
				
			function errorMsg($invalidFields) {
				var contentClass = $.config.get('contentTabs').content.selector,
					$invalidTabs = $invalidFields.parentsUntil($form, contentClass),
					invalidTabs = $invalidTabs.map(function(i, elem) {
						var $tab = elem.id ? $('a[href="#' + elem.id + '"]') : $(null),
							tabLabel = $tab.text();
						return tabLabel ? "'" + tabLabel + "'" : null;
					}).get().reverse(),
					lastInvalidTab = invalidTabs.pop();
					msg = [invalidTabs.join(', '), lastInvalidTab].join(' en ');
					
				msg = msg ? ' bij de onderdelen ' + msg : '';
				alert ('Niet alle verplichte velden zijn ingevuld' + msg + '.\nDe velden aangegeven met een * zijn verplicht.');
			}
				
			if (validate && $form.length) {
				$form.on('submit', function(e) {
					var form = this,
						$invalidFields = $(null);
					
					for (var field in validate) {
						if (validate.hasOwnProperty(field)) {
							if (!validate[field](form[field])) {
								$invalidFields = $invalidFields.add(form[field]);
							}
						}
					}
					
					if ($invalidFields.length) {
						e.preventDefault();
						errorMsg($invalidFields);
					} else if (!confirm ('Klik op OK om je CV aan te melden.\nJe krijgt een persoonlijke toegangscode\nper e-mail waarmee je wijzigingen\nkunt aanbrengen aan je CV.')) {
						e.preventDefault();
					}
				});
				
			}
		}
		
	} );
} )(jQuery);

jQuery( function( $ ) {
	// extend $.config with window.config (if any):
	$.config.extend(window.config);
	
	// init searchForms:
	$.searchForms("#searchForm fieldset.checkboxField ul.overview");
	
	// init content tabs
	$.initTabs();
	
	// home amination & hovers:
	$(window).load($.initHome);
	
	// map search:
	var $tabs = $("body.vacatures #submenu ul ul");
	if ($tabs.hasClass("mapSearch")) {
		$.addMapSearchTab($tabs);
		$.initSearchMap();
	}

	// set final date email service/CV bank:
	$.emailDays();

	// Klik de pagina-brede banner onderaan weg:
	$.closeStickyFooter();

	// dropdown voor landingspagina's:
	$.vacatureLanding();
	
	// validate CV:
	$.validateCV();
	
} );
