
/**
 * $Id: gmap-min.js,v 1.11 2010/01/06 10:05:36 cs1559 Exp $
 * -----------------------------------------------------------------------------
 * 	2008 Copyright
 *  Firestorm Technologies, LLC  - ALL RIGHTS RESERVED
 * 
 *	THIS IS PROPRIETARY SOFTWARE.  COPYING, MODIFYING, REDISTRIBUTING OF THIS
 * 	CODE IS STRICTLY PROHIBITED WITHOUT THE EXPRESS WRITTEN CONSENT OF THE 
 * 	COPYRIGHT HOLDER (FIRESTORM TECHNOLOGIES, LLC).
 * -----------------------------------------------------------------------------
 */


// ======================================================================
// Category Overlay
// ======================================================================

fsCategory.prototype = new GOverlay();

fsCategory.prototype.initialize = function(map) {
	this.map_ = map;
	this.visible = true;
//	this.markers =  new Array();
	//alert('inside initialize');
	for (var i = 0; i < this.markers.length; i++) {
		var marker = this.markers[i];
		this.map_.addOverlay(marker);
	}	
};

fsCategory.prototype.remove = function() {
	for (var i = 0; i < this.markers.length; i++) {
		var marker = this.markers[i];
		marker.hide();
	}
};

fsCategory.prototype.copy = function() {
};

fsCategory.prototype.redraw = function() {
};

fsCategory.prototype.addMarker = function(marker) {
	if (this.markers === undefined) {
		this.markers = new Array();
	}
	this.markers.push(marker);
	//this.map_.addOverlay(marker);		
};

fsCategory.prototype.hide = function() {
	this.visible = false;
};

fsCategory.prototype.show = function() {
	this.visible = true;
};


// ======================================================================
// GMarker extended functions
// ======================================================================

GMarker.prototype.setCategories = function(cat) {
	this.fst_categories = cat;
};

GMarker.prototype.getCategories = function() {
	return this.fst_categories;
};

GMarker.prototype.setId = function(id) {
	this.fst_id = id;
};
GMarker.prototype.getId = function() {
	return this.fst_id;
};


// ======================================================================
// GPolyline extended functions
// ======================================================================

GPolyline.prototype.setCategories = function(cat) {
	this.fst_categories = cat;
};

GPolyline.prototype.getCategories = function() {
	return this.fst_categories;
};

GPolyline.prototype.setId = function(id) {
	this.fst_id = id;
};
GPolyline.prototype.getId = function() {
	return this.fst_id;
};
GPolyline.prototype.setDescription= function(desc) {
	this.fst_desc = desc;
};
GPolyline.prototype.getDescription = function() {
	return this.fst_desc;
};

GPolyline.prototype.getVertices = function() {
	var vertices = new Array();
	var cnt = this.getVertexCount();
	for (var i = 0; i < cnt; i++) {
	    	var pt = this.getVertex(i);
	    	vertices.push(pt);
    }
    return vertices;
};
// ======================================================================
// GPolygon extended functions
// ======================================================================

GPolygon.prototype.setCategories = function(cat) {
	this.fst_categories = cat;
};

GPolygon.prototype.getCategories = function() {
	return this.fst_categories;
};

GPolygon.prototype.setId = function(id) {
	this.fst_id = id;
};
GPolygon.prototype.getId = function() {
	return this.fst_id;
};
GPolygon.prototype.setDescription= function(desc) {
	this.fst_desc = desc;
};
GPolygon.prototype.getDescription = function() {
	return this.fst_desc;
};
// This function returns an array of GLatLng for all vertices in the polygon
GPolygon.prototype.getVertices = function() {
	var vertices = [];
	var cnt = this.getVertexCount();
	for (var i = 0; i < cnt; i++) {
	    	var pt = this.getVertex(i);
	    	vertices.push(pt);
    }
    return vertices;
};


// ======================================================================
// INITIALILZE VARIABLES
// ======================================================================
	var gmMaps = [];
	var Markers = [];
	var MarkersInfo = [];
	var mapBounds = [];
	
	// markerCategories is an array of markers by Categories
	var markerCategories= [];
	var showCategory = [];
	var processMaps = [];
	var fsSHOWMAPTYPE = 1;
	var fsADDLOCALSEARCH = 2;
	var fsADDMAPOVERVIEW = 3;
	var fsENABLEDOUBLECLICKZOOM = 4;
	var fsDISABLEDOUBLECLICKZOOM = 5;
	var fsLARGEZOOMTYPE = 6;
	var fsSMALLZOOMTYPE = 7;	
	var fsSATELLITEMAP = 8;
	var fsHYBRIDMAP = 9;
	var fsNORMALMAP = 10;
	var fsTERRAINMAP = 11;
	var fsSTREETOVERLAY = 12; 
	var fsGOOGLEBAR=13;
	var fsTRAFFICOVERLAY = 14;
	var fsPANORAMIO = 17;

	var jrequest = false;	
	var sidebarRequest = false;

	// variables for creating/editing Polygons
