/* ****************************************************************** */
function Map () {
	var id = Math.round(Math.random() * 1000000);

	var obj = new _Map(id);
	    obj.name = '_Map_object_' + id;

	eval(obj.name + ' = obj');	
	
	return(obj);
}
/* ****************************************************************** */



/* ****************************************************************** */
function _Map (id) {

	this.id				= id;
	this.queue			= new Array();
	this.timer			= null;
	this.interval		= 0.4;
	this.nDraw			= 0;
	this.drawing		= false;
	this.maxOverlays	= 500;

	this.hits			= new Array();
	this.overlays		= new Array();

	this.color			= new Array();

	//this.google_api_key = 'ABQIAAAAgeSPFwT9csKBuoYs7x-Q5xSDS5hle5MQ75a4ii18e2G9D3H3KxS9Gha4gSXZkg6oEFveFL50H2z_cQ';	
	//this.load_GoogleMapsAPI();

	this.initializeMap();

}
/* ****************************************************************** */



/* ****************************************************************** */
_Map.prototype.load_GoogleMapsAPI = function () {
	var script = document.createElement('script');
		script.src = 'http://maps.google.com/maps?file=api&amp;v=2.x&amp;key=' + this.google_api_key;
		script.type='text/javascript';
			
		document.getElementsByTagName('head')[0].appendChild(script);
}
/* ****************************************************************** */



/* ****************************************************************** */
_Map.prototype.setColors = function (colors) {
	for (var i in colors) {
		var query = colors[i][0];
		var color = colors[i][1];
		
		var query_simple = only_alpha(query);
		
		this.color[query_simple] = color;
	}
}
/* ****************************************************************** */



/* ****************************************************************** */
_Map.prototype.startTimer = function () {
	if (!this.timer) {
		eval('var x = function () {' + this.name + '.update();}');
		this.timer = setTimeout(x, this.interval*1000);
		this.drawing = true;
		delete(x);
	}
}

_Map.prototype.stopTimer = function () {
	if (this.timer) clearTimeout(this.timer);
	this.timer = null;
}

/* ****************************************************************** */



/* ****************************************************************** */
_Map.prototype.update = function () {
	this.stopTimer();

	if (this.queue.length == 0) {
		this.drawing = false;
		return(null);
	}

	var tweet = this.queue.pop();

	eval('var draw = function (p) {' + this.name + '.draw_point(p, '+toJSON(tweet)+');}');

	if (tweet.location.indexOf('iPhone: ') > -1) {
		draw(new GLatLng(tweet.location.slice(8).split(',')));
	} else {
		this.geocoder.getLatLng(tweet.location, draw);
	}
	
	this.startTimer();
}
/* ****************************************************************** */



/* ****************************************************************** */
_Map.prototype.isDrawing = function () {
	return(this.drawing);
}
/* ****************************************************************** */



/* ****************************************************************** */
_Map.prototype.processResponse = function (response) {
	if (response.results && response.results.length > 0) {
		response.results.forEach(function (e) {e.query = response.query.replace(/^%22|%22$/, '')});
		response.results.forEach(function (e) {e.query_simple = only_alpha(e.query)});

		this.queue = this.queue.concat(response.results);
		
		if (!this.isDrawing()) this.update();
	}
}
/* ****************************************************************** */



/* ****************************************************************** */
_Map.prototype.draw_point = function (point, tweet) {

	if (point == null) return;

	point = this.surrounding(point);
 
 	var marker = this.createMarker(point, tweet);
 
 	document.getElementById(tweet.query_simple+'_counter').innerHTML =
		Number(document.getElementById(tweet.query_simple+'_counter').innerHTML) + 1;
 
	this.addOverlay(marker);
}

_Map.prototype.draw_central_point = function (point) {

 	var marker = this.create_central_Marker(point);
 
	this.addOverlay(marker);
}
/* ****************************************************************** */



