var mapTooltipTemplate = '<div class="apartment-map-search-tt-small"><div class="tt-top-sml"><div class="community-name"><a href="#" class="name_field name_field@title" title="title"></a><span class="apartment-community">{prop_type}</span></div><div class="close-button"><a href="#" title="Close" id="close_balloon"></a></div></div><div class="tt-mid-sml"><div class="map-tip-info"><div class="apartment-photo-thumb"><div class="photo-top"></div><div class="photo-mid"><img class="front-jpeg@src" src="test" alt="apartment community name" /></div><div class="photo-bot"></div></div><div class="rent-range"><span class="amount"></span><span class="small-title">rent range</span></div><ul class="unit-result-flare"><li class="flare-community"><a class="comm-link@href" href="#">View {prop_type}</a></li><li class="flare-fp2dc"><a href="#">Color Floor Plans</a></li></ul></div><div class="map-tip-links"><div class="apartment-community-address"></div><span class="btn-view-unit"><a class="comm-link@href" href="#" title="View this {display_text}">Go to {display_text}</a></span></div></div><div class="tt-btm-sml"></div></div>';

var mapUnavailTemplate = 'There are no apartments that match your search criteria in this community.';
var mapSingularAvailTemplate = 'There is <span class="highlighted">1</span> apartment that matches your search criteria in this community.';
var mapPluralAvailTemplate = $('<div>There are <span class="highlighted"></span> apartments that match your search criteria in this community.</div>').get(0);

var mflMap;
var showCircle = true;
var circleOverlay;
var drawnRadius = 0;	// the radius of the circle currently being displayed
var ringOpacity = 0.2;

function MFLMap() {
	this.initialize();
	//this.loadNeighborhoods();
	//this.loadGPX();
}

MFLMap.prototype.initialize = function() {
	if (GBrowserIsCompatible()) {
		
		if (typeof(dataArray['radius']) == 'undefined')
			return;
		
		var numComms = 0;
		
		this.curMarkers = [];
		this.valid = true;
		this.overlays = [];
		this.ringPoints = 40;
		
		this.map = new GMap2(document.getElementById("apartment-search-map"));
		
		this.map.setUIToDefault();
		this.map.disableScrollWheelZoom();

		// Initialize Icon
			
		this.houseIcon = new GIcon(G_DEFAULT_ICON);
		this.houseIcon.image = "/images/icon-apt-green.png";
		this.houseIcon.shadow = "/images/icon-apt-shdw.png";
		this.houseIcon.iconSize = new GSize(24,30);
		this.houseIcon.shadowSize = new GSize(40,30);
		this.houseIcon.iconAnchor = new GPoint(12,30);
				
		this.pinIcon = new GIcon(G_DEFAULT_ICON);
		this.pinIcon.image = "/images/icon-pin.png";
		this.pinIcon.shadow = "/images/icon-pin-shdw.png";
		this.pinIcon.iconSize = new GSize(13,47);
		this.pinIcon.shadowSize = new GSize(34,45);
		this.pinIcon.iconAnchor = new GPoint(7,47);
		
		var curPoint;
		var bounds = new GLatLngBounds();
		
		// cache values for sin,cos
		var twopiOverPoints = 2*Math.PI/this.ringPoints;
		this.sinVals = [];
		this.cosVals = [];
		for (point=0; point <= this.ringPoints; point++) {
			this.sinVals[point] = Math.sin(point*twopiOverPoints);
			this.cosVals[point] = Math.cos(point*twopiOverPoints);	
		}
		
		$.each(commsArray, function(item) {
			var itemData = commsArray[item];
			if (itemData['lat'] == null || itemData['lng'] == null) return;
			numComms++;
		});
		
		var markerOptions = {
			icon : this.pinIcon
		};	
	
		var centerPoint = new GLatLng(dataArray['search_lat'], dataArray['search_lng']);
		this.pinMarker = (new GMarker(centerPoint, markerOptions));
		
		
		GEvent.addListener(this.map, "click", function(marker, point) {
			if (!marker) {
				closeBalloon();
				this.enableDoubleClickZoom();
			}
		});
		if (!numComms)
			this.drawSearchRadius();
		else {
			var centerLat = parseFloat(dataArray['search_lat']);
			var centerLng = parseFloat(dataArray['search_lng']);
			this.map.setCenter(new GLatLng(centerLat,centerLng));
		}
		//loadgpx();
	}	
}