//	var polygon = null;
	var polygonPoints = [];


	/**
	 * ===============================================================================================
	 * 	The addMap function adds a numeric id to the 'processMaps' array.   The processMaps
	 * 	array contains a list of map id's to be used in rendering output.
	 * ===============================================================================================	 
	 */
	function addMap(id) {
		processMaps[processMaps.length] = id;
	};
	
	/**
	 * NOTE:  The GENMAPS function should enable a URL to be passed versus having it tied to gmapspro
	 */
	 
	/**
	 * ===============================================================================================	
	 *	The genMaps function is the map generation driver function.  It will loop through the
	 *	array of map ids that need to be rendered.
	 * ===============================================================================================
	 */ 
	function genMaps(mapurl,sidebarurl) {
		if (mapurl === undefined) {
			mapurl = 'index.php?option=com_gmapspro2&controller=maps&task=getmap&tmpl=component&format=raw';
		}	
		if (sidebarurl === undefined) {
			sidebarurl = 'index.php?option=com_gmapspro2&controller=maps&task=getsidebar&tmpl=component&format=raw';
		}	
		
		for (var i=0; i<processMaps.length; i++) {
			var mapid = processMaps[i];
			jQuery.ajax({
			    url: mapurl,
			    data: 'mapid=' + mapid,
			    type: 'GET',
			    dataType: 'script',
	    		error: function(){
	        		alert('Error retrieving map content');	    		
	        		jQuery("#googlemap_"+ mapid).html("Error retieving map - contact administrator");
	    		},
	    		success: function(data){
	    			eval(data);
	    		}	    		
			});			

			jQuery.ajax({
			    url: sidebarurl,
			    data: 'mapid=' + mapid,
			    type: 'GET',
	    		error: function(){
	        		alert('Error retrieving sidebar content');
	        		jQuery("#gmaps-sidebar_"+ mapid).html("Error retrieving sidebar content - contact administrator");
	    		},
	    		success: function(data){
	    			jQuery("#gmaps-sidebar").html(data);
	    		}
			});
		
		}	
	};


	/**
	 * ===============================================================================================	
	 *	Initialize Map
	 * ===============================================================================================	 
	 */
	function initMap(id,lat,lng,zoom, cursor1, cursor2) {
		if (cursor1 === undefined) {
			cursor1 = 'default';
		}
		if (cursor2 === undefined) {
			cursor2 = 'default';
		}
      	if (GBrowserIsCompatible()) {	
			var map = new GMap2(document.getElementById("googlemap_" + id),{			
				draggableCursor: cursor1,
				draggingCursor: cursor2
			});
			map.setCenter(new GLatLng(lat, lng), zoom);
			//map.setUIToDefault();
			gmMaps[id] = map;
			mapBounds[id] = map.getBounds();
		}
	};

	
	function addMapOption(id, feature) {
		switch (feature) {
			case fsSHOWMAPTYPE:
				gmMaps[id].addControl(new GMapTypeControl());
				break;
			case fsADDLOCALSEARCH:
				gmMaps[id].addControl(new google.maps.LocalSearch());
				break;
			case fsADDMAPOVERVIEW:
				gmMaps[id].addControl(new GOverviewMapControl());
				break;
			case fsENABLEDOUBLECLICKZOOM:
				gmMaps[id].enableDoubleClickZoom();
				break;
			case fsDISABLEDOUBLECLICKZOOM:
				gmMaps[id].disableDoubleClickZoom();
				break;
			case fsLARGEZOOMTYPE:
				gmMaps[id].addControl(new GLargeMapControl());
				break;
			case fsSMALLZOOMTYPE:
				gmMaps[id].addControl(new GSmallMapControl());
				break;		
			case fsSATELLITEMAP:
				gmMaps[id].addMapType(G_SATELLITE_MAP);
				gmMaps[id].setMapType(G_SATELLITE_MAP);				
				break;
			case fsHYBRIDMAP:
				gmMaps[id].addMapType(G_HYBRID_MAP);
				gmMaps[id].setMapType(G_HYBRID_MAP);				
				break;
			case fsNORMALMAP:
				gmMaps[id].addMapType(G_NORMAL_MAP);
				gmMaps[id].setMapType(G_NORMAL_MAP);				
				break;
			case fsTERRAINMAP:
				gmMaps[id].addMapType(G_PHYSICAL_MAP);
				gmMaps[id].setMapType(G_PHYSICAL_MAP);				
				break;
			case fsSTREETOVERLAY:
		        svOverlay = new GStreetviewOverlay();
		        gmMaps[id].addOverlay(svOverlay);
//	    	    var myPano = new GStreetviewPanorama(document.getElementById("pano"));
  //  	    	GEvent.addListener(map,"click", function(overlay,latlng) {
    //    			myPano.setLocationAndPOV(latlng);
		//	     });		        
				break;	
			case fsTRAFFICOVERLAY:
				gmMaps[id].addOverlay(new GTrafficOverlay());
				break;
			case fsGOOGLEBAR:
				gmMaps[id].enableGoogleBar();
				break;
			case fsPANORAMIO:
				var pano_layer = new PanoramioLayer(gmMaps[id]);
				pano_layer.enable();
				break;
		}
	};

	/**
	 * ===============================================================================================
		This function will specify the maps center
	 * ===============================================================================================		
	*/
	function setMapCenter(id,lat,lng,zoom) {
		gmMaps[id].setCenter(new GLatLng(lat,lng),zoom);
	};
 
	function fitBestZoom(mapid) {
		var map = gmMaps[mapid];
		var bounds = new GLatLngBounds;
		for (key in Markers) {
			marker = Markers[mapid,key];
			if (marker instanceof GMarker) {
				//latlng = marker.getLatLng();
    				//bounds.extend(new GPoint(latlng.lng(),latlng.lat()));
				bounds.extend(marker.getPoint());
			}
		}
  		map.setZoom(map.getBoundsZoomLevel(bounds)); 
	}

	/**	
	 * ===============================================================================================	
	 * 	The addMarker function will add a marker to a specific map.
	 * ===============================================================================================	 
	 */
	function addMarkerToMap(mapid, markerid, lat, lng, categories, options, userevent, tabs,html) {
		var map = gmMaps[mapid];
		var point = new GPoint( lng,lat);
		var marker	= new GMarker(point,options);
		marker.setCategories(categories);
		marker.setId(markerid);
		Markers[mapid, markerid] = marker;
		map.addOverlay(marker);
		// 05/09/09 - the following 3 lines are for Reef-one
//		bounds = map.getBounds();	
//		bounds.extend(marker.getPoint());
//		map.setZoom(map.getBoundsZoomLevel(bounds));	
		for (var i = 0; i < categories.length; i++) {
		    	addMarkerToCategory(mapid,categories[i],marker);
		}
		/*
			GEvent.addListener(mrkr, event, function() {openInfoWindow(mapid,id,true);});
			GEvent.addListener(mrkr, event, function() {openInfoWindow(mapid,id, false);});
		*/
		
		// Force defining a gmaps event.
		if (tabs) {
			GEvent.addListener(marker, userevent, function() {marker.openInfoWindowTabsHtml(html);});
			GEvent.addListener(marker, 'gmaps-event', function() {marker.openInfoWindowTabsHtml(html);});
		}
		else {
			GEvent.addListener(marker, userevent, function() {marker.openInfoWindowHtml(html);});
			GEvent.addListener(marker, 'gmaps-event', function() {marker.openInfoWindowHtml(html);});
		}
	} ;  
		 
	 //function addMarker(mapid, markerid, lat, lng) {    
	function addMarker(mapid, markerid, lat, lng, categories, options) {
		var map = gmMaps[mapid];
		var point = new GPoint( lng,lat);
		var marker	= new GMarker(point,options);
		marker.setCategories(categories);
		marker.setId(markerid);
		Markers[mapid, markerid] = marker;
		map.addOverlay(marker);
		// 05/09/09 - the following 3 lines are for Reef-one
		bounds = map.getBounds();	
		bounds.extend(marker.getPoint());
		map.setZoom(map.getBoundsZoomLevel(bounds));	
		for (var i = 0; i < categories.length; i++) {
		    	addMarkerToCategory(mapid,categories[i],marker);
		    }
	} ;       

	/**
	 * ===============================================================================================	
	 * This function adds a Polyline marker object to the map
	 * ===============================================================================================	 
	 */
	function addPolylineMarker(mapid,markerid, obj, categories, desc) {
		//addOverlay(mapid,obj);
		var map = gmMaps[mapid];
		obj.setCategories(categories);
		obj.setId(markerid);
		obj.setDescription(desc);
		Markers[mapid, markerid] = obj;
		map.addOverlay(obj);
		for (var i = 0; i < categories.length; i++) {
	    	addMarkerToCategory(mapid,categories[i],obj);
	    }
	};
	
	function addPolygonMarker(mapid, markerid,obj, categories,desc) {
		
		addPolylineMarker(mapid,markerid,obj,categories, desc);
	};
	
	
	function addMarkerToCategory(mapid,category, marker) {
		if (markerCategories[mapid] === undefined) {
			//markerCategories[mapid,category.catid] = Array();
			markerCategories[mapid] = Array();
		}
		if (markerCategories[mapid][category.catid] === undefined) {
			//markerCategories[mapid][category.catid] = new fsCategory();
			markerCategories[mapid][category.catid] = Array();	
		}
		if (showCategory[mapid] === undefined) {
			showCategory[mapid] = Array();
		}
		if (showCategory[mapid][category.catid] === undefined) {
			showCategory[mapid][category.catid] = Array();	
		}		
		showCategory[mapid][category.catid] = true;
		markerCategories[mapid][category.catid].push(marker);
	};

	function addCategoriesToMap(mapid) {
	    var  map = gmMaps[mapid];
	  	for ( var i in markerCategories[mapid]) {
	    	cat = markerCategories[mapid][i];
	    	if (cat === undefined) {
	    		alert('category error');
	    	} else {
	    		map.addOverlay(cat);
	    	}
	    }

	};
	
	/**
	 * ===============================================================================================	
	 * 
	 * ===============================================================================================	 
	 */
    function toggleGroup(mapid,type) {
    	var map = gmMaps[mapid];
   		// change current show status for category
   		if (showCategory[mapid][type] == true) {
   			showCategory[mapid][type] = false;
   		} else {
			showCategory[mapid][type] = true;        		
    	}
      	for (var i = 0; i < markerCategories[mapid][type].length; i++) {
        	var marker = markerCategories[mapid][type][i];
        	var categories = marker.getCategories();
        	// If we are turning it off, we need to check for other categories for the specific marker
        	if (showCategory[mapid][type] == false) {
        		// if the marker is only assigned to one category, the just go ahead and hide it 
	         	if (categories.length > 1) {
	        		// 	Iterate through the list of categories to see if this marker belongs to another 
	        		//	category that causes the marker to continue to be shown.
	        		var found = false;
			    	for (var x = 0; x < categories.length; x++) {
			    		if (showCategory[mapid][categories[x].catid] == true) {
			    			found = true;
			    		}
		    		}
		    		if (found == false) {
		    			marker.hide();
		    		}
		    	} else {
    	    	  marker.hide();
		        }
	        } else {
	        	// if the category is to be turned on, the marker will always be shown.
	        	marker.show();
	        }
		}
    };
    

	function toggleSidebar() {
		var el = document.getElementById("gmaps-sidebar-column");
		var e2 = document.getElementById("gmaps-sidebar");
		if ( el.style.display != 'none' ) {
			el.style.display = 'none';
		}
		else {
			el.style.display = '';
			//e1.style.width = '30%';
		}
		if ( e2.style.display != 'none' ) {
			e2.style.display = 'none';
			//e2.style.width = '0%';
		}
		else {
			e2.style.display = '';
			//e2.style.width = '30%';
		}

	};


	/**
		Add an object to the specified map
	*/
	function addOverlay(id,obj) {
		gmMaps[id].addOverlay(obj);
	};


	/**
	 * ===============================================================================================	
	 *	This function adds the marker information HTML to a marker
	 * ===============================================================================================	
	*/
	function addMarkerInfo(mapid,id,html) {  
		MarkersInfo[mapid,id] = html;
	};



	function addMarkerTabbedInfo(mapid,id,tabcode) {
		var infotab = tabcode;
		MarkersInfo[mapid,id] = infotab;
	};	


	function openInfoWindowByEvent(mapid,id,event) {
		if (Markers[mapid,id] instanceof GMarker) {
			mkr = Markers[mapid,id];
			GEvent.trigger(mkr,'gmaps-event');
		}
	}


	/**
	 * ===============================================================================================	
	 *  This function will open a markers information window.
	 * ===============================================================================================	 
	 */
	function openInfoWindow(mapid,id,usetabs) {
		openInfoWindowByEvent(mapid,id);
		return;
		
		if (Markers[mapid,id] instanceof GMarker) {
			if (usetabs == true) {     
				Markers[mapid,id].openInfoWindowTabsHtml(MarkersInfo[mapid,id],{maxwidth: 250});		
			} else {     
				html = MarkersInfo[mapid,id];
				if (typeof html == 'string') {
					html = html.replace(/&lt;/g,'<');
					html = html.replace(/&gt;/g,'>');
					html = html.replace(/&quot;/g,'"'); 
					Markers[mapid,id].openInfoWindowHtml(html);
				} else {
					Markers[mapid,id].openInfoWindowTabsHtml(MarkersInfo[mapid,id],{maxwidth: 250});
				}   
			}
			var map = gmMaps[mapid];
			map.setCenter(Markers[mapid,id].getPoint());
		}
	};		


	function addMarkerInfoWindowListener(mapid, id, event, tabs) {
		var mrkr = Markers[mapid,id];
		if (tabs)
			GEvent.addListener(mrkr, event, function() {openInfoWindow(mapid,id,true);});
		else
			GEvent.addListener(mrkr, event, function() {openInfoWindow(mapid,id, false);});
	};


	function addPolyEventListener(mapid, id, event, callback) {
		var mrkr = Markers[mapid,id];
		html = MarkersInfo[mapid,id];
		html = html.replace(/"/g,"'"); 
		GEvent.addListener(mrkr, 'click', function(overlaylatlng) {eval(callback +"(mapid,\"" + html + "\",overlaylatlng);");});
	}


	function showPolyInfoWindow(mapid,desc,latlng) {
		var map = gmMaps[mapid];
		map.openInfoWindowHtml(latlng, desc,{maxwidth: 250});
	}
	
	function addScriptLibrary(id, src) {
	   var head = document.getElementsByTagName("head")[0];
	   script = document.createElement('script');
	   script.id = id;
	   script.type = 'text/javascript';
	   script.src = src;
	   head.appendChild(script);
	};


function fsCategory() {
	this.markers = Array();
};






/**
 * ======================================S=========================================================
 *  MARKER EDITOR FUNCTIONS
 * ===============================================================================================
*/
	function drawPolygonOnMap(mapid, callback) {
     	var map = gmMaps[mapid];
     	var polygon1 = new GPolygon([], "#f33f00", 5, 1, "#ff0000", 0.2);
		map.addOverlay(polygon1);
     	polygon1.enableDrawing();
		GEvent.addListener(polygon1,'endline',function() {
			polygon1.disableEditing();
			callback(polygon1);
		});
		GEvent.addListener(polygon1,'cancelline',function() {
			disablePolygonDrawing(polygon1);
		});
		
	};
	

	function getArea(obj) {
		if (obj instanceof GPolygon) {
			alert(obj.getArea());
		} else {
			alert('Unable to obtain area');
		}
	};

	function drawPolylineOnMap(mapid, callback) {
     	var map = gmMaps[mapid];
     	var polyline1 = new GPolyline([], "#f33f00", 5, 1);
		map.addOverlay(polyline1);
     	polyline1.enableDrawing();
		GEvent.addListener(polyline1,'endline',function() {
			polyline1.disableEditing();
			callback(polyline1);
			
		});
		GEvent.addListener(polyline1,'cancelline',function() {
			alert('cancelline fired');
			disablePolylineDrawing(polyline1);
		});
		
	};
	
	
	function changeMarkerPosition(mapid,markerid,lat,lng) {
		var marker = Markers[mapid, markerid];
		var curPosition = marker.getPoint();
		var map = gmMaps[mapid];
		map.setCenter(marker.getPoint());
		lat.value = curPosition.lat();
		lng.value = curPosition.lng();
	};
	
	function clearEditorMap() {
		clearMap(0);
	};
	
	function createEditorMarker(lat,lng) {
		if (lat === undefined || lng === undefined) {
			var map = gmMaps[0];
			var pt = map.getCenter();
		} else {
			var pt = new GLatLng( lat, lng);
		}	
		addMarker(0,0,pt.lat(), pt.lng(),{},{draggable:true});
	};
	
	function clearMap(mapid) {
		var map = gmMaps[mapid];
		map.clearOverlays();
	};
	
	



