/************************************************************************************************
*************************************************************************************************

                       						maps.js

  $Id: maps.js 650 2008-06-25 21:57:19Z dmurphy $
  @type         javascript
  @url          http://www.blackbookmag.com

*************************************************************************************************
************************************************************************************************/


var map;
var geocoder;
var bounds;
var bounds_initial;
var map_listings_count = 0;
var markers = new Array();
var markerinfolist = new Array();
var markers_per_page = 20;
var marker_count = 0;
var map_mop_count = 0;
var map_element = '';
var map_geos_todo = [];
var map_info_drawing = false;

function addMapElement() {
	//$(document.body).insert('<div id="map-multiple" style="display:none;position:absolute">here</div>');
	$('bb-listing-list-rows').insert('<div id="map-multiple" style="display:none;position:absolute">here</div>');
	$('map-multiple').clonePosition('map-multiple-anchor').setStyle({display:'block', height:'400px'});
}

function load(el, hide_controls) {
  if($(el)==null && el=='map-multiple') addMapElement();

  map = null;
  document.getElementById(el).innerHTML = '';
  if (GBrowserIsCompatible()) {
    map = new GMap2(document.getElementById(el));
	geocoder = new GClientGeocoder();
	bounds = new GLatLngBounds();
	bounds_initial = new GLatLngBounds();

	map.setCenter(new GLatLng(0,0));
	if (!hide_controls) {
		map.addControl(new GSmallMapControl());
	}
	map.enableContinuousZoom();

	map.clearOverlays();
	marker_count = 0;
	markerinfolist = [];
	markers = [];
	
	processMapGeos();
  }
}

// Clear map overlays and advance map_mop_count
function mopMap() {
	map.clearOverlays();
	map_mop_count++;
}

function clickLoadMap() {
	if ($(map_element).visible()) {
		$('click-map').removeClassName('on');
		$('click-map').addClassName('off');
		new Effect.BlindUp($(map_element), {duration: .5});
		//$(map_element).hide();
	}
	else {
		$('click-map').removeClassName('off');
		$('click-map').addClassName('on');
		var tmp = markerinfolist.clone();
		$(map_element).show();
		load(map_element);
		markerinfolist = tmp.clone();
		addMarkersToMap();
	}
}

Event.observe(window,'load', function() {
	initExpansion();
});

initExpansion = function() {
	if($$('.expanded, .contracted')) {
		$$('.expanded, .contracted').each(function(elm) {
			$(elm).onclick = function() {
				Effect.toggle($(elm).next(),'blind',{
					duration : .1,
					afterFinish: function() {
						if($(elm).next().visible()) {
							$(elm).removeClassName('contracted');
							$(elm).addClassName('expanded');
						} else {
							$(elm).removeClassName('expanded');
							$(elm).addClassName('contracted');
						}
					}
				});
			}
		});
	}
}

// addAddressToMap() is called when the geocoder returns an
// answer.  It adds a marker to the map with an open info window
// showing the nicely formatted version of the address and the country code.
function addAddressToMap(markerinfo, response) {
  if (!response || response.Status.code != 200) {
	// if we can't find the address, knock the front off until we can
	/*
	current_address = current_address.split(',').slice(1).join(',');
	current_address = current_address.replace(/^\s+/,'').replace(/\s+$/,'');
	if (current_address.match(/,/)!=null) geocoder.getLocations(current_address, addAddressToMap);
	*/
    // alert("Sorry, we were unable to geocode that address");
  } else {
    place = response.Placemark[0];
    point = new GLatLng(place.Point.coordinates[1],
                        place.Point.coordinates[0]);
    marker = new GMarker(point);
		if (markerinfo.html) marker.bindInfoWindowHtml(markerinfo.html);
		bounds.extend(point);
		markers.push(marker);
		if (map_element=='bb-listing-data') updateMap(map_element);
  }
  if ((map_element!='bb-listing-data') && (++marker_count>=markerinfolist.length)) updateMap(map_element);
}

/**
 * Expects to be passed an object like:
 *
 * {
 *     id: (listing id),
 *     lat: (latitude),
 *     lon: (longitude),
 *     name: (listing name),
 *     phone: (listing phone),
 *     rating: (listing rating),
 *     street: (listing street),
 *     tag: (tag text)
 * }
 */
