/* Googlemap overlay that makes polylines sensitive to mouse over, out and click,
 * This overlay does not render anything visual itself, only image map
 * to react to mouse events onEdgeOver, onEdgeOut and onEdgeClick must be implemented;
 */

function GPolyMouseSensor(uid) {
	if (! uid)
		uid = '_gpms';
	this.uid = uid;
	this.edges = {};
	this._counter = 0;
}
GPolyMouseSensor.createClass = function() {
	GPolyMouseSensor.prototype = new GOverlay();
	var from = GPolyMouseSensor.proto;
	var to = GPolyMouseSensor.prototype;
	for (var key in from)
		to[key] = from[key];
	delete GPolyMouseSensor.proto;
}

GPolyMouseSensor.proto = {
	lineWeight : 14,
	override : function(members) {
		for (var key in members) {
			GPolyMouseSensor.prototype[key] = members[key];
		}
	},

	addEdge : function(edge){
		this.edges[edge.uid] = edge;
		if (this.rendered) 
			this.renderEdge(uid);
	},
	removeEdge : function(uid){
		if (this.rendered) {
			var el = document.getElementById(this.getEdgeId(uid));
			if (el) 
				el.parentNode.removeChild(el);
		}
		delete this.edges[uid];
	},
	
	getEdgeId : function(uid){
		return this.uid + '_' + uid;
	},
	
	/* some point coordinates from latLng are negative.
	   Image map coordinates may not be negative thus we need own origin
	   for image map */
	calculateBounds : function(){
		var b = {
			minX: -1000000,
			maxX:  1000000,
			minY: -1000000,
			maxY:  1000000
		}
		/* don't calculate bounds, just take imaginable maximum
		var b = {
			minX: 1000000000,
			maxX: -1000000000,
			minY: 1000000000,
			maxY: -1000000000
		}
		function calc(obj) {
			var p = this.map.fromLatLngToDivPixel(new GLatLng(obj.lat, obj.lng));
			if (p.x < b.minX)
				b.minX = p.x;
			if (p.y < b.minY)
				b.minY = b.y;
			if (p.x > b.maxX)
				b.maxX = p.x;
			if (p.y > b.maxY)
				b.maxY = p.y;
		}
		for (var uid in this.edges) {
			var edge = this.edges[uid];
			calc(edge.p1);
			calc(edge.p2);
		}
		*/
		this.fullWidth = b.maxX - b.minX + 10;
		this.fullHeight = b.maxY - b.minY + 10;
		this.correction = {x : -b.minX, y : -b.minY};
		/*
			- coordinates of the image map must be (left:-correction.x, top:-correction.y)
			- correction must be ADDED to ALL x/y coordinates of the image map's areas
			- size of the image map image must be fullWidth/fullHeight
		*/
	},
	getEdgeAreaHtml : function(edge) {
		var pFrom = this.map.fromLatLngToDivPixel(new GLatLng(edge.p1.lat, edge.p1.lng));
		var pTo = this.map.fromLatLngToDivPixel(new GLatLng(edge.p2.lat, edge.p2.lng));

		var w = pTo.x - pFrom.x;
		var h = pTo.y - pFrom.y;

		var fact = 1 / Math.sqrt(w * w + h * h) * this.lineWeight / 2;

		var v = {x : Math.round(h * fact), y : Math.round(-w * fact)};

		var cor = this.correction;
		var poly = [];
		poly.push([pFrom.x + v.x + cor.x, pFrom.y + v.y + cor.y]);
		poly.push([pTo.x + v.x + cor.x, pTo.y + v.y + cor.y]);
		poly.push([pTo.x - v.x + cor.x, pTo.y - v.y + cor.y]);
		poly.push([pFrom.x - v.x + cor.x, pFrom.y - v.y + cor.y]);
		
		var coords = '';
		for (var i = 0; i < poly.length; i++) {
			if (i > 0)
				coords += ' ';
			coords += poly[i][0] +','+ poly[i][1];
		}
		return '<area style="cursor:pointer" shape="poly" coords="'+coords+'" alt="'+edge.title+'" title="'+edge.title+'"'+
			' onclick="_gpmsClick(\''+this.uid+'\','+edge.uid+'); return false"'+
			' onmouseover="_gpmsOver(\''+this.uid+'\','+edge.uid+')"'+
			' onmouseout="_gpmsOut(\''+this.uid+'\','+edge.uid+')" />';
	},
	
	/* GOverlay overrides */
	initialize : function(map) {
		this.map = map;
	},
	
	// Copy our data to a new GPolyMouseSensor
	copy : function() {
	  return new GPolyMouseSensor(this.x, this.y);
	},

	// Redraw the rectangle based on the current projection and zoom level
	redraw : function(force) {
		if (!force)
			return;
		this.remove();

		this.calculateBounds();

		var div = document.createElement("div");
		div.style.position = 'absolute';
		div.style.left = (-this.correction.x)+'px';
		div.style.top = (-this.correction.y)+'px';
		div.style.width = this.fullWidth+'px';
		div.style.height = this.fullHeight+'px';
		div.style.zIndex = 100000000;

		var imgMapId = this.uid;
		var html = [];
		html.push('<map id="'+imgMapId+'" name="'+imgMapId+'">\n');

		// var proj = G_NORMAL_MAP.getProjection();
		for (var uid in this.edges) {
			var edge = this.edges[uid];
			html.push(this.getEdgeAreaHtml(edge));
		}

		html.push('</map>\n');
		html.push('<img src="clear.gif" style="border:0px; width:'+this.fullWidth+'px; height:'+this.fullHeight+'px;" usemap="#'+imgMapId+'" />');
		html = html.join('\n');
		div.innerHTML = html;

		var pane = G_MAP_MARKER_SHADOW_PANE;
		/*
		G_MAP_FLOAT_PANE
		G_MAP_MAP_PANE
		G_MAP_FLOAT_SHADOW_PANE
		G_MAP_MARKER_SHADOW_PANE
		*/
		map.getPane(pane).appendChild(div);
		this.div = div;
		this.rendered = true;
		_gpms[this.uid] = this;
	},
	remove : function() {
		if (! this.div)
			return;
		this.div.parentNode.removeChild(this.div);
		this.div = null;
		this.rendered = false;
		delete _gpms[this.uid];
	},
	
	/* events to override */
	onEdgeOver: function(edgeuid) {},
	onEdgeOut: function(edgeuid) {},
	onEdgeClick: function(edgeuid) {}
}
var _gpms = {};
function _gpmsOver(uid, edgeuid) {
	_gpms[uid].onEdgeOver(edgeuid);
}
function _gpmsOut(uid, edgeuid) {
	_gpms[uid].onEdgeOut(edgeuid);
}
function _gpmsClick(uid, edgeuid) {
	_gpms[uid].onEdgeClick(edgeuid);
}


/*
function drawPointPoly(poly) {
	var llp = [];
	var str = '';
	for (var i = 0; i < poly.length; i++) {
		var p = poly[i];
		var ll = map.fromDivPixelToLatLng(new GPoint(p[0], p[1]));
		llp.push(ll);
		str += p[0] + ',' + p[1] + ' ';
	}
	var polyline = new GPolyline(llp, '#FF0000', 1, 1);
	map.addOverlay(polyline);
	dbg(str);

	// drawing axis
	llp = [];
	llp.push(map.fromDivPixelToLatLng(new GPoint(0, 0)));
	llp.push(map.fromDivPixelToLatLng(new GPoint(1, 1)));
	polyline = new GPolyline(llp, '#0000FF', 10, 10);
	map.addOverlay(polyline);
}
*/
