// Constructor.
XMarker = function(map) {
	this.XLimit = XMarker.defaultXLimit;
	this.YLimit = XMarker.defaultYLimit;
	this.icon = XMarker.defaultIcon;
	this.extraIcon = XMarker.defaultIcon;
	this.mouseOverIcon = XMarker.defaultMouseOverIcon;
	this.map = map;
	this.MAX_ZOOM_LEVELS = 20;
	this.projection = new GMercatorProjection(this.MAX_ZOOM_LEVELS);
	
	this.boundMarkers = [];	// bounds delimited by existing markers
}

XMarker.defaultXLimit = 10;	// inside this number of pixels, no additional marker is produced
XMarker.defaultYLimit = 10;

XMarker.defaultIcon = new GIcon();
XMarker.defaultIcon.image = 'img/audio.jpg';

XMarker.defaultMouseOverIcon = new GIcon(new GIcon(G_DEFAULT_ICON));
XMarker.defaultMouseOverIcon.image = 'img/arrow_icon.gif';

XMarker.prototype.SetIcon = function (icon) {
	this.icon = icon;
};

XMarker.prototype.SetExtraIcon = function (icon) {
	this.extraIcon = icon;
};

XMarker.prototype.SetMouseOverIcon = function (icon) {
	this.mouseOverIcon = icon;
};

XMarker.prototype.SetXLimit = function (n) {
	this.XLimit = n;
};

XMarker.prototype.SetYLimit = function (n) {
	this.YLimit = n;
};

// The associated markers will be displayed when the mouse is moved on the main marker which is always visible
// These markers are layed on a circle around the main marker
// To display all markers with a size of 30x30 pixels (diagonal is then about 45 pixels),
// we should have 45*N pixels as circonference, that gives us the radius of 45*N/2/PI
// To simpfy the calculation, 45*N/2/3, about 15*N/2, or 8*N, even 10*N
// Give the radius minimum of 50 pixels
// To avoid math calculation, we just use steps for X & Y for each marker: Radius/(N/4)
// If we take Radius as 10*N, we have steps as: 10*N/(N/4) -> 40
// Say the center of the circle is (x, y), the first marker will be (x-radius+40*0, y+40*0),
// second (x-radius+40*1, y-40*1), third (x-radius+40*1, y+40*1), fourth (x-radius+40*2, y-40*2), fifth (x-radius+40*2, y+40*2)
function mouseOver() {
	var stepSize = 10;	// for image size of 8
	var mrker = this.marker;	// this: is the polygone
	if (mrker) {
		var mrkerMap = mrker.map;
		var manager = mrker.manager;
		N = mrker.associateList.length;
		radius = 3*N;	// for image size of 8
		if (radius < 50) {
			radius = 50;
		}
		x = mrker.point.x;
		y = mrker.point.y;
		p1 = mrker.getLatLng();
		z = mrker.map.getZoom();
		if (N > 0) {
			mk = mrker.associateList[0];
			x0 = x-radius;
			pt = manager.projection.fromPixelToLatLng(new GPoint(x0, y), z);
			mk.setLatLng(pt);
			mrkerMap.addOverlay(mk);
			polyline = new GPolyline([pt, p1], "#0000ff", 1);
			mrkerMap.addOverlay(polyline);
			mk.polyline = polyline;
		}
		j = 1;
		k = 1;
		for (i=1; i<N; i++) {
			x0 = x-radius+stepSize*j;
			if (x0 < x) {
				if ((i % 2) == 0) {
					y0 = y+stepSize*j;
				} else {
					y0 = y-stepSize*j;
					j++;
				}
			} else {
				if ((i % 2) == 0) {
					y0 = y+radius-stepSize*k;
				} else {
					y0 = y-radius+stepSize*k;
					k++;
					j++;
				}
			}
			mk = mrker.associateList[i];
			pt = manager.projection.fromPixelToLatLng(new GPoint(x0, y0), z);
			mk.setLatLng(pt);
			mrkerMap.addOverlay(mk);
			polyline = new GPolyline([pt, p1], "#0000ff", 1);
			mrkerMap.addOverlay(polyline);
			mk.polyline = polyline;
		}
	
		p1 = new GPoint(x-radius, y-radius);
		p2 = new GPoint(x-radius, y+radius);
		p3 = new GPoint(x+radius, y+radius);
		p4 = new GPoint(x+radius, y-radius);
		pts = [];
		pts.push(manager.projection.fromPixelToLatLng(p1, z));
		pts.push(manager.projection.fromPixelToLatLng(p2, z));
		pts.push(manager.projection.fromPixelToLatLng(p3, z));
		pts.push(manager.projection.fromPixelToLatLng(p4, z));
		pts.push(manager.projection.fromPixelToLatLng(p1, z));
//		polygone = new GPolygon(pts, "#f33f00", 5, 1, "#ff0000", 0.2);
		polygone = new GPolygon(pts);
		polygone.marker = mrker;
		mrkerMap.addOverlay(polygone);
		GEvent.addListener(polygone, "mouseout", function() {
			var mker = this.marker;	// this: is the polygone
			if (mker) {
				var mkerMap = mker.map;
				var mk;
				N = mker.associateList.length;
				for (i=0; i<N; i++) {
					mk = mker.associateList[i];
					mkerMap.removeOverlay(mk.polyline);
					mkerMap.removeOverlay(mk);
				}
			}
			mkerMap.removeOverlay(polygone);
		});
	}
}