function addListingToMap(listing) /* , override_listing_no */ {
	map_listings_count++;
	var this_listing = map_listings_count;
	if('undefined' != typeof arguments[1]) this_listing = arguments[1];
	if('undefined' == typeof marker_clicks) marker_clicks = [];

	var marker_el_id = 'map_listing_marker_'+this_listing
	var latlng = new GLatLng(listing.lat, listing.lon);
	bounds.extend(latlng);

	var marker = map.openMyWindowHtml(
		latlng,
		'<a class="marker" id="'+marker_el_id+'" onclick="marker_clicks[\''+marker_el_id+'\']();"><span>'+this_listing+'</span></a>',
		{ noCloseOnClick:true, pixelOffset:new GSize(-10, -35) }
	);

	marker_clicks[marker_el_id] = function() {
		if(map_info_drawing) return false;
		map_info_drawing = true;
		
		if($('map_listing_info')!=null) {
			$($F('map_listing_info_marker')).up().removeClassName('active');
			$('map_listing_info').up().remove();
		}
		marker._div.addClassName('active');

		if('undefined' == typeof listing.rating || listing.rating == null) {
			listing.rating = 0;
		}
		listing.rating = Math.floor(listing.rating);

		var tag_html = '';
		if('undefined' != typeof listing.tag && listing.tag != '') {
			tag_html = '<p>'+listing.tag+'</p>';
		}
		var info_html = '<div id="map_listing_info" class="info"><input id="map_listing_info_marker" type="hidden" value="'+marker_el_id+'" />';
		info_html += '<h4><a href="/guides/details/'+listing.permalink+'/">'+listing.name+'</a></h4>';
		info_html += tag_html;
		info_html += '<ul class="bb_rating" title="'+listing.rating+'/5">';
		info_html += '<li class="current-rating" style="width:'+(16*listing.rating)+'px">Current rating: '+listing.rating+' of 5</li>';
		info_html += '</ul>';
		info_html += '<p style="clear:both">'+listing.street+'</p>';
		info_html += '<p class="phone">'+listing.phone+'</p>';
		info_html += '</div>';

		var info_options = {
			onCloseFn: function() {
				$($F('map_listing_info_marker')).up().removeClassName('active');
			},
			pixelOffset:new GSize(-2, -35)
		};
		map.openMyWindowHtml(latlng, info_html, info_options);
		map.panTo(latlng);

		map_info_drawing = false;
	}
	//$(marker_el_id).observe('click', marker_clicks[marker_el_id]);
	
	setZoom();
}

function addListingToDetails(listing) /* , override_listing_no */ {
	map_listings_count++;
	var this_listing = map_listings_count;


	var marker_el_id = 'map_listing_marker_'+this_listing
	var latlng = new GLatLng(listing.lat, listing.lon);
	bounds.extend(latlng);

	var marker = map.openMyWindowHtml(
		latlng,
		'<img id="'+marker_el_id+'" src="/img/map_point.gif" />',
		{ noCloseOnClick:true, pixelOffset:new GSize(-10, -35) }
	);
	
	setZoom();
}

function addListingToMapFromGeo(response, listing) {
	if('undefined' != typeof arguments[2]) this_listing = arguments[2];
	else this_listing = undefined;

	if (!response || response.Status.code != 200) {
	} else {
		place = response.Placemark[0];
		listing.lat = place.Point.coordinates[1];
		listing.lon = place.Point.coordinates[0];
		bounds.extend(new GLatLng(listing.lat, listing.lon));
		addListingToMap(listing, this_listing);
	};
}

function removeMarkers() {
	for (var i=0; i<markers.length; i++) {
		map.removeOverlay(markers[i]);
	}
}

function addMarkersToMap() {
	removeMarkers();
	for (var i=0; i<markerinfolist.length; i++) {
		var markerinfo = markerinfolist[i];
		geocoder.getLocations(markerinfo.address, addAddressToMap.bind(this, markerinfo));
	}
}

function processMapGeos() {
	map_geos_todo.each(function(m) {
		m();
	});
	setZoom();
}

function setZoom() {
	map.setZoom(map.getBoundsZoomLevel(bounds));
	var clat = (bounds.getNorthEast().lat() + bounds.getSouthWest().lat()) /2;
	var clng = (bounds.getNorthEast().lng() + bounds.getSouthWest().lng()) /2;
	map.setCenter(new GLatLng(clat,clng));
}

function centerAtLocation(address) {
	geocoder.getLocations(address, function(response){
	  // map.clearOverlays();
	  if (!response || response.Status.code != 200) {
	    alert("Sorry, we were unable to geocode that address");
	  } else {
	    place = response.Placemark[0];
	    point = new GLatLng(place.Point.coordinates[1],
	                        place.Point.coordinates[0]);
		map.setCenter(point,5);
	  }
	});
}

function updateMap(el) {
	if (markers.length>0) {
		mgr = new GMarkerManager(map);
		mgr.addMarkers(markers, 1);
		mgr.refresh();
		setZoom();
	}
	else {
		// if we don't have any markers on the map, hide it
		document.getElementById(el).style.display='none';
	}
}

function getMarkerPoints(markers) {
	var points = new Array();
	for (var i=0; i<markers.length; i++) {
		points.push(markers[i].getPoint());
	}
	return points;
}
