var rwTypes = [	
		['1', 'Asfaltering / wegverharding'],
		['6', 'Klein onderhoud wegen'],
		['5', 'Onderhoud fietspaden'],
		['10', 'Verkeersregelinstallaties, onderhoud/aanleg'],
		['11', 'Kleine opbrekingen'],
		['12', 'Kleine opbrekingen,herstel na werkzaamheden'],
		['2', 'Leggen van kabels en leidingen'],
		['13', 'Kabels en leidingen, herstel na werkzaamheden'],
		['7', 'Vervanging riool'],
		['14', 'Riolering, reiniging/inspectie'],
		['15', 'Openbare verlichting'],
		['16', 'Bruggen en Tunnels (kunstwerken)'],
		['9', 'Overige'],
		['17', 'Bodemsanering'],
		['18', 'Parkeren'],
		['19', 'Bouwactiviteiten'],
		['20', 'Herinrichting'],
		['21', 'Kortdurende stremmingen'],
		['40', 'Boringen'],
		['47', 'Calamiteit'],
		['3', 'Kappen van bomen'],
		['4', 'Onderhoud bermen'],
		['22', 'Werkzaamheden tram/busbaan'],
		['23', 'Werkzaamheden overweg'],
		['24', 'Werkzaamheden Prorail'],
		['25', 'Openbaar vervoerproject'],
		['8', 'Evenement'],
		['26', 'Markt'],
		['27', 'Voetbalwedstrijd'],
		['28', 'Marathon'],
		['29', 'Sinterklaasoptocht'],
		['30', 'Carnavalsoptocht'],
		['31', 'Braderie'],
		['32', 'Kermis'],
		['41', 'Festival'],
		['42', 'Concert'],
		['43', 'Straatfeest'],
		['44', 'Wielerwedstrijd'],
		['45', 'Sportevenement'],
		['33', 'Werkzaamheden vaarweg'],
		['34', 'Baggerwerkzaamheden'],
		['35', 'Werkzaamheden sluis'],
		['36', 'Evenement op het water'],
		['37', 'Werkzaamheden brug'],
		['46', 'Evenement bij het water'],
		['38', 'Traffic Management Path'],
		['39', 'Annotatie']
];
var obstructTypes = [ 	['10', 'Algemeen'],
			['20', 'Gemotoriseerd verkeer'],
			['25', 'Vrachtverkeer'],
			['30', 'Fietsers'],
			['40', 'Voetgangers'],
			['50', 'Openbaar vervoer'],
			['55', 'Taxi'],
			['60', 'Overig']];
var severityTypes = [ 	['-1', 'Onbekend'],
			['0', 'Geen hinder'],
			['1', 'Kleine hinder'],
			['2', 'Matige hinder'],
			['3', 'Grote hinder'],
			['4', 'Zeer grote hinder']];
var periodFilter = [	[0, 'Altijd'],
			[1, 'Vandaag'],
			[2, 'Komende week'],
			[3, 'Komende maand'],
			[4, 'Komende 12 maanden']];
var parkingBlockType = [
			[0, 'Geopend'],
			[1, 'Beperkt geopend'],
			[2, 'Gesloten']];
var parkingType = [
			[0, 'Open', 'Parkeerplaats'],
			[1, 'Overdekt', 'Overdekte parkeerplaats'],
			[2, 'Tijdelijk', 'Tijdelijke parkeerplaats'],
			[3, 'Straat', 'Parkeren aan de straat'],
			[4, 'Carpool', 'Carpoolplaats'],
			[5, 'P&R', 'Park & Ride']];

