
//
// Add mark on click event
function AddMarkOnClick(mapObj)
{
		mapObj.map.getDragObject().setDraggableCursor("crosshair");

		
		return NewMarker = GEvent.addListener(mapObj.map, "click", function(overlay, latlng) {
			mapObj.map.getDragObject().setDraggableCursor("auto");
			mapObj.YesNoHide();

			mapObj.newPoint =createSimpleMarker(latlng, mapObj.pointTypes[0].icon, true);
			mapObj.map.addOverlay(mapObj.newPoint);
			GEvent.clearListeners(mapObj.map,  "click");
			GEvent.removeListener(NewMarker);
		});
		
}


//
// create simple marker
function createSimpleMarker(point, icono, editable) {
	var marker = new GMarker(point,  {title: '', icon: icono, draggable: editable, title: "Nuevo Punto" });

   	return marker;
}


//
// create click event marker
function createEventClickMarker(id, point, text, icono, action, parameter) {

	var marker = new GMarker(point,  {id: id, icon: icono, title: text });
		GEvent.addDomListener(marker, "click", function() {
			action(parameter)
			});
   	return marker;
}
//
// create event hover marker
function createEventMarker(id, point, text, icono, eventMarker, eventOut) {
	var marker = new GMarker(point,  {id: id, icon: icono, title: text });
		GEvent.addDomListener(marker, "mouseover", function() {
			eventMarker(marker.id)
			});
		GEvent.addDomListener(marker, "mouseout", function() {
			eventOut(marker.id)
			});
   	return marker;
}


//
// Create custom Map Marker
function createCustomMarker(mapObject, pointId, point, label, urlsrc, height, icono, editable) {
	// if browser is opera we must use normal globe
	if (/Opera[\/\s](\d+\.\d+)/.test(navigator.userAgent)){
		return createMarker(mapObject, pointId, point, label, urlsrc, height, icono, editable)
	}

	var marker = new GMarker( point, icono);

	GEvent.addListener(marker, 'click', function(){
    	marker.openExtInfoWindow(
              mapObject.map,
              "bublemap",
              "<div id='globeContent" + pointId + "' style='width:340px;height:"+ height +"px;'><br><br><br><br><center><img src='Templates/images/loading-24.gif'/></center></div>",
              {beakOffset: 5}
        );
		new PeriodicalExecuter(function(pe) {
						new Ajax.Updater( 'globeContent' + pointId, decodeURIComponent(urlsrc), {
							  method: 'get'
						});
						pe.stop();
		}.bind(this) , 0.8);	
	});



    GEvent.addListener(marker,"mouseover", function() {
    	mapObject.showTooltip(marker, label);
      }.bind(this));            
    GEvent.addListener(marker,"mouseout", function() {
    	mapObject.showTooltip(false);
      }.bind(this));            	
	
	GEvent.addListener(marker, "drag", function() {

	mapObject.PointTmpAdd(marker.getTitle(), marker.getPoint())
		
	});

   	return marker;
}

//
// Create Map Marker
function createMarker(mapObject, pointId, point, label, urlsrc, height, icono, editable) {

	var marker = new GMarker(point,  {title: label, icon: icono, draggable: editable });

	
    GEvent.addListener(marker, "click", function() {
    	marker.openInfoWindowHtml("<div id='globeContent" + pointId + "' style='width:300px;height:"+ height +"px;'><br><br><br><br><center><img src='Templates/images/loading-24.gif'/></center></div>",{width:500});
		GEvent.addListener(marker, "infowindowopen", function() {
				//mapObject.map.setCenter(point);
				new PeriodicalExecuter(function(pe) {
						new Ajax.Updater( 'globeContent' + pointId, decodeURIComponent(urlsrc), {
							  method: 'get'
						});
						pe.stop();
				}.bind(this) , 0.8);	
		});
    });
	GEvent.addListener(marker, "drag", function() {

	mapObject.PointTmpAdd(marker.getTitle(), marker.getPoint())
		
	});
	
   	return marker;
}

var markers = null;

