function textareaToArray(t){
	return trim(t.value).split(/[\n\r]+/);
}

function HideContent(d) {
if(d.length < 1) { return; }
document.getElementById(d).style.display = "none";
}

function ShowContent(d) {
if(d.length < 1) { return; }
document.getElementById(d).style.display = "block";
}

function ReverseContentDisplay(d) {
if(d.length < 1) { return; }
if(document.getElementById(d).style.display == "none") { document.getElementById(d).style.display = "block"; }
else { document.getElementById(d).style.display = "none"; }
}


function trim(str, chars) {
    return ltrim(rtrim(str, chars), chars);
}

function ltrim(str, chars) {
    chars = chars || "\\s";
    return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}

function rtrim(str, chars) {
    chars = chars || "\\s";
    return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}

function showMarker(i){
	if(marks.length >= i && marks[i]!="ERROR")
		marks[i].openInfoWindowHtml(getDesc(i));
}

function createMarker(point,i) {
	iconOptions = {};
  iconOptions.width = 16;
  iconOptions.height = 16;
  color = getColor(i);
  iconOptions.primaryColor = color;
  iconOptions.cornerColor = color;
  iconOptions.strokeColor = "#000000";
  myicon = MapIconMaker.createMarkerIcon(iconOptions);
  html = getShortDesc(i);
  var marker = new GMarker(point, {title:''+html, icon:myicon});
  GEvent.addListener(marker, "click", function() {
    marker.openInfoWindowHtml(getDesc(i));
  });
  return marker;
}

function getColor(i){
	if(colors.length >= i && colors[i] != "")
		return colors[i];
	else
		return "#FF0000"; 
}

function getShortDesc(i){
	output = getDesc(i);
	return(output.replace(/<BR>/g, "\n"));
}

function getDesc(i){
	output = "";
	if(locs.length >= i)
		output += locs[i];
	if(descs.length >= i && descs[i] != "")
		output += "<BR>"+descs[i];
	return(output);
}