MFLMap.prototype.clearMarkers = function() {
	if (this.curMarkers) {
		for (var i in this.curMarkers) {
			this.map.removeOverlay(this.curMarkers[i]);
			delete this.curMarkers[i];
		}
		this.curMarkers = [];
	}	
}

MFLMap.prototype.loadMarkers = function(idList) {
	var map = this.map;
	var icon = this.houseIcon;
	var commIndex;
	var numActive = 0;
	
	var bounds = new GLatLngBounds();
	
	closeBalloon();
	
	this.clearMarkers();
	
	$this = this;
	
	showCircle = (commsArray.length == 0);
		
	this.drawSearchRadius();
	$("#apartment-search-results").show();
	
	$.each(commsArray, function(commID) {
		
		if (typeof(idList) != 'undefined' && $.inArray(commID, idList) == -1) return;
		
		var itemData = commsArray[commID];
		if (itemData['lat'] == null || itemData['lng'] == null) return;
		var distance =  Math.round(parseFloat(itemData['d'])*10)/10;
		var markerOptions = {
			icon : icon,
			title : itemData['name'] + ' (' + distance + ' miles)'
		};	
		var point = new GLatLng(parseFloat(itemData['lat']), parseFloat(itemData['lng']));
		var marker = (new GMarker(point, markerOptions));
		bounds.extend(point);
		numActive++;
		$this.curMarkers.push(marker);
		GEvent.addListener(marker, "click", function() {
			$("div.apartment-map-search-tt-small").remove();

			var low;
			var high;
			var rent;
			var rentHigh;
			var numMatches = commsArray[commID]['num_avail'];
			
			low = commsArray[commID]['rent'];
			high = commsArray[commID]['renthigh'];
				
			if (numMatches == 1) {
				var availText = mapSingularAvailTemplate;
			} else if (numMatches == 0) {
				var availText = mapUnavailTemplate;
			}
			else {
				var availData = {
					"highlighted" : numMatches	
				}
				var availText = pure.autoRender(mapPluralAvailTemplate, availData);	
			}
	
			if (low == 0 || low == null) rent = 'Call for details';
			else rent = (low == high) ? '$' + low : '$' + low + ' - $' + high;
	
			var comm_link = (homesMode) ? '/homes/rentals/' : '/apartments/community/'
	
			var data = {
				"name_field" : itemData['name'],
				"amount" : rent,
				"apartment-community-address" : itemData['address'] + '<br />' + itemData['city'] + ', ' + itemData['state'] + ' ' + itemData['zip'],
				"avail-text" : availText,
				"front-jpeg" : '/files' + commsArray[commID]['front_jpeg'],
				"comm-link" : comm_link + commID + '.html'
			};
	
			var colorFp = itemData['commassets']['fp2dc'];
	
			//var finalTemplate = mapTooltipTemplate;
	
			var finalTemplate = mapTooltipTemplate.replace(/{prop_type}/g, (homesMode) ? 'Home' : 'Apartment Community');
			var finalTemplate = finalTemplate.replace(/{display_text}/g, (homesMode) ? 'home' : 'apartment');
	
			var html = pure.autoRender($(finalTemplate).get(0), data);

			var div = $(html).get(0);
			// prevent clicks on the balloon from closing it
			$(div).mousedown(function(e) {	
				if (window.event)
					window.event.cancelBubble = true;
				else e.stopPropagation();
				return false;
			});
			
			mflMap.map.getPane(G_MAP_FLOAT_PANE).appendChild(div);
			
			$("#show_results").click(function() {
				curComm = commID;
				$("#page_0").click();
				return false;
			});
			$("#close_balloon").click(closeBalloon);
			
			mflMap.positionBalloon(marker, div);
			mflMap.map.disableDoubleClickZoom();
				
		});
		$this.map.addOverlay(marker);
	});
	
	if (!numActive) {
		//delete this.map;
		this.valid = false;
		//$("#apartment-search-map").hide();
	}
	else {
		if (!this.valid) {
			$("#apartment-search-map").show();
			this.valid = true;
		}
		$("div.apartment-search-results").show();
		zoom = this.map.getBoundsZoomLevel(bounds);
		this.map.setCenter(bounds.getCenter(), zoom-1);
	}
}

