/* FUNCTIONS FOR DRAWING GOOGLE MAPS WITH GPS VISUALIZER (http://www.gpsvisualizer.com/) */

gv_api_version = FindGoogleAPIVersion();




	




// Define parameters of different marker types
if (!self.gv_icons) { gv_icons = new Array(); }
gv_icons['circle'] = { is:[11,11],ia:[5,5],ss:[13,13],iwa:[10,2],isa:[5,9],im:[0,0, 10,0, 10,10, 0,10, 0,0],letters:true };
gv_icons['pin'] = { is:[15,26],ia:[7,25],ss:[30,26],iwa:[7,1],isa:[12,16],im:[5,25, 5,15, 2,13, 1,12, 0,10, 0,5, 1,2, 2,1, 4,0, 10,0, 12,1, 13,2, 14,4, 14,10, 13,12, 12,13, 9,15, 9,25, 5,25 ],letters:true };
gv_icons['square'] = { is:[11,11],ia:[5,5],ss:[13,13],iwa:[10,2],isa:[5,9],im:[0,0, 10,0, 10,10, 0,10, 0,0],letters:true };
gv_icons['triangle'] = { is:[13,13],ia:[6,6],ss:[15,15],iwa:[11,3],isa:[6,10],im:[0,11, 6,0, 12,11, 0,11],letters:false };
gv_icons['diamond'] = { is:[13,13],ia:[6,6],ss:[13,13],iwa:[11,3],isa:[6,10],im:[6,0, 12,6, 6,12, 0,6, 6,0],letters:false };
gv_icons['airport'] = { is:[17,17],ia:[8,8],ss:[19,19],iwa:[13,3],isa:[13,17],im:[6,0, 10,0, 16,6, 16,10, 10,16, 6,16, 0,10, 0,6, 6,0],letters:false };
gv_icons['google'] = { is:[20,34],ia:[9,34],ss:[37,34],iwa:[9,2],isa:[18,25],im:[8,33, 8,23, 1,13, 1,6, 6,1, 13,1, 18,6, 18,13, 11,23, 11,33],letters:true };
gv_icons['googleblank'] = { is:[20,34],ia:[9,34],ss:[37,34],iwa:[9,2],isa:[18,25],im:[8,33, 8,23, 1,13, 1,6, 6,1, 13,1, 18,6, 18,13, 11,23, 11,33],letters:true };
gv_icons['googlemini'] = { is:[12,20],ia:[6,20],ss:[22,20],iwa:[5,1],isa:[10,15],im:[4,19, 4,14, 0,7, 0,3, 4,0, 7,0, 11,3, 11,7, 7,14, 7,19, 4,19],letters:true };
gv_icons['blankcircle'] = { is:[64,64],ia:[31,31],ss:[70,70],iwa:[55,8],isa:[31,63],im:[19,3, 44,3, 60,19, 60,44, 44,60, 19,60, 3,44, 3,19, 19,3],letters:false };

// Make sure defaults have been set; if not, things break. (Some backwards-compatibility (BC) stuff here)
if (self.gv_default_marker) {
	gv_marker_icon = (gv_default_marker['icon']) ? gv_default_marker['icon'] : 'googlemini';
	gv_marker_color = (gv_default_marker['color']) ? gv_default_marker['color'] : 'red';
	gv_marker_icon_size = (gv_default_marker['size']) ? gv_default_marker['size'] : null;
	gv_marker_icon_trans = (gv_default_marker['transparent']) ? gv_default_marker['transparent'] : null;
	gv_marker_icon_imagemap = (gv_default_marker['imagemap']) ? gv_default_marker['imagemap'] : null;
} else {
	if (!self.gv_marker_icon) { gv_marker_icon = (self.default_icon_style) ? default_icon_style : 'googlemini'; } // BC
	if (!self.gv_marker_color) { gv_marker_color = (self.default_icon_color) ? default_icon_color : 'red'; } // BC
	gv_marker_icon_size = gv_marker_icon_trans = gv_marker_icon_imagemap = null;
}
if (!self.gv_marker_link_target) { gv_marker_link_target = (self.marker_link_target) ? marker_link_target : '_blank'; } // BC
if (!self.gv_maptypecontrol_style) { gv_maptypecontrol_style = (self.maptypecontrol_style) ? maptypecontrol_style : 'menu'; } // BC
if (self.gv_filter_map_types==null) { gv_filter_map_types = (self.filter_map_types!=null) ? filter_map_types : true; }
if (!self.gv_icon_directory) { gv_icon_directory = 'http://www.gpsvisualizer.com/google_maps/icons/'; }
if (self.gv_driving_directions==null) { gv_driving_directions = false; }

// Some stuff related to marker lists
var gv_marker_list; var gv_marker_list_html = '';
var gv_marker_array_name; var gv_marker_list_div; var gv_marker_list_div_name; var gv_marker_list_map_name;
if (self.gv_marker_list_options) {
	gv_marker_list_html = '';
	gv_marker_list_map_name = (gv_marker_list_options['map']) ? gv_marker_list_options['map'] : 'gmap';
	gv_marker_array_name = (gv_marker_list_options['array']) ? gv_marker_list_options['array'] : 'wpts';
	if (document.getElementById(gv_marker_list_options['div'])) {
		gv_marker_list_div_name = gv_marker_list_options['div'];
		gv_marker_list_div = document.getElementById(gv_marker_list_div_name);
	} else if (document.getElementById('gv_marker_list')) {
		gv_marker_list_div_name = 'gv_marker_list';
		gv_marker_list_div = document.getElementById(gv_marker_list_div_name);
	} else {
		gv_marker_list_div_name = '';
		gv_marker_list_div = null;
	}
	if (gv_marker_list_div) {
		if (gv_marker_list_options['list'] === false) { // this trumps everything
			gv_marker_list_div.style.display = 'none';
			gv_marker_list = false;
		} else if (gv_marker_list_div.style.display == '' || gv_marker_list_options['list'] == true) {
			gv_marker_list_div.style.display = 'block';
			gv_marker_list = true;
		} else {
			gv_marker_list = false;
		}
	}
}
//alert ('gv_marker_list = '+gv_marker_list+', gv_marker_list_div.style.background = '+gv_marker_list_div.style.background);

// Some stuff related to filtering waypoints
var gv_filter_waypoints; var gv_filter_marker_list;
if (self.gv_marker_filter_options) {
	gv_filter_waypoints = (gv_marker_filter_options['filter']) ? true : false;
	gv_filter_marker_list = (gv_marker_filter_options['update_list']) ? true : false;
}

// Set up some styles
document.writeln('		<style type="text/css">');
document.writeln('			img.gv_wpt_thumbnail { display:block; text-decoration:none; margin:0px; }');
document.writeln('			img.gv_wpt_photo { display:block; text-decoration:none; margin:0px; }');
document.writeln('			.gv_tooltip {');
document.writeln('				background-color:#FFFFFF; filter:alpha(opacity=100); -moz-opacity:1.0;');
document.writeln('				border:1px solid #666666; padding:2px; text-align:left;');
document.writeln('				font:10px Verdana,sans-serif; color:#000000; white-space: nowrap;');
document.writeln('			}');
document.writeln('			.gv_tooltip img.gv_wpt_thumbnail { display:block; padding-top:3px; }');
document.writeln('			.gv_tooltip img.gv_wpt_photo { display:none; }');
document.writeln('			.gv_legend_tooltip {');
document.writeln('				position:absolute; top:-2000px; z-index:9999; display:none; visibility:hidden;');
document.writeln('			}');
document.writeln('			.gv_wpt { font: 10px Verdana,sans-serif; z-index:999; }');
document.writeln('			.gv_wpt img.gv_wpt_thumbnail { border:1px solid; margin:6px 0px 6px 0px; }');
document.writeln('			.gv_wpt img.gv_wpt_photo { margin:8px 0px 8px 0px; }');
document.writeln('			.gv_driving_directions { background-color:#EEEEEE; padding:4px; margin-top:12px; }');
document.writeln('			.gv_driving_directions_heading { color:#666666; font-weight:bold; }');
document.writeln('			img.hidden_in_info_window { display:none; }');
document.writeln('			.gv_label {');
document.writeln('				filter:alpha(opacity=80); -moz-opacity:0.8;');
document.writeln('				background-color:#333333; border:1px solid #000000; padding:2px;');
document.writeln('				font:9px Verdana,sans-serif; color:#FFFFFF; text-align:left; white-space: nowrap;');
document.writeln('			}');
document.writeln('			.gv_label img { display:none; }');
document.writeln('			.gv_marker_list {');
document.writeln('				font-family:Verdana,sans-serif;');
document.writeln('			}');
document.writeln('			.gv_marker_list_item {');
document.writeln('				padding:2px 0px 6px 0px;');
document.writeln('				font-family:Verdana,sans-serif;');
document.writeln('				font-size:10px;');
document.writeln('				line-height:1.2em;');
document.writeln('			}');
document.writeln('			.gv_marker_list_item .name { font-size:10px; font-weight:bold; }');
document.writeln('			.gv_marker_list_item .name img { display:none; }');
document.writeln('			.gv_marker_list_item .desc { font-size:9px; filter:alpha(opacity=80); -moz-opacity:0.8; }');
document.writeln('			.gv_maptypelink {');
document.writeln('				background-color:#DDDDDD; color:#000000; text-align:center; white-space: nowrap;');
document.writeln('				border:1px solid; border-color: #999999 #222222 #222222 #999999; padding:1px 2px 1px 2px; margin-bottom:3px;');
document.writeln('				font:9px Verdana,sans-serif; text-decoration:none; cursor:pointer;');
document.writeln('			}');
document.writeln('			.gv_maptypelink_selected { background-color:#FFFFFF; }');
document.writeln('		</style>');
document.writeln('		<style type="text/css" media="print">'); // force stuff to print even though Google thinks it shouldn't
document.writeln('			img[src^="http://www.gpsvisualizer.com/"].gmnoprint { display:inline; }'); // anything GV puts up
document.writeln('			img[src^="http://mt.google.com/mld"].gmnoprint { display:inline; }'); // Google Maps tracks
document.writeln('			img[src$="transparent.png"].gmnoprint { display:none; }');
document.writeln('			img[src$="shadow.png"].gmnoprint { display:none; }');
document.writeln('			img[src$="crosshair.gif"].gmnoprint { display:none; }');
document.writeln('			.gv_label { color:#000000; background-color:#FFFFFF; filter:alpha(opacity=100); -moz-opacity:1.0; }');
document.writeln('		</style>');


