Andes.setStaticUrl(brpMapImagePath);

function brpMapType(baseUrls){
	Andes.BasicMapType.call(this, "Jacana", new Andes.RdProjection(), baseUrls, [0.8,1.6,3.2,6.4,12.8,25.6,51.2,102.4,204.8,409.8], null, "Andes")
};
Class.inherit(brpMapType, Andes.BasicMapType);

function brpMapWidget(opts, container, infoWindow){

	// properties
	var me = this;
	me.opts = cpyObj(opts, {startLocation: new Andes.Coordinate(136729, 456014), startZoom: 8, maxZoomPois: 6, iconPath: brpIconPath + 'map/'});
	me.container = $(container);
	me.infoWindow = $(infoWindow);
	me.map = null;
	me.locations = [];
	me.markers = [];
	me.polies = [];
	me.onIconClicked = null;
	me.onUserIconClicked = null;
	me.onTempIconClicked = null;
	me.userLocations = [];
	me.userMarkers = [];
	me.tempLocation = null;
	me.tempMarker = null;
	me.popInfo = {};

	// init map control
	var mapType = new brpMapType(brpTileServer);
	me.map = new Andes.Maps(me.container.get(0), [mapType]);
	me.map.addControl(new Andes.PanControl());
	me.map.getCurrentMapType().getCopyright = function() { return "&copy; " + (new Date()).getFullYear() + " Falkplan BV"	};
	me.map.addControl(new Andes.CopyrightControl());
	me.map.setCenter(opts.startLocation, opts.startZoom);
	me.map.enableScrollWheelZoom();
	
	// nodes
	me.popInfo.node = $('<div class="popInfo" title="Klik voor meer informatie." />');
	me.popInfo.descrNode = $('<div class="mceContentBody" />').appendTo('.description', infoWindow);
	me.popInfo.node.click(function(){me.showPopupInfo()}).mouseout(function(){me.hidePopupInfoIcon()});
	$('.close', infoWindow).click(function(){me.infoWindow.hide()});
	$(me.map.getLayer(Andes.Maps.LAYER_FLOAT)).append(me.popInfo.node);
	
	Andes.addListener(me.map, "moveend", function(){me.loadIcons()});
	Andes.addListener(me.map, "zoomend", function(){me.loadIcons()});
	me.loadIcons();
}

brpMapWidget.prototype.loadIcons = function(){
	if (this.map.getZoomLevel() <= 6) {
		var me = this, mb = this.map.getViewportBounds(), categories = [BRP_CAT_JUNCTIONS];
		for (var id in brpCategories) if (brpCategories[id].visible) categories.push(id);
		$.getJSON(brpGetPoisUrl + '&format=json&callback=?', {
				'x1': mb.getSouthWest().x,
				'y1': mb.getSouthWest().y,
				'x2': mb.getNorthEast().x,
				'y2': mb.getNorthEast().y,
				'cat': categories.join('+')
			},  
			function(data, textStatus){me.iconsLoaded(data, textStatus)}
		);
	}
	else {
		this.locations.length = 0;
		this.drawIcons();
	}
};

brpMapWidget.prototype.iconsLoaded = function(data, textStatus){
	this.locations = data["data"] || [];
	this.drawIcons();
};

brpMapWidget.ICONS = {};
brpMapWidget.prototype.createIcon = function(loc){
	var cid = parseInt(loc.category), icn = brpMapWidget.ICONS[loc.name], uri;
	if (icn) return icn; // cached icon
	if (icn = brpCategories[cid]){ // icon availabe in categories
		var icn = icn['mapIcon'];
		if (icn)
			icn = new Andes.Icon(icn['url'], new Andes.Dimensions(icn['width'] || 0, icn['height'] || 0), new Andes.Coordinate(icn['offsetx'] || 0, icn['offsety'] || 0));
	}
	if (!icn) {
		uri = this.opts.iconPath;
		if (cid == BRP_CAT_JUNCTIONS)
			uri += 'junction%0.png';
		else if (cid == BRP_CAT_ADDRESS)
			uri += 'address%0.png';
		var s = loc.iconnr || '00';
		icn = new Andes.Icon(uri.format(s.toLength(2)), new Andes.Dimensions(27, 27), new Andes.Coordinate(13, 13));
	}
	brpMapWidget.ICONS[loc.icon] = icn;
	return icn
}

brpMapWidget.prototype.drawIcons = function(){

	// clear all markers		
	for (var i = 0; i<this.markers.length; i++)
		this.map.removeOverlay(this.markers[i]);
	this.markers.length = 0;

	// add new markers
	var zoomlevel = this.map.getZoomLevel();
	if (zoomlevel <= this.opts.maxZoomPois) {
		var me = this;
		for (var i = 0; i<this.locations.length; i++) {
			var loc = this.locations[i], idx = i, 
				mrkr = new Andes.Marker(new Andes.Coordinate(loc.x, loc.y), this.createIcon(loc), { "title": loc.name});
			Andes.addListener(mrkr, "click", me.createIconClickHandler(idx));
			if (parseInt(loc.category) > BRP_CAT_JUNCTIONS && loc.description){
				Andes.addListener(mrkr, "mouseover", aplyArgs(me, me.markerMouseOver, i));
				Andes.addListener(mrkr, "mouseout", aply(me, me.markerMouseOut))
			}
			this.map.addOverlay(mrkr);
			this.markers.push(mrkr);
		}
	}            
}