MFLMap.prototype.loadNeighborhoods = function(idList) {
	var map = this.map;
	var icon = this.houseIcon;
	var commIndex;
	
	
	
	$this = this;
	
	for (var n in dataArray['neighborhoods']) {
		
		//$.each(commsArray, function(commID) {
		
		var markerOptions = {
			title: dataArray['neighborhoods'][n]['n']
		};	
		var point = new GLatLng(parseFloat(parseFloat(dataArray['neighborhoods'][n]['lat'])), parseFloat(dataArray['neighborhoods'][n]['lng']));
		var marker = (new GMarker(point, markerOptions));
		
		this.map.addOverlay(marker);
	}
}

MFLMap.prototype.loadGPX = function() {
	var request = GXmlHttp.create();

	if (typeof(dataArray['neighborhoods_file']) == 'undefined') return;

	

	request.open("GET", '/js/neighborhoods/city_' + dataArray['neighborhoods_file'] + '.gpx', true);
	
	var $map = this.map;
	
	request.onreadystatechange = function() {
		var color = "#ff0000";
	  if (request.readyState == 4) {
			var xmlDoc = request.responseXML;
			//alert(request.responseText);
			if( !xmlDoc ) {
				alert("Could not load GPX document ");
			} else {
				//
				//	Parse document boundaries in <bounds>.  Open map.  Guess at zoom level.
				//
				/*
				var bounds = xmlDoc.documentElement.getElementsByTagName("bounds");
				minlat = parseFloat(bounds[0].getAttribute("minlat"));
				minlon = parseFloat(bounds[0].getAttribute("minlon"));
				maxlat = parseFloat(bounds[0].getAttribute("maxlat"));
				maxlon = parseFloat(bounds[0].getAttribute("maxlon"));
	
				zoomlat		= minlat+(maxlat-minlat)/2;
				zoomlon		= minlon+(maxlon-minlon)/2;
				zoomlevel	= 7;
				//map.setCenter(new GLatLng(zoomlon,zoomlat));
	
				bounds = [];
				*/
				//	Parse routes in <rte></rte>
				//
				var rte;
				if (rte == xmlDoc.documentElement.getElementsByTagName("rte") ) {
					points = [];
					//console.log(rte.length);
					for (var i = 0; i < rte.length; i++) {
						
						var cmt = $(rte[i]).find('cmt').text();
						
						
						if (cmt == "Mission Bay") {
							a = 32;	
						}
						
						//tstatus = rte[i].getAttribute("color");
						twidth  = 1;
						
	
						var rtept = rte[i].getElementsByTagName("rtept");
						for (var k = 0; k < rtept.length; k++) {
							points.push(new GPoint(parseFloat(rtept[k].getAttribute("lon")),
												   parseFloat(rtept[k].getAttribute("lat"))));
							}
							
							//var marker = new GMarker(points[0], options);	
							nPoly($map, cmt, points);
							//map.addOverlay(marker);
							points = [];
						//if (i > 10) break;
					}
					
					rte = [];
				}
			} // xmlDoc
		} // readyState
	} // function
	request.send(null);
}



function nPoly(map, name, points) {
	var p = new GPolygon(points, "#aa0000", 1, 1, "#0000aa", 0.5);
	
	GEvent.addListener(p, 'click', function(latlng) {
		map.openInfoWindow(latlng,name);
	});
	map.addOverlay(p);
}