// Create a default icon for all markers
var defaultIcon = new GIcon();
if (gv_marker_icon.substring(0,7) == 'http://') {
	defaultIcon.image = gv_marker_icon;
	defaultIcon.iconSize = (gv_marker_icon_size && gv_marker_icon_size[0] && gv_marker_icon_size[1]) ? new GSize(gv_marker_icon_size[0],gv_marker_icon_size[1]) : new GSize(32,32);
	defaultIcon.iconAnchor = new GPoint(defaultIcon.iconSize.width*0.5,defaultIcon.iconSize.height*0.5);
	defaultIcon.infoWindowAnchor = new GPoint(defaultIcon.iconSize.width*0.75,0);
	defaultIcon.infoShadowAnchor = new GPoint(defaultIcon.iconSize.width*0.5,defaultIcon.iconSize.height);
	defaultIcon.transparent = (gv_marker_icon_trans && gv_marker_icon_trans.substring(0,7) == 'http://') ? gv_marker_icon_trans : null;
	defaultIcon.imageMap = (gv_marker_icon_imagemap && gv_marker_icon_imagemap.length > 5) ? gv_marker_icon_imagemap : [ 0,0, 0,defaultIcon.iconSize.height-1, defaultIcon.iconSize.width-1,defaultIcon.iconSize.height-1, defaultIcon.iconSize.width-1,0, 0,0 ];
	defaultIcon.shadow = null; defaultIcon.shadowSize = null;
	gv_icons[gv_marker_icon] = { is:[defaultIcon.iconSize.width,defaultIcon.iconSize.height],ia:[defaultIcon.iconAnchor.width,defaultIcon.iconAnchor.height],ss:null,iwa:[defaultIcon.infoWindowAnchor.width,defaultIcon.infoWindowAnchor.height],isa:[defaultIcon.infoShadowAnchor.width,defaultIcon.infoShadowAnchor.height],im:defaultIcon.imageMap };
} else {
	if (!gv_icons[gv_marker_icon]) { gv_marker_icon = 'pin'; }
	defaultIcon.image = gv_icon_directory+gv_marker_icon+'/'+gv_marker_color+'.png';
	defaultIcon.transparent = gv_icon_directory+gv_marker_icon+'/'+gv_marker_color+'-t.png';
	defaultIcon.iconSize = new GSize(gv_icons[gv_marker_icon]['is'][0],gv_icons[gv_marker_icon]['is'][1]);
	defaultIcon.iconAnchor = new GPoint(gv_icons[gv_marker_icon]['ia'][0],gv_icons[gv_marker_icon]['ia'][1]);
	defaultIcon.shadow = (gv_icons[gv_marker_icon]['ss'][0]) ? gv_icon_directory+gv_marker_icon+'/shadow.png' : null;
	defaultIcon.shadowSize = (gv_icons[gv_marker_icon]['ss'][0]) ? new GSize(gv_icons[gv_marker_icon]['ss'][0],gv_icons[gv_marker_icon]['ss'][1]) : null;
	defaultIcon.infoWindowAnchor = new GPoint(gv_icons[gv_marker_icon]['iwa'][0],gv_icons[gv_marker_icon]['iwa'][1]);
	defaultIcon.infoShadowAnchor = new GPoint(gv_icons[gv_marker_icon]['isa'][0],gv_icons[gv_marker_icon]['isa'][1]);
	defaultIcon.imageMap = (gv_icons[gv_marker_icon]['im']) ? gv_icons[gv_marker_icon]['im'] : [ 0,0, 0,gv_icons[gv_marker_icon]['is'][1]-1, gv_icons[gv_marker_icon]['is'][0]-1,gv_icons[gv_marker_icon]['is'][1]-1, gv_icons[gv_marker_icon]['is'][0]-1,0, 0,0 ];
}