// icons
// id | type | severity 
// 0 | 1,2,3,4,5,6,7 | -1 
// 1 | 1,2,3,4,5,6,7 | 0
// 2 | 1,2,3,4,5,6,7 | 1
// 3 | 1,2,3,4,5,6,7 | 2
// 4 | 1,2,3,4,5,6,7 | 3
// 5 | 1,2,3,4,5,6,7 | 4
// 6 | 8, 26, 27, 28, 29, 30, 31, 32, 41, 42, 43, 44, 45 | -1 
// 7 | 8, 26, 27, 28, 29, 30, 31, 32, 41, 42, 43, 44, 45 | 0
// 8 | 8, 26, 27, 28, 29, 30, 31, 32, 41, 42, 43, 44, 45 | 1
// 9 | 8, 26, 27, 28, 29, 30, 31, 32, 41, 42, 43, 44, 45 | 2
// 10 | 8, 26, 27, 28, 29, 30, 31, 32, 41, 42, 43, 44, 45 | 3
// 11 | 8, 26, 27, 28, 29, 30, 31, 32, 41, 42, 43, 44, 45 | 4
// 12 | 9, 17, 18, 19, 20, 21, 40, 47 | -1
// 13 | 9, 17, 18, 19, 20, 21, 40, 47 | 0
// 14 | 9, 17, 18, 19, 20, 21, 40, 47 | 1
// 15 | 9, 17, 18, 19, 20, 21, 40, 47 | 2
// 16 | 9, 17, 18, 19, 20, 21, 40, 47 | 3
// 17 | 9, 17, 18, 19, 20, 21, 40, 47 | 4
// 18 | 22, 23, 24, 25 | -1
// 19 | 22, 23, 24, 25 | 0
// 20 | 22, 23, 24, 25 | 1
// 21 | 22, 23, 24, 25 | 2
// 22 | 22, 23, 24, 25 | 3
// 23 | 22, 23, 24, 25 | 4
// 24 | 33, 34, 35, 36, 37, 46 | -1
// 25 | 33, 34, 35, 36, 37, 46 | 0
// 26 | 33, 34, 35, 36, 37, 46 | 1
// 27 | 33, 34, 35, 36, 37, 46 | 2
// 28 | 33, 34, 35, 36, 37, 46 | 3
// 29 | 33, 34, 35, 36, 37, 46 | 4
var icons = [
		['Wegwerk - Onbekende hinder', null],
		['Wegwerk - Geen hinder', null],
		['Wegwerk - Kleine hinder', null],
		['Wegwerk - Matige hinder', null],
		['Wegwerk - Grote hinder', null],
		['Wegwerk - Zeer grote hinder', null],
		['Evenement - Onbekende hinder', null],
		['Evenement - Geen hinder', null],
		['Evenement - Kleine hinder', null],
		['Evenement - Matige hinder', null],
		['Evenement - Grote hinder', null],
		['Evenement - Zeer grote hinder', null],
		['Overige - Onbekende hinder', null],
		['Overige - Geen hinder', null],
		['Overige - Kleine hinder', null],
		['Overige - Matige hinder', null],
		['Overige - Grote hinder', null],
		['Overige - Zeer grote hinder', null],
		['Openbaar vervoer - Onbekende hinder', null],
		['Openbaar vervoer - Geen hinder', null],
		['Openbaar vervoer - Kleine hinder', null],
		['Openbaar vervoer - Matige hinder', null],
		['Openbaar vervoer - Grote hinder', null],
		['Openbaar vervoer - Zeer grote hinder', null],
		['Vaarwegen - Onbekende hinder', null],
		['Vaarwegen - Geen hinder', null],
		['Vaarwegen - Kleine hinder', null],
		['Vaarwegen - Matige hinder', null],
		['Vaarwegen - Grote hinder', null],
		['Vaarwegen - Zeer grote hinder', null]
];
// compute icon index based on type and severity
function getIconId(type, severity){
	if (isNaN(severity)) severity = -1;
	if (type == 8 || (type >= 26 && type <= 32) || (type >= 41 && type <= 45))
		id = severity + 7;
	else if (type == 0 || (type >= 17 && type <= 21) || type == 40 || type == 47)
		id = severity + 13;
	else if (type >= 22 && type <= 25)
		id = severity + 19;
	else if ((type >= 33 && type <= 37) || type == 46)
		id = severity + 25;
	else // (type < 8)
		id = severity + 1;
	if (id < 0 || id > 29) id=0;
	return id;
}

	var parkingIcons = {};

	// global variables
	var objs = new Array(), version;
	var markers = new Array();
	var map;
	var config;
	var uid;
	var tileserver = 'http://utrecht.andes.nl/ts-nl-gm/servlet/ts?';
	var datasets;
	var dataset;
	var regions;
	var region;
	var totalcnt;
	var curcnt;
	var curperiod = 2;
	var lastupdate;
	var configpath = 'config';
	var datapath = 'data';
	var templatepath = 'templates', currtemplate;
	var locorder = {};

	function getRoadworkType(id){
		for (var n=0; n<rwTypes.length; n++){
			if (rwTypes[n][0]==id)
				return rwTypes[n][1];
		}
		return '';
	}

	function getObstructionType(id){
		for (var n=0; n<obstructTypes.length; n++){
			if (obstructTypes[n][0]==id)
				return obstructTypes[n][1];
		}
		return '';
	}

	function getSeverityType(id){
		for (var n=0; n<severityTypes.length; n++){
			if (severityTypes[n][0]==id)
				return severityTypes[n][1];
		}
		return '';
	}
	
	function getParkingBlockType(id){
		for (var n=0; n<parkingBlockType.length; n++){
			if (parkingBlockType[n][0]==id)
				return parkingBlockType[n][1];
		}
		return '';
	}
	
	function getParkingType(id){
		id = parseInt(id);
		for (var n=0; n<parkingType.length; n++){
			if (parkingType[n][0]==id)
				return parkingType[n][1];
		}
		return '';
	}
	
	function getParkingTypeText(id){
		id = parseInt(id);
		for (var n=0; n<parkingType.length; n++){
			if (parkingType[n][0]==id)
				return parkingType[n][2];
		}
		return '';
	}

	// create custom icons
	function createIcons(){
		for (var n=0; n<30; n++){
			var icon = new GIcon();
			icon.image = 'images/icons/icon' + n + '.png';
			if (n<6) icon.shadow = 'images/icons/icon-bg1.png';
			else  icon.shadow = 'images/icons/icon-bg2.png';
			icon.iconSize = new GSize( 32, 32 );
			icon.shadowSize	= new GSize( 49, 33 );
			icon.iconAnchor = new GPoint( 14, 28 );
			icon.infoWindowAnchor = new GPoint( 24, 8 );
			icons[n][1] = icon;
		}
	}
	function createParkingIcons(){
		for (var i = 0; i < parkingType.length; i++){
			var ptype = parkingType[i][0], o = parkingIcons[ptype] = {};
			for (var j = 0; j < parkingBlockType.length; j++){
				var btype = parkingBlockType[j][0], icon = new GIcon();
				icon.image = 'images/parking/p_' + ptype + '_' + btype + '.gif';
				icon.iconSize = new GSize( 16, 16 );
				icon.shadowSize	= new GSize( 0, 0 );
				icon.iconAnchor = new GPoint( 8, 8 );
				icon.infoWindowAnchor = new GPoint( 0, 0 );
				o[btype] = icon;
			}
		}
	}

	// async data loading
	function getAsync(url, handler){
		GDownloadUrl(url, handler);
	}

	// load config
	var defUid = 'default';
	function loadConfig(prefUid, cfgCallback){
		uid = prefUid || getParam('uid', defUid);
		getAsync(configpath + '/' + uid + '.json', function(data, status){processConfig(data, status);if(cfgCallback)cfgCallback();});
	}

	// called when json file has finished loading
	function processConfig(data, status, cfgCallback, mapCallback){
		if (status != 200 && status != 304 && uid != defUid){
			loadConfig(defUid);
			return;
		}
		try{
			config = eval('(' + data + ')');
		}catch(e){
			if (uid != defUid){
				loadConfig(defUid);
				return;
			}else{
				alert("Geen gebruiker gegevens bekend!");
			}
			return
		}

		// populate period filter dropdown
		var lb = document.getElementById('periodFilter');
		var lb2 = document.getElementById('periodFilterVis');
		for (var n=0; n<periodFilter.length; n++){
			//Hidden value field.
			var opt = document.createElement('option');
			opt.text = periodFilter[n][1];
			opt.value = n;
			lb.options.add(opt);

			//Visible clickables
			var sb = new StringBuffer();
			sb.append(lb2.innerHTML);
			sb.append('<dt id="Perfilt' + n + '" class="stmenulinkof" onmouseover="this.className=\'stmenulinkon\'" onmouseout="this.className=\'stmenulinkof\'" onclick="document.getElementById(\'periodFilter\').value=\'' + n + '\'; document.getElementById(\'falkloader\').style.display = \'block\'; document.getElementById(\'falkloader2\').style.display = \'block\'; window.setTimeout(function(){doFilterUpdate();},100);">' + periodFilter[n][1] + '</dt>');
			lb2.innerHTML = sb.toString();
		}

		// get the datasets
		datasets = asArray(config, ['config','dataset']);
		
		// get regions
		regions = asArray(config, ['config','region']);
		if (regions){
			// populate dataset dropdown
			var lb = document.getElementById('selDataset');
			var lb2 = document.getElementById('selDatasetVis');

			for (var n=0; n<regions.length; n++){
				//Hidden value field.
				var opt = document.createElement('option');
				opt.text = regions[n].name;
				opt.value = n;
				lb.options.add(opt);

				//Visible clickables
				var sb = new StringBuffer();
				sb.append(lb2.innerHTML);
				sb.append('<dt id="Regfilt' + n + '" class="stmenulinkof" onmouseover="this.className=\'stmenulinkon\'" onmouseout="this.className=\'stmenulinkof\'" onclick="document.getElementById(\'selDataset\').value=\'' + n + '\'; document.getElementById(\'falkloader\').style.display = \'block\'; document.getElementById(\'falkloader2\').style.display = \'block\'; window.setTimeout(function(){doFilterUpdate();},100);">' + regions[n].name + '</dt>');
				lb2.innerHTML = sb.toString();	
			}
		}
		
		var layout = asArray(config, ['config', 'layout'], [{}])[0];
		if (!layout['template']) layout['template'] = defUid;
		currtemplate = layout['template'];
		var currpath = templatepath + '/' + currtemplate;
		addCss(currpath + '/style.css');
		$('img[src*=@template@]').each(function(){this.src=this.src.replace(/@template@/gi, currpath)});

		// set logo
		var logo = asArray(config, ['config','layout','logo'], null);
		if (logo){
			updateImg('logo', logo[0].url, logo[0].alt);
		}

		// set customer logo
		var clogo = asArray(config, ['config','layout','customerlogo'], null);
		if (clogo){
			var el = $('#clogo');
			el.show().children().attr({'src': clogo[0].url, 'alt': clogo[0].alt});
			if (clogo[0].link){
				el.attr({'href': clogo[0].link});
			}
		}
		
		// set banner
		var banner = asArray(config, ['config', 'layout', 'banner'], null);
		if (!banner){banner = [{url: 'images/foto_naam_balk3.png'}]}
		document.getElementById("header").style.backgroundImage = 'url("' + banner[0].url + '")';

		// set title
		var title = asArray(config, ['config','layout','title'], null);
		if (title){
			updateTitle(title[0]);
			updateSpan('appname', title[0]);
		}

		// set stylesheet
		var css = asArray(config, ['config','layout','stylesheet'], null);
		if (css){
			insertCss(css[0].url);
		}

		// set helpfile
		var help = asArray(config, ['config','layout','helpfile'], null);
		if (help){
			updateAnchor('helpfile', help[0].url);
		}
		
		// set info page
		var info = asArray(config, ['config','layout','info'], null);
		if (info && info[0]){
			updateInfoPage(info[0].url);
		}

		// set rp
		var rp = asArray(config, ['config','layout','rp'], null);
		if (rp && rp[0].url){
			updateRp(rp[0].url);
		}
		
		// Clear locorder
		locorder = {};
		var orders = asArray(config, ['config','location'], []);
		if (orders.length > 0){
			for (var n = 0; n < orders.length; n++){
				locorder[orders[n]["id"]] = orders[n]["order"];
			}
		}

		// set default filter
		document.getElementById('periodFilter').value = curperiod;

		// create main map
		if (GBrowserIsCompatible()) {
			map = new GMap2(document.getElementById('mapPane'), {mapTypes:[falkmap,G_SATELLITE_MAP,G_HYBRID_MAP]});
			map.enableDoubleClickZoom();
			map.enableScrollWheelZoom();
			map.enableContinuousZoom();
			map.addControl(new GLargeMapControl());
			map.addControl(new GMapTypeControl());
		}

		// load default region		
		loadRegion(0);

		// load default dataset
		loadRoadworks(0);
	}
	
	function addCss(url){
		var head = document.getElementsByTagName("head")[0], node = document.createElement('link');
		node.type = 'text/css';
		node.rel = 'stylesheet';
		node.href = url;
		node.media = 'screen';
		head.appendChild(node);
	}

	// load roadworks
	function loadRoadworks(n){
		dataset = n;
		getAsync(datapath + '/' + datasets[n].url, processRoadworks);
	}
	
	// load region
	function loadRegion(n){
		region = n;

		// set map
		if (region >= 0 && region <= regions.length){
			var ll = regions[region].boundsLl.split(','),
				bnds = new GLatLngBounds(new GLatLng(parseFloat(ll[0]), parseFloat(ll[1])), new GLatLng(parseFloat(ll[2]), parseFloat(ll[3]))),
				z = map.getBoundsZoomLevel(bnds);
			if (map.getZoom() == z){
				map.panTo(bnds.getCenter())
			}else{
				map.setCenter(bnds.getCenter(), z)
			}
			map.savePosition();
		}else{
			map.setCenter(new GLatLng(52.4, 5), 8);
		}
		
		hideLoader();
	}

	// called when the json file has finished downloading
	function processRoadworks(data){
		
		// get the raw data
		var json;
		try{
			json = eval('(' + data + ')');
		}catch(e){
			alert("Wegwerken kunnen niet geladen worden. Databestand kan niet ingelezen worden.");
			showApp();
			return;
		}

		// format all objects and store them in global array objs
		version = json.RIDSOutput.Version;
		objs = asArray(json, ['RIDSOutput','RoadActivities','RoadActivity'], []);

		// extract the date/time of last update
		if (json['RIDSOutput'] && json['RIDSOutput']['LastUpdate'])
			lastupdate = Date.parse(json.RIDSOutput.LastUpdate);
		if (lastupdate != null) {
			lastupdate = formatDate(lastupdate);
		} else {
			lastupdate = 'Onbekend';
		}

		// store nr of entries
		totalcnt = objs.length;

		// sort the object list on RoadAuthorityId, name
		objs.sort(function (a,b) {
				var orderA = locorder[a.RoadAuthorityId] || 100, 
					orderB = locorder[b.RoadAuthorityId] || 100;
				if (orderA != orderB)
					return orderA < orderB ? -1 : 1;
				if (a.RoadAuthorityId != b.RoadAuthorityId)
					return a.RoadAuthorityId<b.RoadAuthorityId ? -1 : 1;
				if (a.Name<b.Name)
					return -1; 
				else if (a.Name>b.Name)
					return 1; 
				return 0;
		});

		// create the markers (note: all markers are always created!)
		createMarkers();

		// apply filter
		applyFilter(curperiod);
		
		showApp();
	}
	
	function showApp(){
		$('#loadpage').remove();
		$('#mainpage').css('visibility', '');
		$('body').css('backgroundColor', '');
	}

	// create all the markers and position on the map
	function createMarkers(){
		map.clearOverlays();
		markers = [];
  		for (var n=0; n<objs.length; n++){
			var m = createObjMarkers(n);
			for (var i=0; i<m.length; i++){
				GEvent.addListener(m[i], "click", function(){
					showInfoWindow(this);
				});
				GEvent.addListener(m[i], "infowindowopen", function(){
					infoWindowOpened(this);
				});
				addMrkrDomEvents(m[i], objs[n]);
				map.addOverlay(m[i]);
			}
			markers.push(m);
		}
	}
	function addMrkrDomEvents(mrkr, obj){
		if (showTooltip){
			GEvent.addListener(mrkr, "mouseover", function(){showTooltip(this, obj, true)});
			GEvent.addListener(mrkr, "mouseout", function(){showTooltip(this, obj, false)});
		}
	}

	// create the marker(s) for the given activity
	function createObjMarkers(n){
		var mark = [];		
		var o2 = asArray(objs[n], ['DisplayPositions','DisplayPosition']);
		if (o2){
			for (var i=0; i<o2.length; i++){
				var lat = parseFloat(o2[i].Lat), lon = parseFloat(o2[i].Lon),
					iid = getIconId(parseInt(objs[n].Type.Id), parseInt(objs[n].Severity)),
					marker = new GMarker(new GLatLng(lat, lon), {icon:icons[iid][1]});
				mark.push(marker);
			}
		}
		return mark;
	}

	// find the index of the given marker
	function findMarker (marker){
		for (var n=0; n<markers.length; n++){
			for (var i=0; i<markers[n].length; i++){
				if (markers[n][i]==marker)
					return n;
			}
		}
		return 0;
	}
	
	function formatDate(d){
		var sd = formatDatePart(d.getDate()) + '-' + formatDatePart(d.getMonth() + 1) + '-' + d.getFullYear(),
			st = formatDatePart(d.getHours()) + ':' + formatDatePart(d.getMinutes());
		return st != '00:00' ? sd + ' ' + st : sd;
	}
	
	function formatDatePart(dp){
		return dp < 10 ? '0' + dp : dp
	}

	function htmlString(s){
		if (!s)
			return '';
		s = s.replace(/(\d)T(\d)/g, '$1 $2');
		s = s.replace(/\\n/g, '<br/>');
		var hlink = /\s*(ht|f)tp:\/\/([^ \,\;\:\!\)\(\"\'\<\>\f\n\r\t\v])+/g;
		s = s.replace (hlink, function ($0,$1,$2) { 
					s = $0.substring(0,$0.length); 
		                        // remove trailing dots, if any
		                        while (s.length>0 && s.charAt(s.length-1)=='.') 
		                        	s=s.substring(0,s.length-1);
					// add hlink
					return ' <a href="' + s + '" target="_blank">' + s + '</a>'; 
				}
		             ) 
		return s;
	}

function getDurationsPath() {
	return version <= 7 ? ['Durations','Duration'] : ['Durations','DurationBase'];
}

function applyFilter(n){
	
	n = parseInt(n);

	curperiod = n;

	if (n>0){
		var startDate = Date.today();
		var endDate;
		switch(n){
			case 1:
				endDate = Date.today().add(1).days();
				break;
			case 2:
				endDate = Date.today().add(7).days();
				break;
			case 3:
				endDate = Date.today().add(1).months();
				break;
			case 4:
				endDate = Date.today().add(12).months();
				break;
		}

		// reset nr of active items
		curcnt = 0;

		// loop through all objects, and hide those not in range
		var durPath = getDurationsPath();
		for (var n=0; n<objs.length; n++){
			var dur = asArray(objs[n], durPath), cnt = 0, hide = true;
			for (var i=0; i<dur.length && hide; i++){
				var d1 = Date.parse(dur[i].StartDate);
				var d2 = Date.parse(dur[i].FinishDate);
				hide = (d2 < startDate || d1 > endDate);
			}
			for (var j=0; j<markers[n].length; j++){
				if (hide) {
					markers[n][j].closeInfoWindow();
					markers[n][j].hide() 
				}
				else {
					markers[n][j].show();
					cnt++;
				}
			}
			if (cnt>0) curcnt++;
		}
	}
	else {
		// show all
		for (var n=0; n<markers.length; n++){
			for (var i=0; i<markers[n].length; i++){
				markers[n][i].show();
			}
		}
		curcnt = totalcnt;
	}

	if (curcnt == 0){
		alert('Let op: er zijn geen wegwerken in de gegeven periode.');
	}

	// rebuild the list 
	createList();
	
	// update filter panel
	updateGUI();

	hideLoader();
}

function hideLoader(){
	document.getElementById('falkloader').style.display = 'none';
	document.getElementById('falkloader2').style.display = 'none';
}

function updateGUI(){

	// list pane
	var title = 'Wegwerken en evenementen [' + curcnt + ' van ' + totalcnt + ']';
	var o = document.getElementById('listAccordionPane');
//	o.titleNode.innerHTML = title;

	// filter pane
	var title = 'Filter [' + datasets[dataset].name + '][' + periodFilter[curperiod][1] + ']';
	var o = document.getElementById('filterAccordionPane');
//	o.titleNode.innerHTML = title;

	// last update field
	updateSpan('lastUpdate', lastupdate);
}

function expandOrCollapse(obj1,obj2) {
	var el = document.getElementById(obj1);
	var il = document.getElementById(obj2);
	if ( el.style.display != "none" ) {
		el.style.display = 'none';
		il.className = 'in';
	}
	else {
		el.style.display = '';
		il.className = 'out';
	}
}

function doFilterUpdate(){
	var ds = document.getElementById('selDataset').value;
	var filt = document.getElementById('periodFilter').value;
    if (ds!=region){
		curperiod = filt;
		loadRegion(ds);
	}
	else {
		applyFilter(filt);
	}
}