MFLMap.prototype.drawSearchRadius = function() {
	var searchRadius = parseFloat(dataArray['radius']);
	if ((searchRadius == drawnRadius) && showCircle) return;
	drawnRadius = searchRadius;
	
	if (this.overlays.length) {
		for (var i in this.overlays) {
			this.map.removeOverlay(this.overlays[i]);
		}
		this.overlays = [];
		this.map.removeOverlay(this.pinMarker);
	}
		

	if (!showCircle) {
		drawnRadius = 0;
		//return;
	}
	
	var radius = searchRadius/69;
	var bounds = new GLatLngBounds();
	var centerLat = parseFloat(dataArray['search_lat']);
	var centerLng = parseFloat(dataArray['search_lng']);
	
	var centerPoint = new GLatLng(centerLat, centerLng);
	var offsetPoint = new GLatLng(centerLat, centerLng+1);
	
	var d = centerPoint.distanceFrom(offsetPoint)/1609.344;
	
	// calculate distance of one longitude line at this latitude
	var proportion = searchRadius/d;

	var numPoints = 4;
	var lat, lng;
	
	var points = [];
	var pointObj;
	
	// calculate the boundaries of the search radius
	for (var point=0; point <= this.ringPoints; point += 10) {
		lat = centerLat + this.sinVals[point]*radius;
		lng = centerLng + this.cosVals[point]*proportion;
		pointObj = new GLatLng(lat, lng);
		bounds.extend(pointObj);
		points[point] = pointObj;
	}
	
	this.drawRing(centerLat, centerLng, searchRadius*0.79625, searchRadius);
	this.drawRing(centerLat, centerLng, searchRadius*0.51, searchRadius*0.70625);
	this.drawRing(centerLat, centerLng, searchRadius*0.2325, searchRadius*0.4175);
	this.drawCircle(centerLat, centerLng, searchRadius*0.14125);
	
	this.map.addOverlay(this.pinMarker);
	
	var zoom = this.map.getBoundsZoomLevel(bounds);
	this.map.setCenter(bounds.getCenter(), zoom);
}


MFLMap.prototype.drawRing = function(centerLat, centerLng, inner, outer) {
	var lat, lng;
	var points = [];
	var linePoints = [];
	var ringPoints = [];
	var pointObj;
	
	var innerRadius = inner/69;
	var outerRadius = outer/69;
	
	var centerPoint = new GLatLng(centerLat, centerLng);
	var offsetPoint = new GLatLng(centerLat, centerLng+1);
	
	var d = centerPoint.distanceFrom(offsetPoint)/1609.344;
	
	// calculate distance of one longitude line at this latitude
	var innerProp = innerRadius*69/d;
	var outerProp = outerRadius*69/d;

	var sinVals = [];
	var cosVals = [];

	for (var point=0; point <= this.ringPoints; point++) {
		lat = centerLat + this.sinVals[point]*innerRadius;
		lng = centerLng + this.cosVals[point]*innerProp;
		pointObj = new GLatLng(lat, lng);
		points[point] = pointObj;
		linePoints[point] = pointObj;
	}

	var lineOverlay = new GPolyline(linePoints, "#005500", 4, ringOpacity);
	this.map.addOverlay(lineOverlay);
	this.overlays.push(lineOverlay);

	for (var point=this.ringPoints; point >=0; point--) {
		lat = centerLat + this.sinVals[point]*outerRadius;
		lng = centerLng + this.cosVals[point]*outerProp;
		pointObj = new GLatLng(lat, lng);
		points[point + this.ringPoints + 1] = pointObj;
		linePoints[point] = pointObj;
	}
	
	var lineOverlay2 = new GPolyline(linePoints, "#005500", 4, ringOpacity);
	this.map.addOverlay(lineOverlay2);
	this.overlays.push(lineOverlay2);
	
	// draw solid rings
	
	var half = this.ringPoints/2;
	
	for (var point=0; point <= half; point++) {
		lat = centerLat + this.sinVals[point]*outerRadius;
		lng = centerLng + this.cosVals[point]*outerProp;
		pointObj = new GLatLng(lat, lng);
		ringPoints[point] = pointObj;
	}
	
	for (var point=half; point >= 0; point--) {
		lat = centerLat + this.sinVals[point]*innerRadius;
		lng = centerLng + this.cosVals[point]*innerProp;
		pointObj = new GLatLng(lat, lng);
		ringPoints[this.ringPoints - point + 1] = pointObj;
	}
	
	ringOverlay = new GPolygon(ringPoints, "#880000", 0, ringOpacity, "#5ed835", ringOpacity);
	this.map.addOverlay(ringOverlay);
	this.overlays.push(ringOverlay);
	
	for (var point=half; point <= this.ringPoints; point++) {
		lat = centerLat + this.sinVals[point]*outerRadius;
		lng = centerLng + this.cosVals[point]*outerProp;
		pointObj = new GLatLng(lat, lng);
		ringPoints[point] = pointObj;
	}
	
	for (var point=this.ringPoints; point >= half; point--) {
		lat = centerLat + this.sinVals[point]*innerRadius;
		lng = centerLng + this.cosVals[point]*innerProp;
		pointObj = new GLatLng(lat, lng);
		ringPoints[this.ringPoints - point -1] = pointObj;
	}
	
	ringOverlay = new GPolygon(ringPoints, "#880000", 0, ringOpacity, "#5ed835", ringOpacity);
	this.map.addOverlay(ringOverlay);
	this.overlays.push(ringOverlay);
	
	//var boundaries = new GLatLngBounds(new GLatLng(centerLat - 0.011, centerLng + innerRadius), new GLatLng(centerLat + 0.011, centerLng + innerRadius + 0.03));
	//var numberOverlay = new GGroundOverlay("/number.php?n=" + inner, boundaries);
	//this.map.addOverlay(numberOverlay);
	
}