var gv_marker_count = 0;
function GV_Marker(map,mm,marker_info,lon,name,desc,url,color,style,width,label_id) {

//toegevoegd mm = markermanager
	// The following variables need to have been defined:
	//   gv_icons (array of icon info), gv_icon_directory (absolute URL)
	//   gv_marker_icon (string), gv_marker_color (string), gv_marker_link_target (string)
	//   gv_api_version (number), gv_marker_list (boolean), gv_marker_list_html (string)
	
	var m = {};
	
	// The old "GV_Marker" function had everything in a particular order; this new one uses more user-friendly named parameters.
	// If the second argment has a 'lat' item INSIDE of it, then it's the new version; otherwise that's just the latitude.
	if (marker_info['lat'] != undefined || marker_info['address'] != undefined) {
		m = marker_info;
		if (m['style'] && !m['icon']) { m['icon'] = m['style']; } // this one changed recently
	} else {
		m['lat'] = marker_info; m['lon'] = lon; m['name'] = name; m['desc'] = desc; m['url'] = url; m['color'] = color; m['icon'] = style; m['width'] = width; m['label_id'] = label_id;
	}
	
	if (m['address'] && !m['lat']) { // allow an "address" field to define the location in a pinch
		var geocoder = new GClientGeocoder();
		geocoder.getLatLng(
			m['address'],
			function(coords){
				if (coords) {
					m['lat'] = coords.lat(); m['lon'] = coords.lng();
					GV_Marker(map,m);
				}
			}
		);
		return;
	}
	
	var tempIcon = new GIcon(defaultIcon);
	var scale = (m['scale'] > 0) ? m['scale'] : 1;
	
	if (m['icon_url'] || (m['icon'] && m['icon'].substring(0,7) == 'http://') || (!m['icon'] && gv_marker_icon.substring(0,7) == 'http://')) {
		tempIcon.image = (m['icon_url']) ? m['icon_url'] : m['icon'] || gv_marker_icon;
		tempIcon.iconSize = (m['icon_size'] && m['icon_size'][0] && m['icon_size'][1]) ? new GSize(m['icon_size'][0]*scale,m['icon_size'][1]*scale) : new GSize(32*scale,32*scale);
		tempIcon.iconAnchor = new GPoint(tempIcon.iconSize.width*0.5,tempIcon.iconSize.height*0.5);
		tempIcon.infoWindowAnchor = new GPoint(tempIcon.iconSize.width*0.75,0);
		tempIcon.infoShadowAnchor = new GPoint(tempIcon.iconSize.width*0.5,tempIcon.iconSize.height);
		tempIcon.shadow = null; tempIcon.shadowSize = null;
		tempIcon.transparent = null; tempIcon.imageMap = null;
	} else if (m['icon'] || m['color'] || m['letter'] || m['opacity'] || m['scale'] > 0) {
		var icon = (m['icon'] && gv_icons[m['icon']]) ? m['icon'] : gv_marker_icon;
		var color = (m['color']) ? m['color'] : gv_marker_color;
		if (color.substring(0,1) == '#') { color = color.replace(/^\#/,''); }
		var transparent_icon = color+'-t.png';
		var base_url = (gv_icons[icon]['directory']) ? gv_icons[icon]['directory'] : gv_icon_directory+icon;
		tempIcon.iconSize = new GSize(gv_icons[icon]['is'][0]*scale,gv_icons[icon]['is'][1]*scale);
		tempIcon.iconAnchor = new GPoint(gv_icons[icon]['ia'][0]*scale,gv_icons[icon]['ia'][1]*scale);
		tempIcon.shadow = (gv_icons[icon]['ss']) ? base_url+'/shadow.png' : null;
		tempIcon.shadowSize = (gv_icons[icon]['ss']) ? new GSize(gv_icons[icon]['ss'][0]*scale,gv_icons[icon]['ss'][1]*scale) : null;
		tempIcon.infoWindowAnchor = new GPoint(gv_icons[icon]['iwa'][0]*scale,gv_icons[icon]['iwa'][1]*scale);
		tempIcon.infoShadowAnchor = new GPoint(gv_icons[icon]['isa'][0]*scale,gv_icons[icon]['isa'][1]*scale);
		var opacity = ''; if (m['opacity'] && m['opacity'] > 0 && m['opacity'] < 1) {
			opacity = '-'+Math.round(m['opacity']*100);
			tempIcon.shadow = null; tempIcon.shadowSize = null;
		}
		tempIcon.image = base_url+'/'+color+opacity+'.png';
		if (scale != 1) { tempIcon.imageMap = new Array(); for (j=0; j<gv_icons[icon]['im'].length; j++) { tempIcon.imageMap[j] = gv_icons[icon]['im'][j]*scale; } }
		else { tempIcon.imageMap = gv_icons[icon]['im']; }
		if (m['letter']) {
			// tempIcon.label = { url:gv_icon_directory+icon+'/transparent-'+m['letter'].toUpperCase()+'.png', anchor:new GPoint(0,0), size:new GSize(gv_icons[icon]['is'][0],gv_icons[icon]['is'][1]) }; // makes big gray boxes in IE!
			tempIcon.transparent = base_url+'/transparent-'+m['letter'].toUpperCase()+'.png'; // not the most kosher solution, but it seems to work
		} else {
			tempIcon.transparent = base_url+'/'+color+'-t.png';
		}
	}
	
	// overload!!!!
	if (document.location.toString().indexOf('moveon.org') > -1) {
		var color = (m['color']) ? m['color'] : gv_marker_color;
		tempIcon.image = 'http://labs.google.com/ridefinder/images/mm_20_'+color+'.png';
		tempIcon.shadow = 'http://labs.google.com/ridefinder/images/mm_20_shadow.png';
		tempIcon.transparent = null;
	}
	var marker = (gv_api_version >= 2) ? new GMarker( new GLatLng(m['lat'],m['lon']), {icon:tempIcon, draggable:false} ) : new GMarker( new GPoint(m['lon'],m['lat']), tempIcon );
	var iw_html = '';
	if (m['name']) {
		if (m['url'] && m['url'] != null) { iw_html = iw_html + '<b><a target="'+gv_marker_link_target+'" href="'+m['url']+'">'+m['name']+'</a></b>'; }
		else { iw_html = iw_html + '<b>'+m['name']+'</b>'; }
	}
	if (m['thumbnail'] && !m['photo']) {
		var tn_style = (m['thumbnail_width']) ? ' style="width:'+m['thumbnail_width']+'px;"' : '';
		var thumbnail = '<img class="gv_wpt_thumbnail" src="'+m['thumbnail']+'"'+tn_style+'>';
		if (m['url']) { thumbnail = '<a target="'+gv_marker_link_target+'" href="'+m['url']+'">'+thumbnail+'</A>'; }
		iw_html = iw_html + thumbnail;
	} else if (m['photo']) {
		iw_html = iw_html + '<div><img class="gv_wpt_photo" src="'+m['photo']+'"></div>';
	}
	if (m['desc']) {
		iw_html = iw_html + '<div>' + m['desc'] + '</div>';
	}
	if (m['dd'] || (gv_driving_directions && m['dd']!==false)) {
		iw_html = iw_html + '<div class="gv_driving_directions"><form action="http://maps.google.com/maps" target="_blank" style="margin:0px;">';
		iw_html = iw_html + '<input type="hidden" name="daddr" value="'+(m['dd_lat']||m['lat'])+','+(m['dd_lon']||m['lon'])+' ('+m['name'].replace(/<[^>]*>/g,'').replace(/"/g,"&quot;")+')'+'">';
		iw_html = iw_html + '<p class="gv_driving_directions_heading" style="margin:2px 0px 4px 0px; white-space:nowrap">Driving directions to this point</p>';
		iw_html = iw_html + '<p style="margin:0px">Enter your starting address:<br><input type="text" size="20" name="saddr" value="">&nbsp;<input type="submit" value="Go"></p>';
		iw_html = iw_html + '</div>';
		// add a form for driving directions
	}
	var max_width = (gv_api_version >= 2) ? map.getSize().width - 100 : 600;
	var width = (eval(m['width']) > 200 && eval(m['width']) <= max_width) ? 'width:'+m['width']+'px;' : ''; // apparently you can't make it less than 217 (let's leave 17 for the close box though)
	var info_html = '<DIV style="text-align:left; '+width+'" class="gv_wpt">'+iw_html+'</DIV>';
	if (iw_html) { GEvent.addListener(marker, "click", function(){ marker.openInfoWindowHtml(info_html, {maxWidth:max_width}); }); }
	
	var out_of_range = false;
	if (gv_filter_waypoints) {
		var min_lat = map.getBounds().getSouthWest().lat();
		var min_lon = map.getBounds().getSouthWest().lng();
		var max_lat = map.getBounds().getNorthEast().lat();
		var max_lon = map.getBounds().getNorthEast().lng();
		if (max_lon < min_lon) { min_lon = -180; max_lon = 180; } // Date Line weirdness
		if (m['lon'] < min_lon || m['lon'] > max_lon || m['lat'] < min_lat || m['lat'] > max_lat) {
			out_of_range = true;
		}
	}
	
	if (m['name'] || m['thumbnail']) {
		if (m['label'] || m['label_id']) { // draw a permanent label
			var label_text = (m['label']) ? m['label'] : m['name'];
			var label = new ELabel(new GLatLng(m['lat'],m['lon']),label_text,"gv_label",new GSize(tempIcon.iconSize.width/2+1,8),80,false,m['label_id']);
			map.addOverlay(label);
		}
		if (gv_api_version >= 2) {
			// v2 tooltips, adapted from http://www.econym.demon.co.uk/googlemaps/tooltips4.htm
			if (!document.getElementById('gv_tooltip')) { tooltip = GV_Initialize_Marker_Tooltip(map); } // initialize it if it hasn't been done yet
			var tooltip_html = m['name']+' ';
			if (m['thumbnail']) {
				var tn_style = (m['thumbnail_width']) ? ' style="width:'+m['thumbnail_width']+'px;"' : '';
				tooltip_html = tooltip_html + '<img class="gv_wpt_thumbnail" src="'+m['thumbnail']+'"'+tn_style+'>';
			}
			if (m['photo']) { tooltip_html = tooltip_html + '<img class="gv_wpt_photo" src="'+m['photo']+'">'; } // photo is hidden in tooltip but gets pre-loaded!
			marker.tooltip = '<div class="gv_tooltip">'+tooltip_html+'</div>';
			GEvent.addListener(marker,'mouseover', function() { GV_Create_Marker_Tooltip(map,marker); });
			GEvent.addListener(marker,'mouseout', function() { tooltip.style.visibility = 'hidden' });
		} else {
			// v1 tooltips, adapted from http://www.econym.demon.co.uk/googlemaps1/tooltips.htm
			var topElement = marker.images[0];
			if (marker.iconImage) { topElement = marker.iconImage; }
			if (marker.transparentIcon) { topElement = marker.transparentIcon; }
			if (marker.imageMap) { topElement = marker.imageMap; }
			topElement.setAttribute("title",m['name']);
		}
	}
	if (gv_api_version >= 2) {
		// This info can be used by other functions, like the "marker list":
		marker.name = (m['name']) ? m['name'] : '[unnamed]';
		marker.desc = (m['desc']) ? m['desc'] : '';
		marker.url = (m['url']) ? m['url'] : '';
		marker.shortdesc = (m['shortdesc']) ? m['shortdesc'] : '';
		marker.html = info_html;
		marker.max_width = max_width;
		marker.color = (m['color']) ? m['color'] : gv_marker_color;
		marker.width = tempIcon.iconSize.width;
		marker.height = tempIcon.iconSize.height;
		marker.image = tempIcon.image;
		marker.coords = new GLatLng(m['lat'],m['lon']);
		
		gv_marker_count += 1;
		
		if (gv_marker_list && m['type'] != 'tickmark' && m['type'] != 'trackpoint' && !m['nolist']) {
			marker.list_html = GV_Marker_List_Item(marker,gv_marker_list_map_name,gv_marker_array_name+'['+(gv_marker_count-1)+']');
			if (!gv_filter_marker_list || !out_of_range) {
				gv_marker_list_html += marker.list_html;
			}
		}
	}
	if (!gv_filter_waypoints) {
		//map.addOverlay(marker);
		// eerste 12 zijn provincies
		if ( gv_marker_count < 13) {
    		mm.addMarker(marker,2,7);
		}
		else
		{
		// elke 5e wordt getoond
			if ( (gv_marker_count % 5) == 0 ){
    				mm.addMarker(marker,8,17);
			}
			else
			{
		    	mm.addMarker(marker,9,17);
			}
		}
	}
		
	return marker;
}

function GV_Initialize_Marker_Tooltip(map) {
	var tt = document.createElement('div');
	tt.id = 'gv_tooltip';
	tt.style.visibility = 'hidden';
	map.getPane(G_MAP_FLOAT_PANE).appendChild(tt);
	return (tt);
}

function GV_Create_Marker_Tooltip(map,marker) {
	// copied almost verbatim from http://www.econym.demon.co.uk/googlemaps/tooltips4.htm
	tooltip.innerHTML = marker.tooltip;
	var point=map.getCurrentMapType().getProjection().fromLatLngToPixel(map.fromDivPixelToLatLng(new GPoint(0,0),true),map.getZoom());
	var offset=map.getCurrentMapType().getProjection().fromLatLngToPixel(marker.getPoint(),map.getZoom());
	var anchor=marker.getIcon().iconAnchor;
	var width=marker.getIcon().iconSize.width;
	var height=tooltip.clientHeight;
	offset.x += -1; offset.y += 4; // a little adjustment
	height = 18; // makes all tooltips hover near the mouse, even if they're tall and have thumbnails or whatnot (they expand downward instead of upward)
	var pos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(offset.x - point.x - anchor.x + width, offset.y - point.y -anchor.y -height)); 
	pos.apply(tooltip);
	tooltip.style.visibility = 'visible';
}

function GV_Marker_List() {
	if (gv_marker_list) {
		var header = (gv_marker_list_options['header']) ? gv_marker_list_options['header'] : '';
		var footer = (gv_marker_list_options['footer']) ? gv_marker_list_options['footer'] : '';
		gv_marker_list_div.innerHTML = header+gv_marker_list_html+footer;
	}
	if (document.getElementById('gv_marker_list_handle') && document.getElementById('gv_marker_list_table')) {
		if (!document.getElementById("gv_marker_list_handle").root) { // only needs to be done once
			Drag.init(document.getElementById("gv_marker_list_handle"),document.getElementById("gv_marker_list_table"));
		}
	}
}

function GV_Marker_List_Item(m,map_name,marker_name) {
	var default_color = (gv_marker_list_options['default_color']) ? gv_marker_list_options['default_color'] : '#000000';
	var color = (gv_marker_list_options['colors']) ? m['color'] : default_color;
	var color_style = 'color:'+color;
	
	var unhide = '';
	var center = (gv_marker_list_options['center']) ? map_name+'.setCenter('+marker_name+'.coords); ' : '';
	var zoom_in = (gv_marker_list_options['zoom']) ? map_name+'.zoomIn(); ' : '';
	var hide_crosshair = (gv_marker_list_options['center'] && document.getElementById('gv_crosshair')) ? "document.getElementById('gv_crosshair').style.display = 'none'; gv_crosshair_temporarily_hidden = true;" : '';
	var open_info_window = (gv_marker_list_options['info_window']) ? marker_name+'.openInfoWindowHtml('+marker_name+'.html,{maxWidth:'+marker_name+'.max_width}); ' : '';
	var toggle = (gv_marker_list_options['toggle']) ? 'GV_Toggle_Marker('+map_name+','+marker_name+',this,\''+color+'\');' : '';
	
	var mouseover = (m.tooltip) ? 'onMouseOver="GV_Create_Marker_Tooltip('+map_name+','+marker_name+');" ' : '';
	var mouseout = (m.tooltip) ? 'onMouseOut="tooltip.style.visibility = \'hidden\';" ' : '';
	
	var text_click = unhide+toggle+zoom_in+center+hide_crosshair+open_info_window;
	var icon_click = unhide+zoom_in+center+hide_crosshair+open_info_window;
	
	var wrap_style; var nobr_open; var nobr_close;
	if (gv_marker_list_options['wrap_names']) { wrap_style = ''; nobr_open = ''; nobr_close = ''; } else { wrap_style = 'white-space:nowrap; '; nobr_open ='<nobr>'; nobr_close = '</nobr>'; }
	var open_wrap 
	var icon_scaling = 'width:'+m['width']+'px; height:'+m['height']+'px';
	var icon = (gv_marker_list_options['icons']) ? '<img align="top" '+mouseover+mouseout+'onClick="'+icon_click+'" style="cursor:crosshair; '+icon_scaling+'" src="'+m['image']+'">&nbsp;' : '';
	var name = '<wbr/><span '+mouseover+mouseout+'onClick="'+text_click+'" class="name" style="'+wrap_style+'cursor:crosshair; '+color_style+';">'+m['name'] +'<'+'/span>';
	name = (gv_marker_list_options['url_links'] && m['url']) ? '<a target="'+gv_marker_link_target+'" href="'+m['url']+'">'+name+'</a>' : name;
	var d = (m['shortdesc']) ? m['shortdesc'] : m['desc'];
	var desc = (gv_marker_list_options['desc'] && d) ? '<br><span class="desc" style="'+color_style+'">'+d+'<'+'/span>' : '';
	var first = (gv_marker_count == 1) ? ' gv_marker_list_first_item' : '';
	return ('<div id="gv_list:'+marker_name+'" class="gv_marker_list_item'+first+'">' + nobr_open + icon + name + nobr_close + desc + '</div>'+"\n");
}

function GV_Toggle_Marker(map,marker,link,link_color,dimmed_color) {
	if (marker.gv_hidden) {
		map.addOverlay(marker);
		marker.gv_hidden = false;
	} else {
		map.removeOverlay(marker);
		marker.gv_hidden = true;
	}
	if (link_color && link.style.color) {
		link_color = Color_Hex2CSS(link_color);
		dimmed_color = (dimmed_color) ? Color_Hex2CSS(dimmed_color) : Color_Hex2CSS('#999999');
		if (marker.gv_hidden) { link.style.color = dimmed_color; }
		else { link.style.color = link_color; }
	}
}

function GV_Toggle_Track_And_Label(map,id,color) {
	if (!color) { // older versions of this function only had two parameters
		color = id; id = map; map = gmap;
	} 
	GV_Toggle_Opacity(map,eval(id)); // this one ("trkX") is stored in a variable
	GV_Toggle_Label_Opacity(document.getElementById(id+'_label'),color); // this one ("trkX_label") is a page element
}

function GV_Toggle_Opacity(map,overlay_array) {
	if (gv_api_version >= 2) {
		if (overlay_array.gv_hidden) {
			if (!overlay_array.gv_oor) { // don't turn it on if it's "out of range"
				for (j=0; j<overlay_array.length; j++) { map.addOverlay(overlay_array[j]); }
			}
			overlay_array.gv_hidden = false;
		} else {
			for (j=0; j<overlay_array.length; j++) { map.removeOverlay(overlay_array[j]); }
			overlay_array.gv_hidden = true;
		}
	} else {
		for (j=0; j<overlay_array.length; j++) {
			var item = overlay_array[j];
			if (eval(item.drawElement)) {
				if (item.drawElement.style.display == 'none') { item.drawElement.style.display = ''; }
				else { item.drawElement.style.display = 'none'; }
			} else if (eval(item.images)) {
				for (var i=0; i < item.images.length; i++) {
					if (item.images[i].style.display == 'none') { item.images[i].style.display = ''; }
					else { item.images[i].style.display = 'none'; }
				}
			}
		}
	}
}

function GV_Toggle_Label_Opacity(label,original_color) {
	original_color = Color_Hex2CSS(original_color);
	current_color = Color_Hex2CSS(label.style.color);
	dimmed_color = Color_Hex2CSS('#AAAAAA');
//	if (current_color == dimmed_color) { label.style.color = original_color; }
//	else { label.style.color = dimmed_color; }
	if (label.gv_hidden) { label.gv_hidden = false; label.style.color = original_color; }
	else { label.gv_hidden = true; label.style.color = dimmed_color; }
}

function GV_Toggle(id) {
	if (document.getElementById(id).style.display == 'none') {
		document.getElementById(id).style.display = '';
	} else {
		document.getElementById(id).style.display = 'none';
	}
}

function GV_Filter_Tracks (map,info) {
	if (info == null || info == undefined || !info.length) { return false; }
	var min_lat = map.getBounds().getSouthWest().lat();
	var min_lon = map.getBounds().getSouthWest().lng();
	var max_lat = map.getBounds().getNorthEast().lat();
	var max_lon = map.getBounds().getNorthEast().lng();
	if (max_lon < min_lon) { min_lon = -180; max_lon = 180; } // Date Line weirdness
	for (var t in info) {
		if (info[t]['e'] < min_lon || info[t]['w'] > max_lon || info[t]['n'] < min_lat || info[t]['s'] > max_lat) {
			GV_Track_OutOfRange(map,eval(t),true);
		} else {
			GV_Track_OutOfRange(map,eval(t),false);
		}
	}
}
function GV_Track_OutOfRange (map,trk_array,is_oor) {
	if (is_oor) {
		if (!trk_array.gv_hidden) { // if it's already hidden, there's nothing to do
			for (j=0; j<trk_array.length; j++) { map.removeOverlay(trk_array[j]); }
		}
		trk_array.gv_oor = true;
	} else {
		if (trk_array.gv_oor) { // only add it if it was previously out of range
			if (!trk_array.gv_hidden) { // if it's supposed to be hidden, don't show it
				for (j=0; j<trk_array.length; j++) { map.addOverlay(trk_array[j]); }
			}
		}
		trk_array.gv_oor = false;
	}
}

function GV_Process_Waypoints (map,wpt_array) {
	if (gv_filter_waypoints) {
		GV_Filter_Waypoints_In_View(map,wpt_array);
	}
	if (gv_marker_list) {
		GV_Marker_List();
	}
}

function GV_Filter_Waypoints_In_View (map,wpt_array) {
	var limit = (gv_marker_filter_options['limit'] > 0) ? gv_marker_filter_options['limit'] : 0;
	var update_list = (gv_marker_filter_options['update_list']) ? true : false;
	var sort_list_by_distance = (gv_marker_filter_options['sort_list_by_distance']) ? true : false;
	var min_lat = map.getBounds().getSouthWest().lat();
	var min_lon = map.getBounds().getSouthWest().lng();
	var max_lat = map.getBounds().getNorthEast().lat();
	var max_lon = map.getBounds().getNorthEast().lng();
	if (max_lon < min_lon) { min_lon = -180; max_lon = 180; } // Date Line weirdness
	if (gv_marker_list && update_list) {
		gv_marker_list_html = '';
	}
	var to_be_added = new Array();
	for (j=0; j<wpt_array.length; j++) {
		var w = wpt_array[j];
		map.removeOverlay(w);
		if (w.coords.lng() < min_lon || w.coords.lng() > max_lon || w.coords.lat() < min_lat || w.coords.lat() > max_lat) {
			// do nothing; it's out of range
		} else {
			if (!limit && !update_list) { // add everything that's in the viewport
				to_be_added.push(j);
			} else {
				if (limit > 0 || sort_list_by_distance) {
					w.dist_from_center = map.getCenter().distanceFrom(w.coords);
					var key = (w.dist_from_center/10000000).toFixed(8);
					to_be_added.push(key+' '+j);
				} else {
					to_be_added.push(j);
				}
			}
		}
	}
	if (limit > 0 || (sort_list_by_distance && update_list)) {
		to_be_added = to_be_added.sort();
		if (limit > 0 && limit < to_be_added.length) { to_be_added.length = limit; }
		for (j=0; j<to_be_added.length; j++) {
			var parts = to_be_added[j].split(' ');
			to_be_added[j] = parseInt(parts[1]);
		}
		if (!sort_list_by_distance) { // back to the original order
			to_be_added = to_be_added.sort(function(a,b){ return(a-b) });
		}
	}
	for (j=0; j<to_be_added.length; j++) {
		var w = wpt_array[to_be_added[j]];
		if (!w.gv_hidden) { // if it's supposed to be hidden, don't show it
			map.addOverlay(w);
		}
		if (gv_marker_list && update_list) {
			gv_marker_list_html += w.list_html;
		}
	}
}

function GV_Filter_Waypoints (map,wpt_array) { // For backwards compatibility
	GV_Process_Waypoints (map,wpt_array);
}


function GV_Setup_Crosshair(map,opts) {
	if (!opts['crosshair_container_id']) { opts['crosshair_container_id'] = 'gv_crosshair_container'; }
	if (!opts['crosshair_graphic_id']) { opts['crosshair_graphic_id'] = 'gv_crosshair'; }
	if (!opts['crosshair_width']) { opts['crosshair_width'] = 15; }
	if (!opts['center_coordinates_id']) { opts['center_coordinates_id'] = 'gv_center_coordinates'; }
	
	GV_Recenter_Crosshair(map,opts['crosshair_container_id'],opts['crosshair_width']);
	GV_Show_Center_Coordinates(gmap,opts['center_coordinates_id']);
	GEvent.addListener(map, "moveend", function() {
		GV_Show_Hidden_Crosshair(map,opts['crosshair_graphic_id']);
		GV_Show_Center_Coordinates(map,opts['center_coordinates_id']);
	});
	if (opts['fullscreen'] || opts['full_screen']) {
		GEvent.addListener(map, "resize", function() {
			GV_Recenter_Crosshair(map,opts['crosshair_container_id'],opts['crosshair_width']);
			GV_Show_Hidden_Crosshair(map,opts['crosshair_graphic_id']);
			GV_Show_Center_Coordinates(map,opts['center_coordinates_id']);
		});
	}
	
	if (document.getElementById('gv_credit_container') && !document.getElementById('gv_credit')) {
		document.getElementById('gv_credit_container').innerHTML = '<table style="filter:alpha(opacity=80); -moz-opacity:0.8;" cellspacing="0" cellpadding="0" border="0"><tr><td><div id="gv_credit" style="background-color:#FFFFFF; border:none; padding:1px; font:10px Verdana,sans-serif;"><b>Map created by <a target="_top" href="http://www.gpsvisualizer.com/">GPSVisualizer.com</a></b></div></td></tr></table>';
		GV_Place_Control(map,'gv_credit_container',G_ANCHOR_BOTTOM_RIGHT,6,40); // moved up a bit in case of shorter DIVs
	}
}

function GV_Show_Center_Coordinates(map,id) {
	if (document.getElementById(id)) {
		var lat = map.getCenter().lat().toFixed(5);
		var lng = map.getCenter().lng().toFixed(5);
		document.getElementById(id).innerHTML = "Center: "+lat+","+lng;
	}
	gv_last_center = map.getCenter(); // this will come in handy; make sure it happens AFTER the crosshair is potentially unhidden
}

var gv_crosshair_temporarily_hidden = true;
function GV_Show_Hidden_Crosshair(map,id) {
	// only do something upon the FIRST movement of the map, or when it's been hidden, e.g. because of a centering action
	if (self.gv_crosshair_temporarily_hidden && (!self.gv_last_center || gv_last_center != map.getCenter())) {
		document.getElementById(id).style.display = 'block';
		gv_crosshair_temporarily_hidden = false;
	}
}

function GV_Recenter_Crosshair(map,container_id,crosshair_size) {
	if (document.getElementById(container_id)) {
		if (document.getElementById(container_id).align) { // in the older version, we always used align="left" in the DIV
			document.getElementById(container_id).style.position = 'absolute';
			document.getElementById(container_id).style.top = Math.round(map.getContainer().clientHeight/2-(crosshair_size/2))+'px';
			document.getElementById(container_id).style.left = Math.round(map.getContainer().clientWidth/2-(crosshair_size/2))+'px';
		} else {
			var x = Math.round(map.getContainer().clientWidth/2-(crosshair_size/2));
			var y = Math.round(map.getContainer().clientHeight/2-(crosshair_size/2));
			GV_Place_Control(map,container_id,G_ANCHOR_TOP_LEFT,x,y);
		}
	}
}

function GV_Place_Control(map,control_id,anchor,x,y) {
	if (document.getElementById(control_id)) {
		document.getElementById(control_id).style.display = 'block';
		var gv_position = new GControlPosition(anchor, new GSize(x,y));
		gv_position.apply(document.getElementById(control_id));
		map.getContainer().appendChild(document.getElementById(control_id));
	}
}

function GV_MouseWheel(e) {
	if (e.detail) { // Firefox
		if (e.detail < 0) { gmap.zoomIn(); }
		else if (e.detail > 0) { gmap.zoomOut(); }
	} else if (e.wheelDelta) { // IE
		if (e.wheelDelta > 0) { gmap.zoomIn(); }
		else if (e.wheelDelta < 0) { gmap.zoomOut(); }
	}
}

function Color_Hex2CSS(c) {
	if (c == null) { return null; }
	var rgb = new Array(); rgb = c.match(/([A-F0-9]{2})([A-F0-9]{2})([A-F0-9]{2})/i);
	if (rgb) {
		return ('rgb('+parseInt(rgb[1],16)+','+parseInt(rgb[2],16)+','+parseInt(rgb[3],16)+')');
	} else {
		return (c.replace(/ +/g,''));
	}
}
function Color_Name2Hex(color_name) {
	var c = new Array();
	c['aqua'] = '#00FFFF'; c['black'] = '#000000'; c['blue'] = '#0000FF'; c['brown'] = '#7A4328';
	c['cyan'] = '#00FFFF'; c['default'] = '#FF776B'; c['fuchsia'] = '#FF00FF'; c['gray'] = '#AAAAAA';
	c['green'] = '#009900'; c['grey'] = '#AAAAAA'; c['lime'] = '#00FF00'; c['magenta'] = '#FF00FF';
	c['maroon'] = '#800000'; c['navy'] = '#000080'; c['olive'] = '#808000'; c['orange'] = '#FF6600';
	c['pink'] = '#FF99CC'; c['purple'] = '#990099'; c['red'] = '#FF0000'; c['silver'] = '#808080';
	c['tan'] = '#C1945F'; c['teal'] = '#008080'; c['violet'] = '#6600FF'; c['white'] = '#FFFFFF';
	c['yellow'] = '#FFFF00';
	if (c[color_name]) { return c[color_name]; } else { return color_name; }
}



/**************************************************
 * Custom map layers:
 * Adapted from Jef Poskanzer's Acme Mapper
 * (http://mapper.acme.com/)
 **************************************************/
if (gv_api_version >= 2) {
	var USGS_TOPO_TILES = WMSCreateMap('Topo','Topo maps by USGS via terraserver-usa.com','Topo maps unavailable',5,17,400,'http://terraservice.net/ogcmap6.ashx?version=1.1.1&request=GetMap&styles=&srs=EPSG:4326&format=image/jpeg&bgcolor=0xCCCCCC&exceptions=INIMAGE&layers=DRG');
	var USGS_AERIAL_TILES = WMSCreateMap('Aerial','Imagery by USGS via terraserver-usa.com','USGS aerial imagery unavailable',7,18,400,'http://terraservice.net/ogcmap6.ashx?version=1.1.1&request=GetMap&styles=&srs=EPSG:4326&format=image/jpeg&bgcolor=0xCCCCCC&exceptions=INIMAGE&layers=DOQ');
	var NRCAN_TOPO_TILES = WMSCreateMap('NRCan','Maps by NRCan.gc.ca','NRCan maps unavailable',6,18,600,'http://wms.cits.rncan.gc.ca/cgi-bin/cubeserv.cgi?version=1.1.3&request=GetMap&format=image/png&bgcolor=0xFFFFFF&exceptions=application/vnd.ogc.se_inimage&srs=EPSG:4326&layers=PUB_50K:CARTES_MATRICIELLES/RASTER_MAPS');
	var NRCAN_TOPO_NAMES_TILES = WMSCreateMap('NRCan+','Maps by NRCan.gc.ca','NRCan maps unavailable',11,18,600,'http://wms.cits.rncan.gc.ca/cgi-bin/cubeserv.cgi?version=1.1.3&request=GetMap&format=image/png&bgcolor=0xFFFFFF&exceptions=application/vnd.ogc.se_inimage&srs=EPSG:4326&layers=PUB_50K:CARTES_MATRICIELLES/RASTER_MAPS,TOPONYME_0:BNDT_50K/NTDB_50K');
	var LANDSAT_TILES = WMSCreateMap('Landsat','Map by NASA','OnEarth server unavailable',3,15,256,'http://onearth.jpl.nasa.gov/wms.cgi?request=GetMap&styles=&srs=EPSG:4326&format=image/jpeg&layers=global_mosaic');
	var BLUEMARBLE_TILES = WMSCreateMap('BlueMarble','Map by NASA','OnEarth server unavailable',3,8,128,'http://onearth.jpl.nasa.gov/wms.cgi?request=GetMap&styles=&srs=EPSG:4326&format=image/jpeg&layers=modis');
	var DAILY_TERRA_TILES = WMSCreateMap('"Terra"','Map by NASA','OnEarth server unavailable',3,10,256,'http://onearth.jpl.nasa.gov/wms.cgi?request=GetMap&styles=&srs=EPSG:4326&format=image/jpeg&layers=daily_terra');
	var DAILY_AQUA_TILES = WMSCreateMap('"Aqua"','Map by NASA','OnEarth server unavailable',3,10,256,'http://onearth.jpl.nasa.gov/wms.cgi?request=GetMap&styles=&srs=EPSG:4326&format=image/jpeg&layers=daily_aqua');
}

function GV_Add_Custom_Layers(map) {
	map.addMapType(USGS_TOPO_TILES);
	map.addMapType(USGS_AERIAL_TILES);
	map.addMapType(NRCAN_TOPO_TILES);
	map.addMapType(NRCAN_TOPO_NAMES_TILES);
	map.addMapType(LANDSAT_TILES);
	map.addMapType(BLUEMARBLE_TILES);
	map.addMapType(DAILY_TERRA_TILES);
	map.addMapType(DAILY_AQUA_TILES);
}

function WMSCreateMap(name,copyright,errorMessage,minResolution,maxResolution,tileSize,baseUrl) {
	var tileLayer = new GTileLayer(new GCopyrightCollection(copyright),minResolution,maxResolution);
	tileLayer.baseUrl = baseUrl;
	tileLayer.tileSize = tileSize;
	tileLayer.getTileUrl = WMSGetTileUrl;
	tileLayer.getCopyright = function() { return { prefix:'',copyrightTexts:[copyright]}; };
	var tileLayers = [tileLayer];
	return new GMapType(tileLayers,G_SATELLITE_MAP.getProjection(),name,{errorMessage:errorMessage,tileSize:tileSize});
}
function WMSGetTileUrl(tile,zoom) {
	var southWestPixel = new GPoint(tile.x*this.tileSize,(tile.y+1)*this.tileSize);
	var northEastPixel = new GPoint((tile.x+1)*this.tileSize,tile.y*this.tileSize);
	var southWestCoords = G_SATELLITE_MAP.getProjection().fromPixelToLatLng(southWestPixel,zoom);
	var northEastCoords = G_SATELLITE_MAP.getProjection().fromPixelToLatLng(northEastPixel,zoom);
	var bbox = southWestCoords.lng()+','+southWestCoords.lat()+','+northEastCoords.lng()+','+northEastCoords.lat();
	return this.baseUrl+'&bbox='+bbox+'&width='+this.tileSize+'&height='+this.tileSize;
}


/**************************************************
 * Custom map-type control:
 * more or less from Google's own documentation
 **************************************************/
function GV_MapTypeControl() {}
if (gv_api_version >= 2) {
	GV_MapTypeControl.prototype = new GControl();
	GV_MapTypeControl.prototype.getDefaultPosition = function() {
		return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(7,7));
	}
	GV_MapTypeControl.prototype.initialize = function(map) {
		GV_Add_Custom_Layers(map);
		var map_types = [
			{ label:'G. map',type:'G_NORMAL_MAP',title:'Google street map',bounds:[-180,-90,180,90],excluded:[] }
			,{ label:'G. satellite',type:'G_SATELLITE_MAP',title:'Google satellite map',bounds:[-180,-90,180,90],excluded:[] }
			,{ label:'G. hybrid',type:'G_HYBRID_MAP',title:'Google "hybrid" map',bounds:[-180,-90,180,90],excluded:[] }
			,{ label:'USGS topo',type:'USGS_TOPO_TILES',title:'USGS topographic map',bounds:[-169,18,-66,72],excluded:[],country:'us' }
			,{ label:'USGS aerial',type:'USGS_AERIAL_TILES',title:'USGS aerial photos (black/white)',bounds:[-152,17,-65,65],excluded:[],country:'us' }
			,{ label:'Canada topo',type:'NRCAN_TOPO_TILES',title:'NRCan/Toporama maps with contour lines',bounds:[-141,41.7,-52,85],excluded:[-141,41.7,-86,48],country:'ca' }
			,{ label:'Can. topo+names',type:'NRCAN_TOPO_NAMES_TILES',title:'NRCan/Toporama topo maps with feature names',bounds:[-141,41.7,-52,85],excluded:[-141,41.7,-86,48],country:'ca' }
			,{ label:'Landsat 30m',type:'LANDSAT_TILES',title:'NASA Landsat 30-meter imagery',bounds:[-180,-90,180,90],excluded:[] }
			,{ label:'Blue Marble',type:'BLUEMARBLE_TILES',title:'NASA "Visible Earth" image',bounds:[-180,-90,180,90],excluded:[] }
			,{ label:'Daily "Terra"',type:'DAILY_TERRA_TILES',title:'Daily imagery from "Terra" satellite',bounds:[-180,-90,180,90],excluded:[] }
			,{ label:'Daily "Aqua"',type:'DAILY_AQUA_TILES',title:'Daily imagery from "Aqua" satellite',bounds:[-180,-90,180,90],excluded:[] }
		];
		if (self.gv_custom_map_types && gv_custom_map_types.length > 0) {
			for (j=0; j<gv_custom_map_types.length; j++) { map_types.push(gv_custom_map_types[j]); }
		}
		var center_lat = map.getCenter().lat();
		var center_lng = map.getCenter().lng();
		
		var excluded_maps = new Array;
		if (self.gv_filter_map_types && gv_filter_map_types && self.gv_excluded_map_types && gv_excluded_map_types) {
			for (j=0; j<gv_excluded_map_types.length; j++) {
				excluded_maps[gv_excluded_map_types[j]] = true;
			}
		}
		for (j=0; j<map_types.length; j++) {
			if (self.gv_country && gv_country) {
				if (map_types[j]['country'] && map_types[j]['country'].indexOf(gv_country) < 0) {
					excluded_maps[map_types[j]['type']] = true;
				}
			} else {
				if (!(center_lng >= map_types[j]['bounds'][0] && center_lat >= map_types[j]['bounds'][1] && center_lng <= map_types[j]['bounds'][2] && center_lat <= map_types[j]['bounds'][3]) || (center_lng >= map_types[j]['excluded'][0] && center_lat >= map_types[j]['excluded'][1] && center_lng <= map_types[j]['excluded'][2] && center_lat <= map_types[j]['excluded'][3]) ) {
					excluded_maps[map_types[j]['type']] = true;
				}
			}
		}
		if (gv_maptypecontrol_style == 'menu') {
			var map_selector = document.createElement("select");
			map_selector.id = 'map_selector';
			map_selector.style.font = '10px Verdana';
			map_selector.style.backgroundColor = '#FFFFFF';
			for (j=0; j<map_types.length; j++) {
				if (!gv_filter_map_types || !excluded_maps[map_types[j]['type']]) {
					var opt = document.createElement("option");
					opt.value = map_types[j]['type'];
					opt.appendChild(document.createTextNode(map_types[j]['label']));
					map_selector.appendChild(opt);
					if (map.getCurrentMapType() == eval(opt.value)) { map_selector.selectedIndex = map_selector.length - 1; }
				}
			}
			GEvent.addDomListener(map_selector, "change", function(){
				map.setMapType(eval(this.value));
				// if (self.gv_maptypecontrol) {
				// 	map.removeControl(gv_maptypecontrol);
				// 	map.addControl(gv_maptypecontrol);
				// }
			} );
			map.getContainer().appendChild(map_selector);
			return map_selector;
		} else { // 'list'
			var map_type_container = document.createElement("div");
			for (j=0; j<map_types.length; j++) {
				var map_ok = true;
				if (gv_filter_map_types && !(center_lng >= map_types[j]['bounds'][0] && center_lat >= map_types[j]['bounds'][1] && center_lng <= map_types[j]['bounds'][2] && center_lat <= map_types[j]['bounds'][3]) || (center_lng >= map_types[j]['excluded'][0] && center_lat >= map_types[j]['excluded'][1] && center_lng <= map_types[j]['excluded'][2] && center_lat <= map_types[j]['excluded'][3]) ) { map_ok = false; }
				if (self.gv_country && gv_country && map_types[j]['country'] && map_types[j]['country'].indexOf(gv_country) < 0) { map_ok = false; }
				if (excluded_maps[map_types[j]['type']]) { map_ok = false; }
				if (map_ok) {
					var maplink = document.createElement("div");
					maplink.className = 'gv_maptypelink';
					if (self.gv_maptypecontrol && map.getCurrentMapType() == eval(map_types[j]['type'])) {
						maplink.className = 'gv_maptypelink gv_maptypelink_selected';
					}
					maplink.title = map_types[j]['title'];
					maplink.type = map_types[j]['type'];
					map_type_container.appendChild(maplink);
					maplink.appendChild(document.createTextNode(map_types[j]['label']));
					GEvent.addDomListener(maplink, "click", function(){
						map.setMapType(eval(this.type));
						if (self.gv_maptypecontrol) {
							map.removeControl(gv_maptypecontrol);
							map.addControl(gv_maptypecontrol);
						}
					} );
				}
			}
			map.getContainer().appendChild(map_type_container);
			return map_type_container;
		}
	}
}

// These are here only for backwards compatibilty:
function GPSV_Waypoint(lon,lat,name,desc,url,color,style,width,label_id) { GV_Marker(gmap,lat,lon,name,desc,url,color,style,width,label_id); }
function GPSV_Toggle_Track_And_Label(id,color) { GV_Toggle_Track_And_Label(id,color); } // for backwards compatibility
function GPSV_Toggle_Opacity(overlay_array) { GV_Toggle_Opacity(overlay_array); } // for backwards compatibility
function GPSV_Toggle_Label_Opacity(label,original_color) { GV_Toggle_Label_Opacity(label,original_color); } // for backwards compatibility
function GPSV_MapTypeControl() {}
if (gv_api_version >= 2) { GPSV_MapTypeControl.prototype = GV_MapTypeControl.prototype; }



function GV_Load_Markers_From_XML(opts) {
	var map_name = opts['map'] || 'gmap'; var map = eval(map_name);
	var array_name = opts['array'] || 'wpts'; var marker_array = eval(array_name);
	var filename = opts['xml'] || 'markers.xml';
	var filter = (opts['filter'] === false || opts['filter'] === 0) ? false : true;
	GDownloadUrl(filename, function(data, responseCode) {
		var xml = GXml.parse(data);
		var markers = xml.documentElement.getElementsByTagName(opts['tag']||'marker');
		for (var i = 0; i < markers.length; i++) {
			var m = new Array;
			m['lat'] = m['lon'] = null;
			if (markers[i].getAttribute('latitude')) { m['lat'] = parseFloat(markers[i].getAttribute('latitude')); }
			else if (markers[i].getAttribute('lat')) { m['lat'] = parseFloat(markers[i].getAttribute('lat')); }
			var lon = null;
			if (markers[i].getAttribute('longitude')) { m['lon'] = parseFloat(markers[i].getAttribute('longitude')); }
			else if (markers[i].getAttribute('lon')) { m['lon'] = parseFloat(markers[i].getAttribute('lon')); }
			else if (markers[i].getAttribute('lng')) { m['lon'] = parseFloat(markers[i].getAttribute('lng')); }
			else if (markers[i].getAttribute('long')) { m['lon'] = parseFloat(markers[i].getAttribute('long')); }
			if (m['lat'] && m['lon']) {
				m['name'] = m['desc'] = m['color'] = m['icon'] = '';
				if (markers[i].getAttribute('name'))  { m['name']  = markers[i].getAttribute('name'); }
				if (markers[i].getAttribute('desc'))  { m['desc']  = markers[i].getAttribute('desc'); }
				if (markers[i].getAttribute('color')) { m['color'] = markers[i].getAttribute('color'); }
				if (markers[i].getAttribute('icon'))  { m['icon']  = markers[i].getAttribute('icon'); }
				else if (markers[i].getAttribute('sym'))  { m['icon']  = markers[i].getAttribute('sym'); }
				else if (markers[i].getAttribute('symbol'))  { m['icon']  = markers[i].getAttribute('symbol'); }
				if (markers[i].getAttribute('scale'))  { m['scale']  = markers[i].getAttribute('scale'); }
				marker_array.push( GV_Marker(map,{lat:m['lat'],lon:m['lon'],name:m['name'],desc:m['desc'],color:m['color'],icon:m['icon'],scale:m['scale']}) );
			}
		}
		if (filter) {
			window.setTimeout('GV_Filter_Waypoints('+map_name+','+array_name+')',100); // the delay lets IE6 realize the markers are in the cache
		}
	});
}

function GV_Get_Cached_Addresses(map,opts) {
	var SW = map.getBounds().getSouthWest(); var NE = map.getBounds().getNorthEast();
	var lat_center = map.getCenter().lat().toFixed(7);
	var lon_center = map.getCenter().lng().toFixed(7);
	
	var moved_enough = true;
	if (self.gv_center_when_reloaded && self.gv_last_radius) {
		if (map.getCenter().distanceFrom(gv_center_when_reloaded) < gv_last_radius*0.4) {
			moved_enough = false;
		}
	}
	if (moved_enough) {
		for (var i = 0; i < gv_dynamic_markers.length; i++) { map.removeOverlay(gv_dynamic_markers[i]); }
		gv_marker_count = 0;
		gv_dynamic_markers.length = 0; // this is important!
		if (gv_marker_list) {
			document.getElementById(gv_marker_list_div_name).innerHTML = 'Loading markers...';
			gv_marker_list_html = '';
		}
		var url = '/google_maps/cached_addresses.cgi?lat_center='+lat_center+'&lon_center='+lon_center+'&lat_min='+SW.lat().toFixed(7)+'&lat_max='+NE.lat().toFixed(7)+'&lon_min='+SW.lng().toFixed(7)+'&lon_max='+NE.lng().toFixed(7)+'&quota='+gv_dynamic_markers_quota;
		GDownloadUrl(url, function(data, responseCode) {
			var xml = GXml.parse(data);
			var marker_tags = xml.documentElement.getElementsByTagName("marker");
			for (var i = 0; i < marker_tags.length; i++) {
				var this_color = (marker_tags[i].getAttribute("color")) ? marker_tags[i].getAttribute("color") : '';
				var this_label = (opts['labels']) ? marker_tags[i].getAttribute("name") : '';
				var m = GV_Marker(map,{
					lat:marker_tags[i].getAttribute("lat"),
					lon:marker_tags[i].getAttribute("lon"),
					name:marker_tags[i].getAttribute("name"),
					desc:marker_tags[i].getAttribute("desc"),
					color:this_color,
					label:this_label
				});
				gv_dynamic_markers.push(m);
			}
			gv_last_radius = 0.7 * map.getCenter().distanceFrom(map.getBounds().getSouthWest()); // in case the XML doesn't have a radius
			if (opts['circle']) {
				var trackpoints = xml.documentElement.getElementsByTagName("trkpt");
				if (trackpoints.length) {
					var tracks = xml.documentElement.getElementsByTagName("trk"); gv_last_radius = tracks[0].getAttribute("radius");
					var pts = new Array();
					for (var i = 0; i < trackpoints.length; i++) {
						pts.push( new GLatLng(trackpoints[i].getAttribute("lat"),trackpoints[i].getAttribute("lon")) );
					}
					var circle_color = (gv_marker_color) ? gv_marker_color : 'white';
					gv_dynamic_markers.push (new GPolyline(pts,Color_Name2Hex(circle_color),2,0.2));
					map.addOverlay(gv_dynamic_markers[gv_dynamic_markers.length-1]);
				}
			}
			if (gv_marker_list) {
				GV_Marker_List();
			}
		});
		gv_center_when_reloaded = map.getCenter();
	}
}


function GV_Get_Dynamic_Markers(map,opts) {
	if (!self.gv_dynamic_markers || !opts['db']) { return; }
	var program_on_server = '/google_maps/dynamic_markers.cgi';
	
	var SW = map.getBounds().getSouthWest(); var NE = map.getBounds().getNorthEast();
	var lat_center = map.getCenter().lat().toFixed(7);
	var lon_center = map.getCenter().lng().toFixed(7);
	
	var moved_enough = true;
	if (self.gv_zoom_when_reloaded && (map.getZoom() < gv_zoom_when_reloaded)) {
		moved_enough = true; // regardless of how far they moved, reload if they zoomed out
	} else if (self.gv_center_when_reloaded && self.gv_last_radius) {
		if (map.getCenter().distanceFrom(gv_center_when_reloaded) < gv_last_radius*0.4) {
			moved_enough = false; // they moved, but not very far, so don't reload
		}
	}
	if (moved_enough) {
		for (var i = 0; i < gv_dynamic_markers.length; i++) { map.removeOverlay(gv_dynamic_markers[i]); }
		gv_marker_count = 0;
		gv_dynamic_markers.length = 0; // this is important!
		if (gv_marker_list) {
			document.getElementById(gv_marker_list_div_name).innerHTML = 'Loading markers...';
			gv_marker_list_html = '';
		}
		var fields = (opts['fields']) ? opts['fields'] : 'name,description,latitude,longitude';
		var sort = (opts['sort']) ? opts['sort'] : '';
		var url = program_on_server+'?db='+opts['db']+'&fields='+escape(fields)+'&lat_center='+lat_center+'&lon_center='+lon_center+'&lat_min='+SW.lat().toFixed(7)+'&lat_max='+NE.lat().toFixed(7)+'&lon_min='+SW.lng().toFixed(7)+'&lon_max='+NE.lng().toFixed(7)+'&quota='+gv_dynamic_markers_quota+'&sort='+sort;
		GDownloadUrl(url, function(data, responseCode) {
			var xml = GXml.parse(data);
			var marker_tags = xml.documentElement.getElementsByTagName("marker");
			for (var i = 0; i < marker_tags.length; i++) {
				var this_color = (marker_tags[i].getAttribute("color")) ? marker_tags[i].getAttribute("color") : '';
				var this_icon = (marker_tags[i].getAttribute("icon")) ? marker_tags[i].getAttribute("icon") : '';
				var this_label = (marker_tags[i].getAttribute("label")) ? marker_tags[i].getAttribute("label") : marker_tags[i].getAttribute("name");
				var this_shortdesc = (marker_tags[i].getAttribute("shortdesc")) ? marker_tags[i].getAttribute("shortdesc") : '';
				this_label = (opts['labels']) ? this_label : '';
				var m = GV_Marker(map,{
					lat:marker_tags[i].getAttribute("lat"),
					lon:marker_tags[i].getAttribute("lon"),
					name:marker_tags[i].getAttribute("name"),
					desc:marker_tags[i].getAttribute("desc"),
					shortdesc:this_shortdesc,
					color:this_color,
					icon:this_icon,
					label:this_label
				});
				gv_dynamic_markers.push(m);
			}
			gv_last_radius = 0.7 * map.getCenter().distanceFrom(map.getBounds().getSouthWest()); // in case the XML doesn't have a radius
			if (opts['circle']) {
				var trackpoints = xml.documentElement.getElementsByTagName("trkpt");
				if (trackpoints.length) {
					var tracks = xml.documentElement.getElementsByTagName("trk"); gv_last_radius = tracks[0].getAttribute("radius");
					var pts = new Array();
					for (var i = 0; i < trackpoints.length; i++) {
						pts.push( new GLatLng(trackpoints[i].getAttribute("lat"),trackpoints[i].getAttribute("lon")) );
					}
					var circle_color = (gv_marker_color) ? gv_marker_color : 'white';
					gv_dynamic_markers.push (new GPolyline(pts,Color_Name2Hex(circle_color),2,0.2));
					map.addOverlay(gv_dynamic_markers[gv_dynamic_markers.length-1]);
				}
			}
			if (gv_marker_list) {
				document.getElementById(gv_marker_list_div_name).innerHTML = '';
				GV_Marker_List();
			}
		});
		gv_center_when_reloaded = map.getCenter();
		gv_zoom_when_reloaded = map.getZoom();
	}
}



function FindGoogleAPIVersion() {
	var v = 2;
	var scripts = document.getElementsByTagName("script")
	for (var i=0; i<scripts.length; i++) {
		var pattern = /\/maps([0-9])?(\.?[0-9]+)(\.api)?\.js/;
		var m = pattern.exec(scripts[i].src);
		if (m != null) {
			if (m[1] == null) { v = parseFloat('1'+m[2]); }
			else { v = parseFloat(m[1]+m[2]); }
			break;
		}
	}
	return v;
}




/**************************************************
elabel.js
(adapted from http://www.econym.demon.co.uk/googlemaps/elabel.htm)
(My modification: adding the "label_id" parameter)
**************************************************/

function ELabel(point, html, classname, pixelOffset, percentOpacity, overlap, label_id) {
	// Mandatory parameters
	this.point = point;
	this.html = html;
	
	// Optional parameters
	this.classname = classname || "";
	this.pixelOffset = pixelOffset || new GSize(0,0);
	if (percentOpacity) {
		if (percentOpacity < 0) { percentOpacity = 0; }
		if (percentOpacity > 100) { percentOpacity = 100; }
	}
	this.percentOpacity = percentOpacity;
	this.overlap = overlap || false;
	this.label_id = label_id;
}

if (gv_api_version >= 2) {
	ELabel.prototype = new GOverlay();
	
	ELabel.prototype.initialize = function (map) {
		var div = document.createElement("div");
		div.style.position = "absolute";
		div.innerHTML = '<div id = "' + this.label_id + '" class="' + this.classname + '">' + this.html + '</div>' ;
		map.getPane(G_MAP_FLOAT_SHADOW_PANE).appendChild(div);
		this.map_ = map;
		this.div_ = div;
		if (this.percentOpacity) {
			if (typeof(div.style.filter) == 'string') { div.style.filter='alpha(opacity:'+this.percentOpacity+')'; }
			if (typeof(div.style.KHTMLOpacity) == 'string') { div.style.KHTMLOpacity=this.percentOpacity/100; }
			if (typeof(div.style.MozOpacity) == 'string') { div.style.MozOpacity=this.percentOpacity/100; }
			if (typeof(div.style.opacity) == 'string') { div.style.opacity=this.percentOpacity/100; }
		}
		if (this.overlap) {
			var z = GOverlay.getZIndex(this.point.lat());
			this.div_.style.zIndex = z;
		}
	}
	
	ELabel.prototype.remove = function() {
		this.div_.parentNode.removeChild(this.div_);
	}
	
	ELabel.prototype.copy = function() {
		return new ELabel(this.point, this.html, this.classname, this.pixelOffset, this.percentOpacity, this.overlap);
	}
	
	ELabel.prototype.redraw = function(force) {
		var p = this.map_.fromLatLngToDivPixel(this.point);
		var h = parseInt(this.div_.clientHeight);
		this.div_.style.left = (p.x + this.pixelOffset.width) + "px";
		this.div_.style.top = (p.y +this.pixelOffset.height - h) + "px";
	}
	
	ELabel.prototype.show = function() {
		this.div_.style.display="";
	}
	
	ELabel.prototype.hide = function() {
		this.div_.style.display="none";
	}
	
	ELabel.prototype.setContents = function(html) {
		this.html = html;
		this.div_.innerHTML = '<div id = "' + this.label_id + '" class="' + this.classname + '">' + this.html + '</div>' ;
		this.redraw(true);
	}
	
	ELabel.prototype.setPoint = function(point) {
		this.point = point;
		if (this.overlap) {
			var z = GOverlay.getZIndex(this.point.lat());
			this.div_.style.zIndex = z;
		}
		this.redraw(true);
	}
	
	ELabel.prototype.setOpacity = function(percentOpacity) {
		if (percentOpacity) {
			if (percentOpacity < 0) { percentOpacity=0; }
			if (percentOpacity > 100) { percentOpacity=100; }
		}
		this.percentOpacity = percentOpacity;
		if (this.percentOpacity) {
			if (typeof(this.div_.style.filter) == 'string') { this.div_.style.filter='alpha(opacity:'+this.percentOpacity+')'; }
			if (typeof(this.div_.style.KHTMLOpacity) == 'string') { this.div_.style.KHTMLOpacity=this.percentOpacity/100; }
			if (typeof(this.div_.style.MozOpacity) == 'string') { this.div_.style.MozOpacity=this.percentOpacity/100; }
			if (typeof(this.div_.style.opacity) == 'string') { this.div_.style.opacity=this.percentOpacity/100; }
		}
	}
}

/**************************************************
 * dom-drag.js
 * 09.25.2001
 * www.youngpup.net
 * Script featured on Dynamic Drive (http://www.dynamicdrive.com) 12.08.2005
 **************************************************
 * 10.28.2001 - fixed minor bug where events
 * sometimes fired off the handle, not the root.
 **************************************************/
var Drag = {

	obj : null,

	init : function(o, oRoot, minX, maxX, minY, maxY, bSwapHorzRef, bSwapVertRef, fXMapper, fYMapper) {
		if (!o) { return false; }
		o.onmousedown	= Drag.start;

		o.hmode			= bSwapHorzRef ? false : true ;
		o.vmode			= bSwapVertRef ? false : true ;

		o.root = oRoot && oRoot != null ? oRoot : o ;

		if (o.hmode  && isNaN(parseInt(o.root.style.left  ))) o.root.style.left   = "0px";
		if (o.vmode  && isNaN(parseInt(o.root.style.top   ))) o.root.style.top    = "0px";
		if (!o.hmode && isNaN(parseInt(o.root.style.right ))) o.root.style.right  = "0px";
		if (!o.vmode && isNaN(parseInt(o.root.style.bottom))) o.root.style.bottom = "0px";

		o.minX	= typeof minX != 'undefined' ? minX : null;
		o.minY	= typeof minY != 'undefined' ? minY : null;
		o.maxX	= typeof maxX != 'undefined' ? maxX : null;
		o.maxY	= typeof maxY != 'undefined' ? maxY : null;

		o.xMapper = fXMapper ? fXMapper : null;
		o.yMapper = fYMapper ? fYMapper : null;

		o.root.onDragStart	= new Function();
		o.root.onDragEnd	= new Function();
		o.root.onDrag		= new Function();
	},

	start : function(e) {
		var o = Drag.obj = this;
		e = Drag.fixE(e);
		var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
		var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
		o.root.onDragStart(x, y);

		o.lastMouseX	= e.clientX;
		o.lastMouseY	= e.clientY;

		if (o.hmode) {
			if (o.minX != null)	o.minMouseX	= e.clientX - x + o.minX;
			if (o.maxX != null)	o.maxMouseX	= o.minMouseX + o.maxX - o.minX;
		} else {
			if (o.minX != null) o.maxMouseX = -o.minX + e.clientX + x;
			if (o.maxX != null) o.minMouseX = -o.maxX + e.clientX + x;
		}

		if (o.vmode) {
			if (o.minY != null)	o.minMouseY	= e.clientY - y + o.minY;
			if (o.maxY != null)	o.maxMouseY	= o.minMouseY + o.maxY - o.minY;
		} else {
			if (o.minY != null) o.maxMouseY = -o.minY + e.clientY + y;
			if (o.maxY != null) o.minMouseY = -o.maxY + e.clientY + y;
		}
		
		gv_onmousemove_before_dragging = document.onmousemove; // preserve this and put it back later
		gv_onmouseup_before_dragging = document.onmouseup; // preserve this and put it back later
		document.onmousemove	= Drag.drag;
		document.onmouseup		= Drag.end;

		return false;
	},

	drag : function(e) {
		e = Drag.fixE(e);
		var o = Drag.obj;

		var ey	= e.clientY;
		var ex	= e.clientX;
		var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
		var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
		var nx, ny;

		if (o.minX != null) ex = o.hmode ? Math.max(ex, o.minMouseX) : Math.min(ex, o.maxMouseX);
		if (o.maxX != null) ex = o.hmode ? Math.min(ex, o.maxMouseX) : Math.max(ex, o.minMouseX);
		if (o.minY != null) ey = o.vmode ? Math.max(ey, o.minMouseY) : Math.min(ey, o.maxMouseY);
		if (o.maxY != null) ey = o.vmode ? Math.min(ey, o.maxMouseY) : Math.max(ey, o.minMouseY);

		nx = x + ((ex - o.lastMouseX) * (o.hmode ? 1 : -1));
		ny = y + ((ey - o.lastMouseY) * (o.vmode ? 1 : -1));

		if (o.xMapper)		nx = o.xMapper(y)
		else if (o.yMapper)	ny = o.yMapper(x)

		Drag.obj.root.style[o.hmode ? "left" : "right"] = nx + "px";
		Drag.obj.root.style[o.vmode ? "top" : "bottom"] = ny + "px";
		Drag.obj.lastMouseX	= ex;
		Drag.obj.lastMouseY	= ey;

		Drag.obj.root.onDrag(nx, ny);
		return false;
	},

	end : function() {
		// document.onmousemove = null;
		// document.onmouseup   = null;
		document.onmousemove = (self.gv_onmousemove_before_dragging) ? gv_onmousemove_before_dragging : null;
		document.onmouseup = (self.gv_onmouseup_before_dragging) ? gv_onmouseup_before_dragging : null;
		Drag.obj.root.onDragEnd(	parseInt(Drag.obj.root.style[Drag.obj.hmode ? "left" : "right"]), 
									parseInt(Drag.obj.root.style[Drag.obj.vmode ? "top" : "bottom"]));
		Drag.obj = null;
	},

	fixE : function(e) {
		if (typeof e == 'undefined') e = window.event;
		if (typeof e.layerX == 'undefined') e.layerX = e.offsetX;
		if (typeof e.layerY == 'undefined') e.layerY = e.offsetY;
		return e;
	}
};



function GV_Legend_Tooltip_Show(item_div_name,map_div_name) {
	var map_div, legend_div, item_div, legend_tooltip_div;
	if (!map_div_name) { map_div_name = 'gmap_div'; }
	if (document.getElementById(item_div_name)) { item_div = document.getElementById(item_div_name); }
	if (document.getElementById(map_div_name)) { map_div = document.getElementById(map_div_name); }
	if (document.getElementById('gv_legend_tooltip')) { legend_tooltip_div = document.getElementById('gv_legend_tooltip'); }
	if (item_div.title && !item_div.description) {
		item_div.description = item_div.title; item_div.title = '';
	}
	if (item_div && legend_tooltip_div && item_div.description) {
		legend_tooltip_div.innerHTML = item_div.description;
		var map_pos = findPos(map_div);
		var item_pos = findPos(item_div);
		var item_height = item_div.offsetHeight || 12;
		var map_right = map_pos[0] + parseInt(map_div.offsetWidth);
		var tooltip_padding = parseInt(legend_tooltip_div.style.padding);
		var tooltip_border = parseInt(legend_tooltip_div.style.borderWidth);
		var tooltip_width = parseInt(legend_tooltip_div.style.width) || 200;
		var max_right = parseInt(map_right-tooltip_width-tooltip_padding*2-tooltip_border*2);
		legend_tooltip_div.style.left = (item_pos[0] > max_right) ? max_right+'px' : item_pos[0]+'px';
		legend_tooltip_div.style.top = parseInt(item_pos[1]+item_height+3)+'px';
		legend_tooltip_div.style.display = 'block';
		legend_tooltip_div.style.visibility = 'visible';
		// var tooltip_width = parseInt(legend_tooltip_div.offsetWidth);
	}
}

function GV_Legend_Tooltip_Hide(item_div_name) {
	var item_div, legend_tooltip_div;
	if (document.getElementById('gv_legend_tooltip')) { legend_tooltip_div = document.getElementById('gv_legend_tooltip'); }
	if (document.getElementById(item_div_name)) { item_div = document.getElementById(item_div_name); }
	if (legend_tooltip_div) {
		legend_tooltip_div.innerHTML = '';
		legend_tooltip_div.style.visibility = 'hidden';
		legend_tooltip_div.style.display = 'none';
		legend_tooltip_div.style.top = '-2000px';
		// window.setTimeout("GV_Legend_Tooltip_Hide_Delayed('"+legend_tooltip_div.id+"')",3000);
	}
}

function GV_Legend_Tooltip_Hide_Delayed(legend_tooltip_div_name) {
	var legend_tooltip_div = document.getElementById(legend_tooltip_div_name);
	if (legend_tooltip_div) {
		legend_tooltip_div.innerHTML = '';
		legend_tooltip_div.style.visibility = 'hidden';
		legend_tooltip_div.style.display = 'none';
		legend_tooltip_div.style.top = '-2000px';
	}
}

function findPos(obj) {
	var left = 0; var top = 0;
	if (obj.offsetParent) {
		left = obj.offsetLeft; top = obj.offsetTop;
		while (obj = obj.offsetParent) {
			left += obj.offsetLeft; top += obj.offsetTop;
		}
	}
	return [left,top];
}


function IE_PNG() { // correctly handle PNG transparency in Win IE 5.5 & 6.
	var arVersion = navigator.appVersion.split("MSIE")
	var version = parseFloat(arVersion[1])
	if ((version >= 5.5) && (document.body.filters)) {
		for(var i=0; i<document.images.length; i++) {
			var img = document.images[i]
			var imgName = img.src.toUpperCase()
			if (imgName.substring(imgName.length-3, imgName.length) == "PNG") {
				var imgID = (img.id) ? "id='" + img.id + "' " : "";
				var imgClass = (img.className) ? "class='" + img.className + "' " : "";
				var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' ";
				var imgStyle = "display:inline-block;" + img.style.cssText;
				if (img.align == "left") { imgStyle = "float:left;" + imgStyle; }
				if (img.align == "right") { imgStyle = "float:right;" + imgStyle; }
				if (img.parentElement.href) { imgStyle = "cursor:hand;" + imgStyle; }
				var strNewHTML = "<span " + imgID + imgClass + imgTitle
				  + " style=\"" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";"
				  + "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
				  + "(src=\'" + img.src + "\', sizingMethod='image');\"></span>" ;
				img.outerHTML = strNewHTML;
				i = i-1;
			}
		}
	}
}


