function map(layerId) {

	this.MAX_STATIC_POIS = 20;

	// Si se proporciona la key de Google es porque queremos el mapa estático
	if (arguments[6] || GBrowserIsCompatible()) {
		this.latitud = (arguments[1])?arguments[1]:null;
		this.longitud = (arguments[2])?arguments[2]:null;
		this.zoom = (arguments[3])?arguments[3]:null;
		this.mapType = (arguments[4])?arguments[4]:null;
		this.isImage = (arguments[6])?true:false;
		this.gKey = arguments[6];
		if (typeof(document.maps) == "undefined") {
			document.maps = [];
		}
		mapNumber = document.maps.length;
		document.maps[mapNumber] = this;
		this.index = mapNumber;
		this.gmarkers = [];
		this.bindedMarkers = [];
		this.polygons = [];
		this.lines = [];
		this.editMode = false;
		this.elements = [];
		if (!this.isImage) {
			this.map = new GMap2(document.getElementById(layerId));
			this.map.addControl(new GSmallMapControl());
			this.map.addControl(new GMapTypeControl());
			if (this.longitud != null && this.latitud != null && this.zoom != null) {
				this.map.setCenter(new GLatLng(parseFloat(this.latitud), parseFloat(this.longitud)), parseInt(this.zoom), this.mapType);
			}
		} else {
			this.layerId = layerId;
			var width = document.getElementById(layerId).width;
			if (!width) {
				width = parseInt(document.getElementById(layerId).style.width);
			}
			if (!width) {
				width = 400;
			}

			var height = document.getElementById(layerId).height;
			if (!height) {
				height = parseInt(document.getElementById(layerId).style.height);
			}
			if (!height) {
				height = 400;
			}
			// Static maps are max 512px per side
			var maxSide = 512;
			var biggestSide = Math.max(width, height);
			if (biggestSide > maxSide) {
				if (width == biggestSide) {
					height = Math.round((height * maxSide) / width);
					width = maxSide;
				} else {
					width = Math.round((width * maxSide) / height);
					height = maxSide;
				}
			}

			this.imageUrl = "http://maps.google.com/staticmap?center=" + this.latitud + "," + this.longitud +
			                    "&zoom=" + this.zoom + "&maptype=" + this.mapType + "&size=" + width + "x" + height +
			                    "&key=" + this.gKey;
		}
	}
}