MFLMap.prototype.drawCircle = function(centerLat, centerLng, radius) {
	var lat, lng;
	
	var points = [];
	var pointObj;
	
	var outerRadius = radius/69;
	
	var centerPoint = new GLatLng(centerLat, centerLng);
	var offsetPoint = new GLatLng(centerLat, centerLng+1);
	
	var d = centerPoint.distanceFrom(offsetPoint)/1609.344;
	
	// calculate distance of one longitude line at this latitude
	var prop = outerRadius*69/d;
	
	for (var point=this.ringPoints; point >= 0; point--) {
		lat = centerLat + this.sinVals[point]*outerRadius;
		lng = centerLng + this.cosVals[point]*prop;
		pointObj = new GLatLng(lat, lng);
		points[point] = pointObj;
	}
	
	var lineOverlay = new GPolyline(points, "#005500", 4, ringOpacity );
	this.map.addOverlay(lineOverlay);
	this.overlays.push(lineOverlay);
	
	ringOverlay = new GPolygon(points, "#880000", 0, ringOpacity, "#5ed835", ringOpacity);
	this.map.addOverlay(ringOverlay);
	this.overlays.push(ringOverlay);
}

MFLMap.prototype.drawGroundOverlay = function(radius) {
	var o = radius;
	var yDist = radius;
	var xDist = radius*69/d;

	// ground overlay	 
	var boundaries = new GLatLngBounds(new GLatLng(centerLat-yDist, centerLng-xDist), new GLatLng(centerLat+yDist, centerLng+xDist));
	var oldmap = new GGroundOverlay("/images/test.png", boundaries);
	this.map.addOverlay(oldmap);
}

MFLMap.prototype.positionBalloon = function(marker, balloon) {
	var yOffset = 30;
	var xOffset = 110;
	var ySpacing = 1;
	//var anchorX = this.marker.getIcon().iconAnchor.x - this.marker.getIcon().infoWindowAnchor.x;
	var anchorY = marker.getIcon().iconAnchor.y - marker.getIcon().infoWindowAnchor.y;
	var point = marker.getPoint();
	var screenPoint = this.map.fromLatLngToDivPixel(point);
	var balloonAnchor = new GPoint(screenPoint.x, screenPoint.y);
	var balloonCenterPix = new GPoint(balloonAnchor.x + balloon.offsetWidth/2 - xOffset, balloonAnchor.y - balloon.offsetHeight/2 - yOffset);
	var balloonCenter = this.map.fromDivPixelToLatLng(balloonCenterPix);
	
	balloon.style.left = screenPoint.x - 112 + 'px';
	balloon.style.top = screenPoint.y - anchorY - 225 + ySpacing + 'px';

	this.map.panTo(balloonCenter);
}

function closeBalloon() {
	curComm = 0;
	$("div.apartment-map-search-tt-small").remove();
	return false;
}
