function MapTrips() {
	var this1 = this;
	var debug = true;
	this1.mymap = null;
	var lastHL = null; // Last highlighted trip
	var markerCB = null;
	
	this1.HLmarker = null;
	this1.loadingMsg = null;

	this1.tripHighlighted = null; // current highlighted trip
	this1.visitHighlighted = null; // last highlighted visit
	this1.markerInfo = null;
	/*========================================================================================
	  
	   Function : init
	   
	 ========================================================================================*/
	this1.init = function(map1) {
		logit("init");
		this1.mymap = map1;
		// preload icons
		this1.tripsPositionIcon_ = new Image();
		this1.tripsPositionIcon_.src = "myicons/Blue-ani-16-slow.gif";
	}
	/*========================================================================================
	  
	   Function : parseXml
	   
	   creates markerInfo structure
	  
	 ========================================================================================*/
	this1.parseXml = function(data) {
		logit("parseXml");

		//
		// get xml info 
		//
		var tempInfo = {};
	
		tempInfo.name 					= $(data).find("document").attr("name");
	
		var l_nano = 380;   // upto 645
		var tripsAll = [];
		$(data).find("trip").each(function() {
			var trip = {};
			trip.name 			= $(this).attr("name");
			trip.maxlat 		= parseFloat($(this).find("trip_maxlat").text());
			trip.maxlng 		= parseFloat($(this).find("trip_maxlng").text());
			trip.minlat 		= parseFloat($(this).find("trip_minlat").text());
			trip.minlng 		= parseFloat($(this).find("trip_minlng").text());
			
			setCenterBounds(trip); // set bounds and center for this trip
			
			trip.markercolor = NanometerToRGB(l_nano,1.0);
			
			l_nano += 10;
					
	  	logit("found trip:"+trip.name);
			var helpCity = [];
			var visitAll = [];
			$(this).find("visit").each(function() {
				var visit = {};
				visit.visitdate	= $(this).attr("date");
		  	visit.city 		  = $(this).find("city").text();
		  	visit.country	  = $(this).find("country").text();
		  	//logit("found city:"+visit.city);
				
		  	visit.gpslat 	= parseFloat($(this).find("gpslat").text());
		  	visit.gpslng 	= parseFloat($(this).find("gpslng").text());
		  	
		  	// double city markers are placed next to each other
				if (typeof(helpCity[visit.city]) != "undefined") {
					helpCity[visit.city] += 1;
			  	logit("found city:"+visit.city+"/"+helpCity[visit.city]);
				} else {
					helpCity[visit.city] = 1;
					//logit("found city:"+visit.city+"/"+helpCity[visit.city]);
				}
				visit.citynr    = helpCity[visit.city];  	
		  	//visit.marker  = createBlock(trip.name,trip.markercolor,visit.gpslat,visit.gpslng,visit.visitdate,visit.city,helpCity[visit.city]);
		  	
				visitAll.push(visit);
			});
			trip.visit = visitAll;
			setCenterBounds(trip);
			tripsAll.push(trip);
			tripsAll.markersAdded = false;
		});
		tempInfo.trip = tripsAll;
		tempInfo.markersAdded = false;
		
		this1.markerInfo = tempInfo;
		
		return; // tempInfo;
	}
	this1.addMarker = function(trip,city,visitdate,gps) {
		createBlock(trip,"#000000",gps.lat(),gps.lng(),visitdate,city,0);
	}
	/*========================================================================================
	  
	   Function : hide
	   
	 ========================================================================================*/
	this1.hide = function(exceptIdx) {
		
		var tripA = this1.markerInfo.trip;
		
		//logit("hide except:"+exceptIdx);
		var eIdx = -1;  // Except idx
		if (typeof(exceptIdx) != "undefined" ) {
			eIdx = exceptIdx;
		}
		//logit("hide all except:"+eIdx);
		for (var i = 0; i < tripA.length; i += 1) {
			//logit("Remove Trip Marker:"+tripA[i].name);
			if (eIdx != i) {
				for (var j = 0; j < tripA[i].visit.length; j += 1) {
					//logit("Remove marker:"+i+'/'+j);
					if (tripA[i].visit[j].marker) tripA[i].visit[j].marker.hide();		
				}
			}
		}
	}
	/*========================================================================================
	  
	   Function : show
	   
	 ========================================================================================*/
	this1.show = function(show_trip) {
		this1.curTripIdx = null;  // remember if only one trip is shown
		if (show_trip) {
			this1.curTripIdx = getIndex(show_trip);
		}
		if (this1.curTripIdx) {
			this1.tripHighlighted = this1.markerInfo.trip[this1.curTripIdx];
			this1.visitIdx = -1;
			showMarker(this1.curTripIdx);
		} else {
			// no starting idx or not known, then show all
			for (var i = 0; i < this1.markerInfo.trip.length; i += 1) {
				showMarker(i);
			}
		}
	}
	function showMarker(i) {
		//logit("Remove Trip Marker:"+tripA[i].name+"/"+show_trip);
		var tripA = this1.markerInfo.trip;
		for (var j = 0; j < tripA[i].visit.length; j += 1) {
			//logit("Remove marker:"+i+'/'+j);
			if (tripA[i].visit[j].marker) {
				if (tripA[i].visit[j].marker) tripA[i].visit[j].marker.show();		
			} else {
				// no marker created yet, then create it now
				var trip = tripA[i];
				var visit = trip.visit[j];
	  	  visit.marker  = createBlock(trip.name,trip.markercolor,visit.gpslat,visit.gpslng,visit.visitdate,visit.city,visit.citynr);
	  	  // add marker to markerInfo
			}
		}
	}
	function getIndex(name) {
		for (var i = 0; i < this1.markerInfo.trip.length; i += 1) {
			if (name === this1.markerInfo.trip[i].name) {
				return(i);
			}
		}
		return null;
	}

	/*========================================================================================
	  
	   Function : highlight a trip
	   
	 ========================================================================================*/
	this1.highlight = function(trip,px) {
		this1.tripHighlighted = this1.markerInfo.trip[trip];
		logit("highlight:"+trip+"/"+this1.markerInfo.trip[trip].name);
		this1.visitIdx = -1;
		var visitA = this1.markerInfo.trip[trip].visit;
		for (var j = 0; j < visitA.length; j += 1) {
			if (visitA[j].marker) {
				visitA[j].marker.highlight(px,1e8);		
				visitA[j].marker.show();
			}
		}
	}
	/*========================================================================================
	  
	   Function : unhighlight a trip
	   
	 ========================================================================================*/
	this1.unhighlight = function(trip) {
		var visitA = this1.markerInfo.trip[trip].visit;
		for (var j = 0; j < visitA.length; j += 1) {
			if (visitA[j].marker) visitA[j].marker.unhighlight();		
		}
	}
	/*========================================================================================
	  
	   Function : highlight a visit
	   
	 ========================================================================================*/
	this1.highlightVisit = function(visitIdx,CB) {
		logit("highlightVisit:"+visitIdx);
		
		if (!this1.tripHighlighted) return;

		if (visitIdx >= this1.tripHighlighted.visit.length) return;
		
		//if (this1.visitHighlighted) this1.visitHighlighted.unhighlight();

		this1.visitIdx = visitIdx;
	
		var visit = this1.tripHighlighted.visit[visitIdx];
		
		if (visit.marker) {
			this1.visitHighlighted = visit.marker;
			logit("highlightVisit before 2");
			showHLmarker(visit.marker,function() {
				logit("highlightVisit 2:"+this1.visitIdx);
				CB(visit.marker.point_);
			});
			return;
		}
	  logit("highlightVisit:"+this1.visitIdx);
		return null;
	}
	
	this1.getNextIdx = function(direction,loop) {
		var visitIdx = this1.visitIdx;
		logit("getNextIdx before:"+visitIdx+"/"+direction+"/"+loop);
		if (direction == "prev") {
			logit("highlightVisit prev:"+visitIdx);
			visitIdx--;
			if (visitIdx < 0) {
				return null;
			} 
		} else {
			logit("highlightVisit next:"+visitIdx);
			visitIdx++;
			if (visitIdx >= this1.tripHighlighted.visit.length) {
				if (loop) {
					visitIdx = 0;
				} else {
					return null;
				}
			}
		}
		logit("getNextIdx after:"+visitIdx);
		return visitIdx;
	}
	this1.getPoint = function(visitIdx) {
		return this1.tripHighlighted.visit[visitIdx].marker.point_;
	}
	this1.highlightVisitStop = function() {
		logit("highlightVisitStop");
		if (this1.visitHighlighted) this1.visitHighlighted.unhighlight();
		if (this1.HLmarker) this1.HLmarker.hide();
		this1.visitIdx = -1;
	}
	this1.highlightVisitRainbow = function() {
		if (this1.visitHighlighted) this1.visitHighlighted.unhighlight();
		this1.visitIdx = -1;
	}
	this1.getCity = function(visitIdx) {
		return this1.tripHighlighted.visit[visitIdx].city;
		/*
		if (!this1.tripHighlighted) return;
		if (this1.visitIdx < 0) return;
		return this1.tripHighlighted.visit[this1.visitIdx].city;
		*/
	}
	this1.getCountry = function(visitIdx) {
		return this1.tripHighlighted.visit[visitIdx].country;
	}
	this1.getDate = function(visitIdx) {
		return this1.tripHighlighted.visit[visitIdx].visitdate.substr(0,10);
		/*
		if (!this1.tripHighlighted) return;
		if (this1.visitIdx < 0) return;
		return this1.tripHighlighted.visit[this1.visitIdx].visitdate.substr(0,10);
		*/
	}

	/*========================================================================================
  
	   Function : createBlock
	  
	 ========================================================================================*/
	function createBlock(groupid,color,gpslat,gpslng,date_,name_,offset_) {
		// offset : to avoid 2 markers on same gps
		//logit("Create Block:"+name);
		
	  var pos = new GLatLng(gpslat,gpslng);
	  
	  // NanometerToRGB(i,1.0) // i from 380 to 645
	  var marker = new BdccBlock(pos,color,date_.substr(0,10)+' '+name_,offset_);
	  marker.date_ = date_;
	  marker.city_ = name_; 
	  
	  if (markerCB) {
	   	GEvent.addListener(marker, "click", function() {
	   		markerCB(this);
			});
		}	  
		this1.mymap.addOverlay(marker);
		
		return marker;
	}
	/*========================================================================================
  
	   Function : setZoomCenter
	
		 Zoom in and set the center  
	 ========================================================================================*/
	this1.setZoomCenter = function(trip) {
		
		if (typeof(trip) === "undefined") {
			// show world map
			this1.mymap.setCenter(new GLatLng(0,0),2);
		} else {
			var reg1 = mapTrips.markerInfo.trip[trip];
			
			if (reg1.region_bounds) {
				var zoom = this1.mymap.getBoundsZoomLevel(reg1.region_bounds);
			} else {
				var zoom = 8;
			}
			logit("zoom level for displaying region="+zoom+',at:'+reg1.center.lat()+'/'+reg1.center.lng());
			this1.mymap.setCenter(reg1.center);
			this1.mymap.setZoom(zoom);
		}
	}

	/*========================================================================================
  
	   Function : createBlock
	  
	 ========================================================================================*/
	this1.load = function(map,p_xmlfile,markerCallback,callback,fresh) {
		if (map) this1.mymap = map;
		
		markerCB = markerCallback;
		
		if (!fresh) {
			logit("Get File data:"+p_xmlfile);
		  // Because IE had a problem (parse error) when using jQuery, I am using Google Maps Ajax 
		 	GDownloadUrl(p_xmlfile+"?dummy=8", function(data, responseCode) {
				if(responseCode == 200) {
					xml = GXml.parse(data);
					// I do not quite understand the following line, but found it on the web 
					$('node', xml.documentElement);
				 	logit("******************** ajax received:"+$(xml).find("document").attr("name"));
	 				this1.parseXml(xml);  // parse and save markerInfo
				 	callback(xml);
				} else if(responseCode == -1) {
					alert("Data request timed out. Please try later.");
					return;
				} else {
					alert("Request resulted in error. Check XML file is retrievable.");
					return;
				}
				logit("ende GDownloadUrl");		
			});
		} else {		
			logit("Get FRESH data from ajaxGetTravels");
			$.ajax({
				type	: "GET",
				url		: "ajaxGetTravels.php",
				data	: "type=XML",
				error: function() {
					alert("Data request timed out. Please try later.");
					return;
				},
				success: function(xml){
				 	logit("******************** ajax received:"+$(xml).find("document").attr("name"));
	 				this1.parseXml(xml);  // parse and save markerInfo
				 	callback(xml);
				}
			});
		}
	}
	function logit(text) {
		if (debug) logitAll("MapTrips-"+text);
	}

	function showHLmarker(BdccMarker,CB) {
		//var refDiv = BdccMarker.div_;
		logit("showHLmarker");		
		if (this1.HLmarker == null) {
			logit("new HLmarker");
			// http://www.panoramio.com/img/panoramio-marker.png
			//icon_.src = "images/favicon.ico";
			//icon_.src = "myicons/blue-on-16.png";
			//var iconready_ = new Image();
			//iconready_.src = "myicons/blue-on-16.png"; // preload
			//icon_.src = "myicons/ajax-loader-big.gif";
			// Preload Icon because BdccBlock needs to determine width/height
			//
			// we do not do an imgLoaded wait, because in IE7 we get a loop
			// probably because marker is animated GIF
			//
		  //imgLoaded(icon_,function() {
	  	logit("image loaded");
			this1.HLmarker = new BdccBlock(BdccMarker.point_,BdccMarker.color_,BdccMarker.tooltip_,0,this1.tripsPositionIcon_.src,"myicons/blue-on-16.png");
			this1.mymap.addOverlay(this1.HLmarker);
			this1.HLmarker.show();
			logit("now callback after HLmarker created");
			CB();
		} else {
			logit("Reposition HLmarker");
			this1.HLmarker.tooltip_ = BdccMarker.tooltip_;
			this1.HLmarker.setLatLng(BdccMarker.point_,"fast",CB);
		}
	}
}