function getHTMLCode(){
	out = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n';
	out += '<HTML xmlns="http://www.w3.org/1999/xhtml">\n<HEAD>\n';
	out += '<!-- CHANGE THE KEY BELOW TO YOUR OWN GOOGLE MAPS API KEY -->\n'; 
	out += '<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAA2UFMZAZhEnsIlnLlATrIzhSILCL80nNYNKA-RwUzzI8GBT-kAhTv9pcukNzH1UvEg9dcdbkJ48BMqw" type="text/javascript"></script>\n';
	out += '<script type="text/javascript">\n';
	out += 'var MapIconMaker = {};\n';
	out += '/**\n * MapIconMaker v1.0\n * Copyright (c) 2008 Pamela Fox\n *\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License. \n *\n *\n *  Author: Pamela Fox\n *\n *  This gives you static function(s) for creating dynamically sized and\n *  colored marker icons using the Charts API marker output.\n */\n\n var MapIconMaker = {};\n\n MapIconMaker.createMarkerIcon = function(opts) {\n   var width = opts.width || 32;\n   var height = opts.height || 32;\n   var primaryColor = opts.primaryColor || "#ff0000";\n   var strokeColor = opts.strokeColor || "#000000";\n   var cornerColor = opts.cornerColor || "#ffffff";\n    \n   var baseUrl = "http://chart.apis.google.com/chart?cht=mm";\n   var iconUrl = baseUrl + "&chs=" + width + "x" + height + \n       "&chco=" + cornerColor.replace("#", "") + "," + primaryColor.replace("#", "") + "," + strokeColor.replace("#", "") + "&ext=.png";\n   var icon = new GIcon(G_DEFAULT_ICON);\n   icon.image = iconUrl;\n   icon.iconSize = new GSize(width, height);\n   icon.shadowSize = new GSize(0,0);\n   icon.iconAnchor = new GPoint(width/2, height);\n   icon.infoWindowAnchor = new GPoint(width/2, Math.floor(height/12));\n   icon.printImage = iconUrl + "&chof=gif";\n   icon.mozPrintImage = iconUrl + "&chf=bg,s,ECECD8" + "&chof=gif";\n   var iconUrl = baseUrl + "&chs=" + width + "x" + height + \n       "&chco=" + cornerColor.replace("#", "") + "," + primaryColor.replace("#", "") + "," + strokeColor.replace("#", "");\n   icon.transparent = iconUrl + "&chf=a,s,ffffff11&ext=.png";\n \n   icon.imageMap = [\n       width/2, height,\n       (7/16)*width, (5/8)*height,\n       (5/16)*width, (7/16)*height,\n       (7/32)*width, (5/16)*height,\n       (5/16)*width, (1/8)*height,\n       (1/2)*width, 0,\n       (11/16)*width, (1/8)*height,\n       (25/32)*width, (5/16)*height,\n       (11/16)*width, (7/16)*height,\n       (9/16)*width, (5/8)*height\n   ];\n   for (var i = 0; i < icon.imageMap.length; i++) {\n     icon.imageMap[i] = parseInt(icon.imageMap[i]);\n   }\n \n   return icon;\n }\n';
	out += 'function showMarker(i){\n if(marks.length >= i && marks[i]!="ERROR")\n marks[i].openInfoWindowHtml(marks[i].getTitle().replace(/\\n/g, "<BR>"));\n}\n\nfunction createMarker(point,color,desc) {\n iconOptions = {};\n iconOptions.width = 16;\n iconOptions.height = 16;\n iconOptions.primaryColor = color;\n iconOptions.cornerColor = color;\n iconOptions.strokeColor = "#000000";\n myicon = MapIconMaker.createMarkerIcon(iconOptions);\n var marker = new GMarker(point, {title:""+(desc.replace(/<BR>/g, "\\n")), icon:myicon});\n GEvent.addListener(marker, "click", function() {\n  marker.openInfoWindowHtml(desc);\n}\n);\n return marker;\n}\n';
	out += 'function toggleMarks(s){\n temp = s.split(" ");\n for(i=0; i < temp.length; i++){\n  j = parseInt(temp[i]);\n  if(!isNaN(j) && j >= 0 && j < marks.length && marks[j] != "ERROR"){\n   if (marks[j].isHidden()) {\n   marks[j].show();\n   } else {\n   marks[j].hide();\n  }\n }\n}\n}\n\n';
	out += 'var map;\n';
	out += 'var marks = new Array();\n';
	for(i=0; i < marks.length; i++){
		if(marks[i] != "ERROR")
			out += 'marks['+i+']=createMarker(new GLatLng('+marks[i].getLatLng().lat()+','+marks[i].getLatLng().lng()+'),"'+getColor(i)+'","'+getDesc(i)+'");\n';
		else
			out += 'marks['+i+']="ERROR";';
	}
	out += 'function initialize() {\n map = new GMap2(document.getElementById("map_canvas"));\n map.addControl(new GSmallMapControl());\n bounds = new GLatLngBounds;\n for(i = 0; i < marks.length; i++){\n if(marks[i] != "ERROR"){\n bounds.extend(marks[i].getLatLng());\n }\n }\n sw = bounds.getSouthWest();\n ne = bounds.getNorthEast();\n newbounds = new GLatLngBounds(new GLatLng(sw.lat() - .05*(ne.lat()-sw.lat()),sw.lng()-.05*(ne.lng()-sw.lng())),new GLatLng(ne.lat() + .05*(ne.lat()-sw.lat()),ne.lng()+.05*(ne.lng()-sw.lng())));\n map.setCenter(newbounds.getCenter(), map.getBoundsZoomLevel(newbounds)); for(i = 0; i < marks.length; i++){\n if(marks[i] != "ERROR"){\n map.addOverlay(marks[i]);\n }\n }\n}\n';
	out += '</script>\n';
	out += '</HEAD>\n<BODY onload="initialize()" onunload="GUnload()">\n';
	out += '<TABLE border=0 CELLPADDING=0 CELLSPACING=0>\n<TR>\n<TD><div id="map_canvas" style="width: 512px; height: 307px"></div>\n</TD><TD><div id="leg" style="width: 150px; height: 311px; overflow: auto; border: 1px solid #D3DCE3; background-color: #FFFFFF; padding: 5px; margin-left: 2px; margin-right:2px; margin-bottom: 0px; margin-top: 0px; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 11px; color: #444; text-decoration: none; text-align: left;">'+makeLegend()+'</div></TD></TR></TABLE>';
	out += '</BODY>\n</HTML>\n';
	return out;
}

function getImageCode(){
	cpoint = newbounds.getCenter();
	zlevel = map.getBoundsZoomLevel(newbounds);
	return "http://maps.google.com/staticmap?center="+cpoint.lat()+","+cpoint.lng()+"&zoom="+zlevel+"&size=512x307&format=gif&&key=ABQIAAAA2UFMZAZhEnsIlnLlATrIzhSILCL80nNYNKA-RwUzzI8GBT-kAhTv9pcukNzH1UvEg9dcdbkJ48BMqw";
}