//
// Get Xml Data
//function getXMLData(map, dataXML, markerTypes){
function getXMLData(mapObject, dataXML){
		
		// show loading dialog
		//mapObject.DescShow('<h3>Cargando Datos<br><br> <img src="Templates/Script/lib/MapClasses/img/miniloading.gif" border=0></h3>');
		
		GDownloadUrl(dataXML, function(doc)
		{
	      var xmlDoc = GXml.parse(doc);
		  markers = xmlDoc.documentElement.getElementsByTagName("marker");
		  
		  mapObject.xmlMarkers = markers;
		  mapObject.DrawPoints(mapObject.draggableIcons, true);
		  
		  // Hide loading dialog
		  //mapObject.DescHide();
		  
		  
		});
}




//
// Map Class
// (Fungo's main Map)
//
var Map = Class.create
({
	initialize: function(id, dataXML, position, zoomLevel, controls, mapType, pointTypes , mode) 
	{
		this.id = id;
		this.dataXML = dataXML;
		
		

		this.zoomLevel = zoomLevel;
		this.zoomLevelMax = false;
		this.zoomLevelMin = false;

		
		this.controls = controls;
		this.mapType = mapType;
		this.setPosition(position[0], position[1]);
		this.position = new GLatLng(this.positionX, this.positionY);
		if (pointTypes == null)
			this.pointTypes = Array()
		else
			this.pointTypes = pointTypes;

		this.draggableIcons = false;

		this.newPoint = null;
		
		this.pointsTMP = Array();
		this.points = Array();
		
		if (GBrowserIsCompatible()) {
	        this.map = new GMap2(document.getElementById(this.id));
	        this.map.setCenter(this.position , this.zoomLevel);
	    }
		else
		{
			alert('Google Maps incompatible Browser');
		}
		
		// icon hover tooltip
		maptooltip = document.createElement('div');
		Element.extend(maptooltip);
		maptooltip.addClassName('maptooltip');		
		
		if(this.controls != 0)
			this.showControls();
		
		this.map.enableScrollWheelZoom();
		
		// Markers Manager
		this.markermanager = new GMarkerManager(this.map);
		
		
		// Zoom listener
		this.startZoomListener();

		this.map.enableContinuousZoom();
		
		GEvent.addListener(this.map, "extinfowindowclose", function() {
			allowhover();
		});
		
	},
	
	setPosition: function(positionX, positionY)
	{
		this.positionX=positionX;
		this.positionY=positionY;
		this.position = new GLatLng(this.positionX, this.positionY);

	}
	,
	//
	// show zoom and position controls;
	//
	showControls: function()
	{

		if( this.controls == 1 ) // only map type selector
		{
			this.map.addControl(new GMapTypeControl());
		}
		else
		if ( this.controls == 2 ) // only movement&zoom controls
		{
			this.map.addControl(new GLargeMapControl());
		}
		else
		if (this.controls == 3) // all controls
		{
			this.map.addControl(new GMapTypeControl());
			this.map.addControl(new GLargeMapControl());
		}
		
	},
	
	
	
	//
	// Add Map type
	AddMapType: function(tileLayer, maptype_name)
	{
		
		var maptype = new GMapType(tileLayer, G_SATELLITE_MAP.getProjection(), maptype_name ) ;
		this.map.addMapType(maptype);
		
		//this.map.setMapType(maptype);
		return maptype;
		// this.map.setCenter(this.position , 19, maptype);

		
	},
	
	//
	//	change map type (on gmaps [satellite, atlas, ..])
	//
	changeMapType: function(mapType)
	{
		this.mapType = mapType;
		this.map.setMapType(this.mapType);
		//..
		//this.refresh();
		
	},
	
	refresh: function ()
	{
		this.zoomSet(  this.zoomLevel)
		this.map.panTo(this.position);
		//this.map.setCenter(this.position, this.zoomLevel);
	},
	
	

	
	//
	// create dialog boxes
	//
	CreateDialogBoxes: function()
	{
		//
		// Description box
		
		this.fatherMapDIV = document.getElementById( this.id );
		this.descbox = document.createElement('div');
		this.descbox.id = this.id+"Description";
		this.descbox.style.position ='absolute';
		this.descbox.innerHTML = "";
		this.descbox.style.backgroundColor = "white";
		this.descbox.style.font = "small Arial";
		this.descbox.style.opacity =".75";
		this.descbox.style.border="1px solid black";
		this.descbox.style.textAlign = "center";
		//this.descbox.style.width = "100px";
		this.descbox.style.padding = "30px";
		this.descbox.style.paddingTop = "10px";
		this.descbox.style.paddingBottom = "10px";
		this.descbox.style.top = "50px";
		this.descbox.style.left = "50px";
		this.fatherMapDIV.appendChild(this.descbox);
		
		Element.hide(this.descbox);
		
		//
		// Yes/No Box
		this.fatherMapDIV = document.getElementById( this.id );
		this.yesnoBox = document.createElement('div');
		this.yesnoBox.id = this.id+"YesNo";
		this.yesnoBox.style.position ='absolute';
		this.yesnoBox.innerHTML = "";
		this.yesnoBox.style.backgroundColor = "white";
		this.yesnoBox.style.font = "small Arial";
		this.yesnoBox.style.opacity =".75";
		this.yesnoBox.style.border="1px solid black";
		this.yesnoBox.style.textAlign = "left";
		this.yesnoBox.style.width = "300px";
		this.yesnoBox.style.paddingLeft = "10px";
		this.yesnoBox.style.paddingTop = "10px";
		this.yesnoBox.style.paddingBottom = "10px";
		this.yesnoBox.style.top = "10px";
		this.yesnoBox.style.left = "300px";
		this.fatherMapDIV.appendChild(this.yesnoBox);
		
		
		Element.hide(this.yesnoBox);

	},
	
	//
	// Load Points from XML Source
	LoadPoints: function()
	{
		this.xmlMarkers = null;		
		getXMLData(this , this.dataXML);		
	},

	
	// Add NEw point on map
	NewPoint: function()
	{
		this.newPointEvent = AddMarkOnClick(this);
	},
	
	// Stop new point event
	StopNewPoint: function()
	{
		if(this.newPointEvent)
		{
			this.map.getDragObject().setDraggableCursor("auto");
			GEvent.clearListeners(this.map,  "click");
			GEvent.removeListener(this.newPointEvent);
		}
	},
	
	//
	// Draw points from points array
	// @fr < is first read from xml
	DrawPoints: function(isDragable, fr)
	{
		this.ErasePoints();
		
		if (fr == true)
			this.points = Array();
		
        
		//this.points.icon;
		for (var i = 0; i < this.xmlMarkers.length; i++)
		{
			if (fr == true)
			{
				this.points[i] = Array();
				
				// obtain the attribues of each marker
				this.points[i]['lat']  = parseFloat(this.xmlMarkers[i].getAttribute("lat"));
				this.points[i]['lng'] = parseFloat(this.xmlMarkers[i].getAttribute("lng"));
				this.points[i]['point'] = new GLatLng(this.points[i]['lat'], this.points[i]['lng']);
				this.points[i]['html'] = this.xmlMarkers[i].getAttribute("html");
				this.points[i]['label'] = this.xmlMarkers[i].getAttribute("labelo");
				this.points[i]['urlsrc'] = this.xmlMarkers[i].getAttribute("urlsrc");
				this.points[i]['type'] = this.xmlMarkers[i].getAttribute("type");
				this.points[i]['id'] = this.xmlMarkers[i].getAttribute("id");
				this.points[i]['height'] = this.xmlMarkers[i].getAttribute("height");
			}
			
						
			//alert(this.points.icon.image);
			// create the marker
	
			this.points[i]['marker'] = createCustomMarker(	this,
														this.points[i]['id'] ,
														this.points[i]['point'], 
														this.points[i]['label'],
														this.points[i]['urlsrc'],
														this.points[i]['height'],
														this.pointTypes[this.points[i]['type']].icon, null);
				        
			// draw the point
			this.map.addOverlay(this.points[i]['marker']);		
		}
		
		
		
		// If openonload is defined click it
		if (typeof this.openOnloadID != "undefined")
			this.PointAction(this.openOnloadID, "click");
		
	},
	
	//
	//	show icons tooltip
	//
	showTooltip: function (marker, text) {
      	
		if(marker != false)
		{
			var point=this.map.getCurrentMapType().getProjection().fromLatLngToPixel(this.map.getBounds().getSouthWest(),this.map.getZoom());
			var offset=this.map.getCurrentMapType().getProjection().fromLatLngToPixel(marker.getPoint(),this.map.getZoom());
			var anchor=marker.getIcon().iconAnchor;
			var width=marker.getIcon().iconSize.width;
			var pos = new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(offset.x - point.x - anchor.x + width,- offset.y + point.y +anchor.y)); 
			pos.apply(maptooltip);
	
			maptooltip.innerHTML=text;
			document.body.appendChild(maptooltip);
			
			maptooltip.show();
		}
		else
			maptooltip.hide();
    },

	// open map point wen load is finished
	OpenOnload: function(id)
	{
		this.openOnloadID = id;
	},
	
	//
	// trigger for click event ( simulate an click event )
	//
	PointAction: function(pointID, action)
	{ 
		var point = this.GetPointbyID(pointID); 		
		GEvent.trigger(point['marker'], action);
	},
	
	
	//
	// Add temporal marker
	//
	PointTmpAdd: function(pointID, situation)
	{	
		this.pointsTMP[pointID] = Array();
		this.pointsTMP[pointID]['id'] = pointID;
		this.pointsTMP[pointID]['point'] = situation;
	},
	
	
	//
	//	Save temporal points
	//	
	SaveTmpPoints: function()
	{
		// Save into points Array
		for(var c=0;c<=this.points.length; c++)
		{
			if (this.points[c]) {
				if (this.pointsTMP[this.points[c]['id']])
				{
					//alert(this.points[c]['id']);
					//alert(this.points[c]['point']);
					this.points[c]['point'] = this.pointsTMP[ this.points[c]['id'] ]['point'];


					//alert(this.points[c]['point']);
				//	alert(this.points[c]['point'] );
					//alert(this.pointsTMP[ this.points[c]['id'] ]['point']);
				}
			}
		}

		
		// Erase temporal points
		this.EraseTmpPoints();
	},

	//
	// Erase Temporal points	
	EraseTmpPoints: function()
	{
		this.pointsTMP = Array();
	},
	
	
	
	//
	// search point by ref
	//
	GetPointbyID: function(refPoint)
	{ 
		for(var i =0; i< this.points.length; i++ )
		{
	
			if(refPoint == this.points[i]['id'] ){
				return this.points[i];				
			}
		}		
		return null;
	},
	
	//
	// Erase all points
	ErasePoints: function()
	{
		this.map.clearOverlays();
	},
	
	//
	// Increments zoom
	zoomIn: function()
	{
		this.map.zoomIn();
		this.zoomLevel = this.map.getZoom();
	},
	
	//
	// Decrements zoom
	zoomOut: function()
	{
		this.map.zoomOut();
		this.zoomLevel = this.map.getZoom();
	},
	
	//
	// zoom Set
	zoomSet: function(zoom) {
		if (zoom != this.zoomLevel) {
			this.map.setZoom(zoom);
			this.zoomLevel = this.map.getZoom();
		}
	},
	
	//
	// Set zoom listeners
	startZoomListener: function() {
		
		GEvent.addListener(this.map,"zoomend", function(oldLevel, newLevel)
		{
			if (oldLevel != newLevel) {
				this.zoomLevel = this.map.getZoom();
				if (this.zoomLevelMax != false && newLevel > this.zoomLevelMax) 
					this.zoomSet(this.zoomLevelMax);
				if (this.zoomLevelMin != false && newLevel < this.zoomLevelMin) 
					this.zoomSet(this.zoomLevelMin);
			}

		}.bind(this));
	},
	
	//
	// Set zoom max and min limits
	zoomSetLimits: function(zMin, zMax) {
		
		this.zoomLevelMax = zMax;
		this.zoomLevelMin = zMin;
	},
	
	////////////////////////////////////////
	////////////////////////////////////////
	//////////////// Eventos de Botones
	
	
	DescShow: function(desc)
	{
		Element.show(this.descbox);
		this.descbox.innerHTML = ""+desc+"";
	},
	
	DescHide: function(desc)
	{
		Element.hide(this.descbox);
		this.descbox.innerHTML = "";
	},
	
	YesNoShow: function(comment, yesBtnID, noBtnID)
	{

		if (yesBtnID == null){
			if (noBtnID == null)
				this.yesnoBox.innerHTML = "<p>"+comment+"</p>";
			else
				this.yesnoBox.innerHTML = "<p>"+comment+"</p><input type='button' id='"+noBtnID+"'  value='Cancelar'>";
		}
		else
			this.yesnoBox.innerHTML = "<p>"+comment+"</p><input type='button' id='"+noBtnID+"'  value='Cancelar'><input type='button' id='"+yesBtnID+"'  value='Aceptar'>";
		Element.show(this.yesnoBox);

	},
	
	YesNoHide: function()
	{
		Element.hide(this.yesnoBox);
		this.yesnoBox.innerHTML = "";
	}
	
	
});