brpMapWidget.prototype.markerMouseOver = function(idx){
	var pi = this.popInfo;
	if (pi.timer) {
		clearTimeout(pi.timer);
		pi.timer = null
	}
	pi.index = idx;
	pi.timer = setTimeout(aply(this, this.showPopupInfoIcon), 500)
}

brpMapWidget.prototype.markerMouseOut = function(evt){
	var pi = this.popInfo;
	if (pi.timer) {
		clearTimeout(pi.timer);
		pi.timer = null
	} else {
		// if element we move onto is the info icon then enable; otherwise hide info icon
		if ((evt.relatedTarget || evt.toElement) == pi.node[0]){
			
		}else{
			this.hidePopupInfoIcon()
		}
	}
}

brpMapWidget.prototype.showPopupInfoIcon = function(){
	var pi = this.popInfo;
	pi.timer = null;
	var mrkr = this.markers[pi.index], pxc = this.map.fromCoordToDivPixel(mrkr.getCoordinate()),
		dim = mrkr.getIcon().getDimensions(), anchor = mrkr.getIcon().getImageAnchor();
	pi.node.css({'left': parseInt(pxc.x) + dim.width - anchor.x - 1,'top': parseInt(pxc.y) - anchor.y - 4}).show()
}

brpMapWidget.prototype.hidePopupInfoIcon = function(){
	this.popInfo.node.hide()
}

brpMapWidget.prototype.showPopupInfo = function(){
	var loc = this.locations[this.popInfo.index];
	this.popInfo.descrNode.html(loc.description);
	this.infoWindow.show();
}

brpMapWidget.prototype.createIconClickHandler = function(idx){
	var me = this;
	return function(){me.iconClicked(idx);};
}

brpMapWidget.prototype.iconClicked = function(i){
	if (i==-1){
		if (this.onTempIconClicked)
			this.onTempIconClicked(this.tempLocation);
	}
	else if (i<1000) {
		if (this.onIconClicked){
			this.onIconClicked(this.locations[i]);
		}
	}
	else {
		if (this.onUserIconClicked){
			this.onUserIconClicked(this.userLocations[i-1000]);
		}
	}
};

brpMapWidget.prototype.zoomTo = function(loc, zoom){
	this.map.setCenter(new Andes.Coordinate(loc.x, loc.y), zoom);
}
 
brpMapWidget.prototype.drawRoute = function(route){

	// clear all polies
	for (var i = 0; i<this.polies.length; i++)
		this.map.removeOverlay(this.polies[i]);
	this.polies.length = 0;
	
	// add route
	if (route){
		var zoomlevel = this.map.getZoomLevel();
		var coords = new Array();
		$(route.sections).each(function(){
			$(this.coordinates).each(function(){
				coords.push(new Andes.Coordinate(this.x, this.y));
			});
		});
		if (coords.length>0) {
			var polyline = new Andes.Polyline(coords, "blue", (14-zoomlevel)/2.0);
			this.map.addOverlay(polyline);
			this.polies.push(polyline);
		}
	}
}

brpMapWidget.prototype.showTempMarker = function(loc){
	var me = this;
	if (this.tempMarker)
		this.map.removeOverlay(this.tempMarker);
	loc.icon = brpTempMarkerIcon;
	var mrkr = new Andes.Marker(new Andes.Coordinate(loc.x, loc.y), this.createIcon(loc), { "title": loc.name});
	Andes.addListener(mrkr, "click", me.createIconClickHandler(-1));                    
	this.map.addOverlay(mrkr);
	this.tempMarker = mrkr;
	this.tempLocation = loc;
}

brpMapWidget.prototype.hideTempMarker = function(){
	if (this.tempMarker){
		this.map.removeOverlay(this.tempMarker);
		this.tempMarker = null;
		this.tempLocation = null;
	}
}

brpMapWidget.prototype.addUserMarker = function(loc){
	var me = this;
	var n = this.userMarkers.length + 1;
	loc.iconnr = n < 10 ? '0' + n : '' + n;
	var mrkr = new Andes.Marker(new Andes.Coordinate(loc.x, loc.y), this.createIcon(loc), { "title": loc.name});
	Andes.addListener(mrkr, "click", me.createIconClickHandler(1000+this.userLocations.length));                    
	this.map.addOverlay(mrkr);
	this.userMarkers.push(mrkr);
	this.userLocations.push(loc);
}

brpMapWidget.prototype.resize = function(){
	this.map.checkResize();
}