function getCallBackFunction(indexv){
	return function(response) {
      if (!response || response.Status.code != 200) {
       	marks[indexv] = "ERROR";
      } else {
        place = response.Placemark[0];
        point = new GLatLng(place.Point.coordinates[1],place.Point.coordinates[0]);
    		marks[indexv] = createMarker(point,indexv);
    		map.addOverlay(marks[indexv]);
      }
      document.getElementById('processingdiv').innerHTML = "Processed "+(indexv+1)+" of "+locs.length+" locations. Please wait ...";
			loadLocation(indexv + 1);
    }
}
    
var map;
var geocoder;
var locs;
var colors;
var descs;
var marks;
var newbounds;

function initialize() {
  map = new GMap2(document.getElementById("map_canvas"));
  map.addControl(new GSmallMapControl());
  map.setCenter(new GLatLng(34, 0), 1);
  geocoder = new GClientGeocoder();
  if(trim(document.getElementById('locations').value) != "")
  	addLocations();
}

function toggleMarks(s){
	temp = s.split(" ");
	for(i=0; i < temp.length; i++){
		j = parseInt(temp[i]);
		if(!isNaN(j) && j >= 0 && j < marks.length && marks[j] != "ERROR"){
			if (marks[j].isHidden()) {
          marks[j].show();
        } else {
          marks[j].hide();
        }
		}
	}
}

function makeLegend(){
	ltext = document.getElementById('legend');
	legendtext = "<TABLE BORDER=0 CELLSPACING=2 CELLPADDING=2>";
	datitle = trim(document.getElementById('legtitle').value);
	if(datitle == "")
		datitle = "Legend";
	if(trim(ltext.value) != ""){
		legendlines = textareaToArray(ltext);
		lcolors = new Array(legendlines.length);
		ldescs = new Array(legendlines.length);
		lindexes = new Array(legendlines.length);
		hasindexes = false;
		for (i=0; i<legendlines.length; i++){
			value = legendlines[i].split("|");
			if(value.length > 0)
				lcolors[i] = trim(value[0]);
			else
				lcolors[i] = "";
			if(value.length > 1)
				ldescs[i] = trim(value[1]);
			else
				ldescs[i] = "";
			if(value.length > 2){
				lindexes[i] = trim(value[2]);
				hasindexes = true;
			}else
				lindexes[i] = "";
		}
		if(!hasindexes){
			legendtext += "<TR><TD valign=MIDDLE COLSPAN=2><B>"+datitle+"</B></TD></TR>";
			for (i=0; i<legendlines.length; i++){
				legendtext += "<TR><TD valign=middle><div style=\"width: 10px; height: 10px; background-color: "+lcolors[i]+";\"></div></TD><TD ALIGN=LEFT>"+ldescs[i]+"</TD></TR>\n";
			}
		}else{
			legendtext += "<TR><TD valign=MIDDLE COLSPAN=3><B>"+datitle+"</B></TD></TR>";
			for (i=0; i<legendlines.length; i++){
				legendtext += "<TR><TD valign=middle><input type=checkbox onClick=\"toggleMarks('"+trim(lindexes[i])+"');\" CHECKED></TD><TD valign=middle><div style=\"width: 10px; height: 10px; background-color: "+lcolors[i]+";\"></div></TD><TD ALIGN=LEFT>"+ldescs[i]+"</TD></TR>\n";
			}
		}
	}else{
		legendtext += "<TR><TD valign=MIDDLE COLSPAN=2><B>"+datitle+"</B></TD></TR>";
		for (i=0; i<marks.length; i++){
			if(marks[i] != "ERROR"){
				legendtext += "<TR><TD valign=middle><div style=\"width: 10px; height: 10px; background-color: "+getColor(i)+";\"></div></TD><TD ALIGN=LEFT><A href=\"javascript:void(0)\" onclick=\"showMarker("+i+")\">"+locs[i]+"</A></TD></TR>\n";
			}
		}
	}
	legendtext += "</TABLE>\n";
	return legendtext;
}

function createLegend(){
	document.getElementById('leg').innerHTML = makeLegend();
}