/* ****************************************************************** */
_Map.prototype.createMarker = function (point, tweet) {
	
	var query_simple = only_alpha(tweet.query);
	
	// Create our "tiny" marker icon
	var tinyIcon = new GIcon();
//		tinyIcon.image = "http://labs.google.com/ridefinder/images/mm_20_red.png";
//		tinyIcon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
		tinyIcon.image = 'images/colors/'+ this.color[query_simple] + '.png';
//		tinyIcon.iconSize = new GSize(18, 20);
//		tinyIcon.shadowSize = new GSize(22, 20);
		tinyIcon.iconAnchor = new GPoint(6, 20);
		tinyIcon.infoWindowAnchor = new GPoint(5, 1);

	var marker = new GMarker(point, {icon:tinyIcon});
 
 	var html = this.tooltip_HTML(tweet);
 	var opts = {maxWidth:300};
 
	GEvent.addListener(marker,"mouseover", function() {marker.openInfoWindowHtml(html, opts);});
	
	return(marker);
}

_Map.prototype.create_central_Marker = function (point, tweet) {
	// Create our "tiny" marker icon
	var tinyIcon = new GIcon();
		tinyIcon.image = "http://labs.google.com/ridefinder/images/mm_20_red.png";
		tinyIcon.iconAnchor = new GPoint(6, 20);
		tinyIcon.infoWindowAnchor = new GPoint(5, 1);

	var marker = new GMarker(point, {icon:tinyIcon});
 
	return(marker);
}
/* ****************************************************************** */



/* ****************************************************************** */
_Map.prototype.addOverlay = function (new_marker) {
	if (this.overlays.length > this.maxOverlays) {
		var oldest_marker = this.overlays.shift();
			oldest_marker.remove();
	}

	this.overlays.push(new_marker);
	this.gmap.addOverlay(new_marker);
}
/* ****************************************************************** */



/* ****************************************************************** */
_Map.prototype.tooltip_HTML = function (tweet) {
	var text = tweet.text.replace(new RegExp('('+tweet.query.replace(/\s+/g, '|')+')', 'ig'), "<font color='#BB0000'>$1</font>");
		text = text.replace(/@\w+/, "");

	return ("<div style='margin-bottom:10px'><a target='_blank' style='font-weight:bold;' href='http://twitter.com/"+tweet.from_user+"'>"+tweet.from_user+"</a><br><img width='48px' height='48px' style='float:left; margin-right:10px; margin-bottom:10px' src='"+tweet.profile_image_url+"'/><i>"+text+"</i></div>");
}
/* ****************************************************************** */



/* ****************************************************************** */
_Map.prototype.surrounding = function (point) {
	this.hits[point] = (this.hits[point] ? this.hits[point]+1 : 1);
	
//	debug.innerHTML += this.hits[point] + " : " + point + " => ";

	var lat = point.lat() + ((Math.random()*(this.hits[point]*2))-this.hits[point]) / 10000;
	var lng = point.lng() + ((Math.random()*(this.hits[point]*2))-this.hits[point]) / 10000;
	
	var new_point = new GLatLng(lat, lng);
	
//	debug.innerHTML += new_point + "<br>";	
	
	return(new_point);
}
/* ****************************************************************** */



/* ****************************************************************** */
_Map.prototype.initializeMap = function () {
	if (GBrowserIsCompatible()) {
		
		var gMap = new GMap2(document.getElementById("map_canvas"));
			gMap.setCenter(new GLatLng(37.0625,-95.677068), 4);

		var gCoder = new GClientGeocoder();
		
		this.gmap = gMap;
		this.geocoder = gCoder;
	}

/*
	document.getElementById("map_canvas").childNodes[1].style.display = "none";
	document.getElementById("map_canvas").childNodes[2].style.display = "none";
*/
}
/* ****************************************************************** */



/* ****************************************************************** */
_Map.prototype.isLoaded = function () {
	return (this.gmap.isLoaded());
}
/* ****************************************************************** */
