/* === utrechtzorg.js === */


(function($) {
	$.extend( {
		
		config: (function() {
			// Put config settings in configObj (private):
			var confObj = {
				quickSelect:	{
									selected:					"geselecteerd",
									"Kies sector…":				"sectoren",
									"Kies functie…":			"functies",
									"Kies regio…":				"regio's"
									
								},
				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: "Zoeken op kaart",
					id: "kaart",
					fUrl: "/vacatures/zoek_op_kaart",
					afterId: "link_naam"
				},
				mapSearch: {
					wrapperId: "mapSearch",
					hash: {
						map: "#map_search",
						searched: "#map_searched"
					},
					zoom: 9,
					bounds: {
						north: 52.2936627830471,
						east: 5.626974331420911,
						south: 51.93779482515482,
						west: 4.792013393920911
					},
					infoWindow: {
						contentClassName: "infoContent",
						lists: [	// order + list headers
							{"vacatures": "Vacatures"},
							{"stages": "Stageplaatsen"},
							{"vrijwilligers": "Vrijwilligersvacatures"}
						]
					},
					dev: false // development
				}
			};
			
			// 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="aan"';
				}
				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() {
						$("#" + mapConf.wrapperId + " div." + infoConf.contentClassName).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());
		},
		
		homepageTabs: function () {
			$tabs = $(".tabbladen .tab");
			$tabTitles = $(".tabbladen .tabtitle");
			$(".tabbladen .tabtitle").removeClass("jsHide");
			$(".tabbladen .tab:not(:first)").addClass("jsHide");
			
			$(".tabbladen .tabtitle").click(function () {
				$this = $(this);
				$tabTitles.removeClass("tabaan");
				$this.addClass("tabaan");
				$tabs.addClass("jsHide");
				$("#" + $this.attr("rel")).removeClass("jsHide");
			});
		}
		
	} );
} )(jQuery);

jQuery( function( $ ) {
	// extend $.config with window.config (if any):
	$.config.extend(window.config);
	
	// init searchForms:
	$.searchForms("#searchForm fieldset.checkboxField ul.overview");
	
	// map search:
	var $tabs = $("#sectionNav ul.subMenu");
	if ($tabs.hasClass("mapSearch")) {
		$.addMapSearchTab($tabs);
		$.initSearchMap();
	}

	// quick selects:
	$.initQuickSelect();
	
	// make entire block elements clickable:
	$("#resultList li").clickable();
	
	// set final date email service/CV bank:
	$.emailDays();
	
	// tabjes in "leren" blokje op homepage
	$.homepageTabs();
} );