// Call this to add a marker.
// gLatLng is of GLatLng class, title could be useful information associated to marker
XMarker.prototype.AddMarker = function(gLatLng, title) {
	gPoint = this.projection.fromLatLngToPixel(gLatLng, this.map.getZoom());
	
	newMarker = true;
	for (i=0; i<this.boundMarkers.length; i++) {
		if (this.boundMarkers[i].containsPoint(gPoint)) {
			newMarker = false;
			centerMarker = this.boundMarkers[i].marker;
			break;
		}
	}
	
	if (newMarker) {
		marker = new GMarker(gLatLng, { icon: this.icon });
		marker.point = gPoint;
		Xmin = gPoint.x - this.XLimit;
		if (Xmin < 0) Xmin = 0;
		Xmax = gPoint.x + this.XLimit;
		Ymin = gPoint.y - this.YLimit;
		if (Ymin < 0) Ymin = 0;
		Ymax = gPoint.y + this.YLimit;
		points = [];
		p1 = new GPoint(Xmin, Ymin);
		p2 = new GPoint(Xmin, Ymax);
		p3 = new GPoint(Xmax, Ymax);
		p4 = new GPoint(Xmax, Ymin);
		points.push(p1);
		points.push(p2);
		points.push(p3);
		points.push(p4);
		bound = new GBounds(points);
		bound.marker = marker;
		bound.title = title;
		this.boundMarkers.push(bound);
		marker.associateList = [];
		marker.polygone = null;
		marker.mainMarker = true;
		this.map.addOverlay(marker);
		mk = new GMarker(gLatLng, { icon: this.extraIcon });
		mk.mainMarker = false;
		mk.title = title;
		marker.associateList.push(mk);
	} else {
		marker = new GMarker(gLatLng, { icon: this.extraIcon });
		marker.mainMarker = false;
		centerMarker.associateList.push(marker);
		if (centerMarker.polygone == null) {
			gLatLng = centerMarker.getLatLng();
			z = this.map.getZoom();
			gPoint = this.projection.fromLatLngToPixel(gLatLng, z);
			Xmin = gPoint.x - this.XLimit;
			if (Xmin < 0) Xmin = 0;
			Xmax = gPoint.x + this.XLimit;
			Ymin = gPoint.y - this.YLimit;
			if (Ymin < 0) Ymin = 0;
			Ymax = gPoint.y + this.YLimit;
			p1 = new GPoint(Xmin, Ymin);
			p2 = new GPoint(Xmin, Ymax);
			p3 = new GPoint(Xmax, Ymax);
			p4 = new GPoint(Xmax, Ymin);
			pts = [];
			pts.push(this.projection.fromPixelToLatLng(p1, z));
			pts.push(this.projection.fromPixelToLatLng(p2, z));
			pts.push(this.projection.fromPixelToLatLng(p3, z));
			pts.push(this.projection.fromPixelToLatLng(p4, z));
			pts.push(this.projection.fromPixelToLatLng(p1, z));
//			polygone = new GPolygon(pts, "#f33f00", 5, 1, "#ff0000", 0.2);	// uncomment this line to see the polygone
			polygone = new GPolygon(pts, "#f33f00", 0, 0, "#ff0000", 0);
			centerMarker.polygone = polygone;
			polygone.marker = centerMarker;
			this.map.addOverlay(polygone);

			GEvent.addListener(centerMarker.polygone, "mouseover", mouseOver);
		}		
 	}
	marker.map = this.map;
	marker.manager = this;
	marker.title = title;
	return marker;
};


// Call this to remove a marker.
XMarker.prototype.RemoveMarker = function (marker) {
	this.map.removeOverlay(marker);
	// To be completed: remove the marker from the list
};

XMarker.prototype.Clean = function(evt) {
	this.boundMarkers = [];
}