function updateOutput(){
	bounds = new GLatLngBounds; 
	for(i = 0; i < marks.length; i++){
  	if(marks[i] != "ERROR"){
  		bounds.extend(marks[i].getLatLng());
  	}
  }
  sw = bounds.getSouthWest();
  ne = bounds.getNorthEast();
  newbounds = new GLatLngBounds(new GLatLng(sw.lat() - .05*(ne.lat()-sw.lat()),sw.lng()-.05*(ne.lng()-sw.lng())),new GLatLng(ne.lat() + .05*(ne.lat()-sw.lat()),ne.lng()+.05*(ne.lng()-sw.lng())));
  map.setCenter(newbounds.getCenter());
  map.setZoom(map.getBoundsZoomLevel(newbounds));
	text = "Latitude Longitude\n";
	for(i = 0; i < marks.length; i++){
		if(marks[i] != "ERROR"){
			latlng = marks[i].getLatLng();
			text += ""+latlng.lat()+" "+latlng.lng()+"\n";
		}else{
			text += ""+marks[i]+" "+marks[i]+"\n";
		}
	}
	createLegend();
	document.getElementById('latslngs').value = text;
	document.getElementById('htmlcode').value = getHTMLCode();
	HideContent("processingdiv");
	ShowContent("inputdiv");
	ShowContent("outputdiv");
	errors = "";
	for (i=0; i<marks.length; i++){
		if(marks[i] == "ERROR")
			errors += "Error loading location "+(i+1)+"\n";
	}
	if(errors != ""){
		document.getElementById('errs').value = errors;
		ShowContent("errdiv");
	}else
		HideContent("errdiv");
}

function loadLocation(i){
	if(i < locs.length){
		if(locs[i] != ""){
			loca = locs[i].split(" ");
			if(loca.length ==	2 && !isNaN(Number(loca[0])) && !isNaN(Number(loca[1]))){
				point = new GLatLng(Number(loca[0]),Number(loca[1]));
				locs[i] = "Location "+(i+1);
    		marks[i] = createMarker(point,i);
//    		setTimeout("map.addOverlay(marks["+i+"])",10);
				map.addOverlay(marks[i]);
    		document.getElementById('processingdiv').innerHTML = "Processed "+(i+1)+" of "+locs.length+" locations. Please wait ...";
				setTimeout("loadLocation("+(i+1)+")",0);
			}else{	
				setTimeout("geocoder.getLocations('"+locs[i].replace(/\'/g,"\\'")+"', getCallBackFunction("+i+"))",1000);
			}
		}else{
			marks[i] = "ERROR";
			loadLocation(i+1);
		}
	}else{
		/*
		mgr = new GMarkerManager(map);
		mgr.addMarkers(marks,0);
		mgr.refresh();
		*/
    updateOutput();
  }
}

function addLocations(){
	map.setCenter(new GLatLng(34, 0), 1);
	document.getElementById('latslngs').value = "";
	document.getElementById('htmlcode').value = "";
	HideContent("outputdiv");
	HideContent("inputdiv");
	ShowContent("processingdiv");
  document.getElementById('leg').innerHTML = "";
	map.clearOverlays();
	lines = textareaToArray(document.getElementById('locations'));
	locs = new Array(lines.length);
	colors = new Array(lines.length);
	descs = new Array(lines.length);
	for (i=0; i<lines.length; i++){
		value = lines[i].split("|");
		if(value.length > 0)
			locs[i] = trim(value[0]);
		else
			locs[i] = "";
		if(value.length > 1)
			colors[i] = trim(value[1]);
		else
			colors[i] = "";
		if(value.length > 2)
			descs[i] = trim(value[2]);
		else
			descs[i] = "";
	}
	marks = new Array(locs.length);
	setTimeout("loadLocation(0)",0);
	/*
	for (i=0; i<locs.length; i++){
		if(locs[i] != ""){
			loca = locs[i].split(" ");
			if(loca.length ==	2 && !isNaN(Number(loca[0])) && !isNaN(Number(loca[1]))){
				point = new GLatLng(Number(loca[0]),Number(loca[1]));
				locs[i] = "Location "+(i+1)+"<BR>("+point.lat()+",<BR>"+point.lng()+")";
    		marks[i] = createMarker(point,i);
    		map.addOverlay(marks[i]);
    		ind = ind + 1;
    		document.getElementById('processingdiv').innerHTML = "Processed "+ind+" of "+locs.length+" locations. Please wait ...";
			}else{	
				setTimeout("geocoder.getLocations('"+locs[i]+"', getCallBackFunction("+i+"))",1000*i);
			}
		}else{
			marks[i] = "ERROR";
		}
	}
	if(ind == locs.length){
     updateOutput();
  }
  */
}