map.prototype = {
	setEditMode: function(editMode) {
		if (typeof(document.getElementById("editPanel")) != "undefined") {
			this.editMode = editMode;
		} else {
			return false;
		}
	},
	
	loadXMLPointsCoords: function(XMLNodes) { 
		var coords = [];
		for (var j = 0; j < XMLNodes.length; j++) {
			coords[j]={};
			coords[j]["lat"] = XMLNodes[j].getAttribute("lat");
			coords[j]["lng"] = XMLNodes[j].getAttribute("lng");
		}
		return coords;
	}, 
	
	loadFromXML: function(xmlFile) {
		//Segundo argumento opcional: una función que si se la pasa hará las veces de "onload".
		var optFunction = (typeof(arguments[1]) == "function")?arguments[1]:function () {return true};
		var mapIndex = this.index;
		var httpPois = "";
		var request = jQuery.get(xmlFile, function() {
			if (request.readyState == 4 && request.status == 200) {
				var countPois = 0;
				var xmlDoc = request.responseXML;
				var pois = xmlDoc.getElementsByTagName("poi");
				
				for (var j = 0; j< pois.length; j++) {
					if (pois[j].childNodes.length > 0) {
						//Contiene info sobre nombre y descripción;
						var lat = pois[j].getAttribute("lat");
						var lng = pois[j].getAttribute("lng");
						if (!document.maps[mapIndex].isImage) {
							var icon = pois[j].getAttribute("icon");
							var id = pois[j].getAttribute("id");
							var html = [];
							var name = [];
							for (var k = 0; k < pois[j].getElementsByTagName("description").length; k++) {
								html[k] = pois[j].getElementsByTagName("description")[k].firstChild.nodeValue.replace(/-amp-/g,"&");
								name[k] = pois[j].getElementsByTagName("name")[k].firstChild.nodeValue.replace(/-amp-/g,"&");
							}
							if (typeof(document.tmpNodeHTML) == "undefined") {
								document.tmpNodeHTML = document.createElement("div");
								document.tmpNodeName = document.createElement("div");
							}
							document.tmpNodeHTML.innerHTML = html[0];
							document.tmpNodeName.innerHTML = name[0];
							if (this.editMode) {
								draggable = true;
							} else {
								draggable = false;
							}
							document.maps[mapIndex].addMarker(
								lat, 
								lng, 
								html, 
								name, 
								id,
								icon);
						} else {
							httpPois += "|" + lat + "," + lng;
							if (++countPois > document.maps[mapIndex].MAX_STATIC_POIS) {
								break;
							}
						}
					}
				}
				if (document.maps[mapIndex].isImage && httpPois.length) {
					document.maps[mapIndex].imageUrl += "&markers=" + httpPois.substr(1);
					document.maps[mapIndex].loadStaticMap();
					return;
				}
				
				if (xmlDoc.getElementsByTagName("lines").length > 0) {
					var lines = xmlDoc.getElementsByTagName("lines")[0].getElementsByTagName("line");
					for (var j = 0; j < lines.length; j++) {
						var color = lines[j].getAttribute("color");
						var width = lines[j].getAttribute("width");
						var opacity = lines[j].getAttribute("opacity");
						var pts = lines[j].getElementsByTagName("point");
						document.maps[mapIndex].addLine(
							document.maps[mapIndex].loadXMLPointsCoords(pts), 
							color, 
							width, 
							opacity
						);
					}
				}
				if (xmlDoc.getElementsByTagName("areas").length > 0) {
					var areas = xmlDoc.getElementsByTagName("areas")[0].getElementsByTagName("area");
					for (var j = 0; j < areas.length; j++) {
						var color = areas[j].getAttribute("color");
						var fillColor = areas[j].getAttribute("fillColor");
						var width = areas[j].getAttribute("width");
						var opacity = areas[j].getAttribute("opacity");
						var fillOpacity = areas[j].getAttribute("fillOpacity");
						var pts = areas[j].getElementsByTagName("point");
						document.maps[mapIndex].addPolygon(
							document.maps[mapIndex].loadXMLPointsCoords(pts), 
							color, 
							width, 
							opacity, 
							fillColor,
							fillOpacity
						);
					}
				}	
/*				var bindedMarkers = document.maps[mapIndex].getBindedMarkers();
				for (nodeId in bindedMarkers) {
					document.getElementById(nodeId).innerHTML = document.maps[mapIndex].getSideBar(bindedMarkers[nodeId]);
				}
*/				
				if (document.maps[mapIndex].getEditMode() && typeof(editor.loadData) == "function") {
					editor.loadData(mapIndex);
				}
			}
			
			optFunction();
		});
	},

	getEditMode: function() {
		return this.editMode;
	},

	getBindedMarkers: function () {
		return this.bindedMarkers;
	},

	setCenter: function(latitud, longitud, zoom) {
		this.map.setCenter(new GLatLng(parseFloat(latitud),parseFloat(longitud)),parseInt(zoom));
	},
	
	setLabel: function(width, height, message) {
		this.label = new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(width, height));
      		var tmpDiv = document.createElement("div");
		tmpDiv.innerHTML = message;
		this.label.apply(tmpDiv);
		this.map.getContainer().appendChild(tmpDiv);
	},
	
	getMarkers: function() {
		return this.gmarkers;
	}, 

	getLines: function() {
		return this.lines;
	},

	getPolygons: function() {
		return this.polygons;
	},

	addMarker: function(latitud, longitud, html, name, id, icon) {
		var point = new GLatLng(latitud,longitud);
		var marker = new GMarker(point);
		mapIndex = this.mapIndex;
		var nombre = name;
		GEvent.addListener(marker, "click", function() {
			opts={}; 
			if (html.length == 1) {
				var info="<div style='width:200px;border-bottom:1px solid silver;'><b>"+nombre+"</b></div><br>";
				info+="<div style='width:200px'>"+html+"</div>";
				marker.openInfoWindowHtml(info, opts);
			} else {
				var infoTabs = [];
				for (var i = 0; i < html.length; i++) {
					infoTabs[i] = new GInfoWindowTab(name[i], html[i]);
				}
				marker.openInfoWindowTabsHtml(infoTabs);
			}
		});
		var gmarkerNumber = this.gmarkers.length;
		this.gmarkers[gmarkerNumber] = marker;
		this.gmarkers[gmarkerNumber].name = name;
		this.gmarkers[gmarkerNumber].poiId = id;
		this.gmarkers[gmarkerNumber].oldIcon = icon;
		this.map.addOverlay(marker);
		marker.setImage(icon);
	},
	
	addLine: function(points) {
		var color = (arguments[1])?arguments[1]:null;
		var width = (arguments[2])?arguments[2]:null;
		var opacity = (arguments[3])?arguments[3]:null;
		var lineNumber = this.lines.length;
		var pts = [];
		for (var i in points) {
			pts[i] = new GLatLng(parseFloat(points[i]["lat"]), parseFloat(points[i]["lng"]));
		}
		this.lines[lineNumber] = new GPolyline(pts, color, width, opacity);
		this.map.addOverlay(this.lines[lineNumber]);
	},
	
	addPolygon: function(points) {
		var strokeColor = (arguments[1])?arguments[1]:null;
		var strokeWidth = (arguments[2])?arguments[2]:null;
		var strokeOpacity = (arguments[3])?arguments[3]:null;
		var fillColor = (arguments[4])?arguments[4]:null;
		var fillOpacity = (arguments[5])?arguments[5]:null;
		var polygonNumber = this.polygons.length;
		var pts = [];
		for (var i in points) {
			pts[i] = new GLatLng(parseFloat(points[i]["lat"]), parseFloat(points[i]["lng"]));
		}
	        if (pts[i]["lat"] != pts[0]["lat"] && pts[i]["lng"] != pts[0]["lng"]) {
                        pts[i++] = [];
                        pts[i]["lat"] = pts[0]["lat"];
                        pts[i]["lng"] = pts[0]["lng"];
                }
		this.polygons[polygonNumber] = new GPolygon(pts, strokeColor, strokeWidth, strokeOpacity, fillColor, fillOpacity);
		this.map.addOverlay(this.polygons[polygonNumber]);
	},
        clear: function() {
                this.currentMarker = null;
                for (var i = 0; i < this.gmarkers.length; i++) {
                        this.map.removeOverlay(this.gmarkers[i]);
                }
                this.gmarkers = [];
                for (var i = 0; i < this.lines.length; i++) {
                        if (this.lines[i].active) {
                                this.map.removeOverlay(this.lines[i]);
                                this.lines[i] = null;
                        }
                }
                this.lines = [];
                for (var i = 0; i < this.polygons.length; i++) {
                        if (this.polygons[i].active) {
                                this.map.removeOverlay(this.polygons[i]);
                                this.polygons[i] = null;
                        }
                }
                this.polygons = [];
        },

	getElements: function() {
		return this.elements;	
	},

	loadStaticMap: function() {
		var img = document.getElementById(this.layerId);
		if (img) {
			img.src = this.imageUrl;
		}
	}
/*	

	sideBarElementClicked: function(gmarkerIndex) {
	        GEvent.trigger(this.gmarkers[gmarkerIndex], "click");
	},
	
	bindMarkers: function(nodeId, html) {
		this.bindedMarkers[nodeId] = html;
	},
	getSideBar: function(html) {
		//html puede ser
		//<li onclick="EVENT">TEXT</li>
		// o
		//<a href="javascript:EVENT">TEXT</a><br>
		// o
		//<td><input type="button" onclick="EVENT" value="TEXT"></td>
		// o lo que nos salga del penedés
		var ret = "";
		for (var i in this.gmarkers) {
			aux = html.replace(/EVENT/, "document.maps[" + this.index + "]" + ".sideBarElementClicked("+i+")");
			aux = aux.replace(/TEXT/, this.gmarkers[i].name);
			ret += aux;
		}
		return ret;
	}
*/
}


