//
//
// Custom Google Maps Implementation
// Reuben King 
// Swirl.net
// September 2007
//
//
// googlemap/core.js: Core API Implementation
//


// Google Maps API stuff
var gMap, gDir;
var locsXml, locs;
var geocoder = new GClientGeocoder();
var gMarkers = [], gMarkersHtml = [], gMarkersToHereHtml = [], gMarkersFromHereHtml = [];
var gMarkerIndex = 0;


// icon defaultsvar 
baseIcon = new GIcon();
baseIcon.image = gMapConfig.MarkerIconDefault;
baseIcon.shadow = gMapConfig.MarkerShadowIcon;
baseIcon.iconSize = new GSize(12, 20);
baseIcon.shadowSize = new GSize(22, 20);
baseIcon.iconAnchor = new GPoint(6, 20);
baseIcon.infoWindowAnchor = new GPoint(5, 1);

// Google Geocoder Errors
var reasons=[];
reasons[G_GEO_SUCCESS]            = "Success";
reasons[G_GEO_MISSING_ADDRESS]    = "Missing Address: The address was either missing or had no value.";
reasons[G_GEO_UNKNOWN_ADDRESS]    = "Unknown Address:  No corresponding geographic location could be found for the specified address.";
reasons[G_GEO_UNAVAILABLE_ADDRESS]= "Unavailable Address:  The geocode for the given address cannot be returned due to legal or contractual reasons.";
reasons[G_GEO_BAD_KEY]            = "Bad Key: The API key is either invalid or does not match the domain for which it was given";
reasons[G_GEO_TOO_MANY_QUERIES]   = "Too Many Queries: The daily geocoding quota for this site has been exceeded.";
reasons[G_GEO_SERVER_ERROR]       = "Server error: The geocoding request could not be successfully processed.";
reasons[G_GEO_BAD_REQUEST]        = "A directions request could not be successfully parsed.";
reasons[G_GEO_MISSING_QUERY]      = "No query was specified in the input.";
reasons[G_GEO_UNKNOWN_DIRECTIONS] = "The GDirections object could not compute directions between the points.";


// Initialization:  Load the XML data and if successful, draw the map
function init()
{
	if ( typeof( gMapConfig ) != 'object' ) {
		window.alert( 'Fatal: Unable to load configuration data from googlemap/config.js.  Check the contents of this file' );
		return false;
	}
	
	// set up debugging
	if ( gMapConfig.LoggingLevel >= 0 )
	{
		FVL_LOG_ON = true;
		FVL_DEFAULT_LOG_LEVEL = gMapConfig.LoggingLevel;
		FVL_LOG_ID = gMapConfig.LogElementId;
		
		var logDiv = $( FVL_LOG_ID );
		if ( !logDiv )
		{
			var outerDiv = $( gMapConfig.MapOuterDivId );
			if ( !outerDiv ) outerDiv = document.getElementsByTagName('body').item(0);
			
			logDiv = document.createElement('div');
			logDiv.id = gMapConfig.LogElementId;
			outerDiv.appendChild( logDiv );
		}
		
	}
	else
	{
		FVL_LOG_ON = false;
	}
	
	var xmlUrl = gMapConfig.LocationsXmlFile;
	debug('init called: loading xmlUrl ' + xmlUrl );
	//var url = '/10.247.16.11:28080?url=' + encodeURIComponent(xmlUrl);
	
	debug('init called: loading URL ' + xmlUrl );
	
	if ( gMapConfig.ForceNoCache ) {
		info('note: XML Request Cache Disabled');
		xmlUrl += '?seed=' + Math.floor( Math.random() * 100000 );
	}
	//alert("URL is: "+url);
	// load locations from XML and populate map
	new Ajax.Request( xmlUrl, {
					 method: 'get',
					 requestHeaders: { 'Accept' : 'text/xml', 'Cache-Control': 'no-store' },
					 onSuccess: function(transport) {
					 	debug('Ajax.Request Success (' + transport.status + '/' + transport.statusText + ')' )
						if ( getLocationsFromXml( transport.responseXML ) ) {
							setupMap();
							addLocationsToMap();
						} else {
							dieGracefully('Locations data unavailable');
						}
					 },
					 onFailure: function(transport) {
					 	dieGracefully('Ajax.Request Failure! (' + transport.status + '/' + transport.statusText + ')' );
					 }
		});
	
	
}


// Create the Map, load the XML, party on..
function setupMap()
{
	debug( 'setupMap started' );

	if ( GBrowserIsCompatible() ) 
	{
		var gMapOuterDiv = document.getElementById( gMapConfig.MapOuterDivId );
		var gMapDiv      = document.getElementById( gMapConfig.MapInnerDivId );
		var gDirDiv      = document.getElementById( gMapConfig.DirectionsDivId );
		
		if ( !gMapOuterDiv || !gMapDiv )
		{
			dieGracefully( 'Unable to hook onto map div' );
		}
		else
		{
			gMapDiv.style.width  = gMapConfig.Width + 'px';
			gMapDiv.style.height = gMapConfig.Height + 'px';
			
			gMap = new GMap2( gMapDiv );		
			gDir = new GDirections( gMap, gDirDiv );

			// map navigation controls
			if ( gMapConfig.ShowBaseControls ) gMap.addControl( new GLargeMapControl() );
			if ( gMapConfig.ShowExtraControls ) gMap.addControl( new GMapTypeControl() );
	
			// center map on Alameda
			gMap.setCenter( new GLatLng( gMapConfig.InitialLatitude, gMapConfig.InitialLongitude ), gMapConfig.InitialZoomLevel );
			
			// Catch Directions errors
			GEvent.addListener( gDir, 'error', function() {
				var code = gDir.getStatus().code;
				var reason = 'Code ' + code;
				if ( reasons[code] ) 
				{
					reason = reasons[code]
				} 
			
				dieGracefully( 'Failed to obtain directions, ' + reason );
			});
			
			GEvent.addListener( gDir, 'load', function() {
				showDirectionsPane();
			});
		}
	}
	else
	{
		//@todo: create and display alternate low-fi version of map
		dieGracefully("Sorry, Google Maps is not compatible with this browser");
	}
}


// callback function from simpleXml-- adds markers to map for all locations
function getLocationsFromXml( sx )
{
	debug( 'getLocationsFromXml called' );
	var pLat, pLong, thePoint, tMarker;
	
	locs = sx.getElementsByTagName('location');
	
	if ( !locs.length ) 
	{
		if ( typeof(console) == 'object' ) {
			warn('no locations found in reponse XML! (see console for object dump)');
			console.dir( sx );
		} else {
			warn('no locations found in reponse XML!');
		}
		
		return false;
	}
	else
	{
		debug('found ' + locs.length + ' locations' );
		
		for ( var i=0; i < locs.length; i++ ) 
		{	
			pLat = parseFloat( locs[i].getAttribute('lat') );
			pLong = parseFloat( locs[i].getAttribute('long') );
			
			thePoint = new GLatLng( pLat, pLong );
			debug('after GLatLng');
			tMarker = createMarker( thePoint, locs[i] );
		}
		
		debug('found ' + (i+1) + ' locations' );
		
		return true;
	}
}

function addLocationsToMap()
{
	debug('addLocationsToMap called');

	for ( var i=0; i < gMarkers.length; i++ ) 
	{	
		gMap.addOverlay( gMarkers[i] );
	}
	
	debug('added ' + (i+1) + ' locations to map' );
	
	return true;
}

function getLocationIcon( location )
{
	var imagef = gMapConfig.MarkerIcons[ location.getAttribute('icon').toLowerCase() ];
	
	if ( imagef ) {
		return new GIcon( baseIcon, imagef );
	} else {
		return new GIcon( baseIcon );
	}
}

// Creates a marker for a given location
function createMarker( point, location )
{
	
	var icon = getLocationIcon( location );

	var marker = new GMarker( point, icon );
	var html, htmlStart, htmlEnd, toHereHtml, fromHereHtml;
	
	var locName = location.getElementsByTagName('name')[0].firstChild.data;
	var locStreet = location.getElementsByTagName('street')[0].firstChild.data;
	var locCity = location.getElementsByTagName('city')[0].firstChild.data;
	var locState = location.getElementsByTagName('state')[0].firstChild.data;
	var locZip = location.getElementsByTagName('zip')[0].firstChild.data;
	// added by indira
		
	var isPhone = false;
	var locPhone = '';
	if(location.getElementsByTagName('phone')[0].firstChild != null)
	{
		isPhone = true;
		locPhone = location.getElementsByTagName('phone')[0].firstChild.data;		
	}
	// end added by indira
	
	
	var isNotes = false;
	var locNotes = '';
	if(location.getElementsByTagName('notes')[0].firstChild != null)
	{
		isNotes = true;
		locNotes = location.getElementsByTagName('notes')[0].firstChild.data;		
	}
	
	
	
	//var locPhone = location.getElementsByTagName('phone')[0].firstChild.data;
	var address = locStreet + '<br>' + locCity + ', ' + locState + ' ' + locZip;
	var address2 = address.replace('<br>',', ');
	debug('after address2');
	
	var toHereLink   = '<a href="javascript:void(0)" onClick="getDirectionsToHere(' + gMarkerIndex + ')">To Here</a>';
	var fromHereLink = '<a href="javascript:void(0)" onClick="getDirectionsFromHere(' + gMarkerIndex + ')">From Here</a>';
	
	htmlStart      = '<div id="popup' + location.getAttribute('id') + '" class="locationPopup">';
	htmlStart     += '<h1>Address:</h1>';
	if ( locName ) 
		htmlStart += '<p class="name">' + locName + '</p>';
	htmlStart     += '<p class="address">' + address + '</p>';
	//htmlStart     += '<p class="phone">' +locPhone + '</p>';
	// added by indira
	if(isPhone)
		htmlStart     += '<p class="phone">' +locPhone + '</p>';
	//end added by indira
	
	if(isNotes)
		htmlStart     += '<p class="phone"><b>Notes:</b> ' +locNotes + '</p>';
	
	
	
	htmlEnd = '</div>';	
	
	html = htmlStart;
	html += '<p class="directions"><strong>Get Directions:</strong> ' + toHereLink + ' - ' + fromHereLink + '</p>';
	html += htmlEnd;
	
	toHereHtml      = htmlStart;
	toHereHtml     += '<p class="directions"><strong>Get Directions:</strong> To Here - ' + fromHereLink + '</p>';
	toHereHtml     += '<form action="javascript:getDirections()">';
	toHereHtml     += '<p class="small grey">Start Address</p>';
	toHereHtml     += '<input type="text" id="startAddr" class="address" /><input type="submit" value="Go" /></p>';
	toHereHtml     += '<input type="hidden" id="endAddr" value="' + address2 + '@' + point.lat() + ',' + point.lng() + '"/>';
	toHereHtml     += '</form>';
	toHereHtml     += htmlEnd;
	
	fromHereHtml    = htmlStart;
	fromHereHtml   += '<p class="directions"><strong>Get Directions:</strong> ' + toHereLink + ' - From Here</p>';
	fromHereHtml   += '<form action="javascript:getDirections()">';
	fromHereHtml   += '<p class="small grey">End Address</p>';
	fromHereHtml   += '<input type="text" id="endAddr" class="address" /><input type="submit" value="Go" /></p>';
	fromHereHtml   += '<input type="hidden" id="startAddr" value="' + address2 + '@' + point.lat() + ',' + point.lng() + '"/>';
	fromHereHtml   += htmlEnd;

	gMarkersHtml[gMarkerIndex] = html;
	gMarkersToHereHtml[gMarkerIndex] = toHereHtml;
	gMarkersFromHereHtml[gMarkerIndex] = fromHereHtml;
	
	GEvent.addListener( marker, "click", function() {
		marker.openInfoWindowHtml( html );
	});
	
	gMarkers[gMarkerIndex] = marker;
	gMarkersToHereHtml[gMarkerIndex] = toHereHtml;
	
	gMarkerIndex++;
	
	return marker;
}

// When "To Here" and "From Here" links are clicked
function getDirectionsToHere( i )
{
	debug( 'get directions to here click received' );
	gMarkers[i].openInfoWindowHtml( gMarkersToHereHtml[i] );
}

function getDirectionsFromHere( i )
{
	debug( 'get directions from here click received' );
	gMarkers[i].openInfoWindowHtml( gMarkersFromHereHtml[i] );
}

// Fire up the Directions manager 
function getDirections()
{
	var saddr = $( 'startAddr' ).value
	var daddr = $( 'endAddr' ).value
	
	debug( 'loading directions info for ' + saddr + ' to ' + daddr );
	gDir.load( 'from: ' + saddr + ' to: ' + daddr);
}

function showDirectionsPane()
{
	debug( 'show directions pane' );
	
	var dirDiv = $( gMapConfig.DirectionsDivId );
	var mapDiv = $( gMapConfig.MapInnerDivId );
	
	dirDiv.style.display = 'block';
	dirDiv.style.width = mapDiv.style.width;
}

function dieGracefully( str )
{
	debug('die gracefully called');
	//@todo: beef this up
	error('died: ' + str );
	
	var outerDiv = $( gMapConfig.MapOuterDivId );
	var innerDiv = $( gMapConfig.MapInnerDivId );
	
	var fatalErrDiv = document.createElement('div');
	
	fatalErrDiv.id = 'gMapsError';
	fatalErrDiv.innerHTML = '<p class="error title">Unable to display locations map:</p><p class="error">' + str + '</p>'
	
	outerDiv.replaceChild(  fatalErrDiv, innerDiv );
}



// Add some hooks to the onLoad and onUnload window events:
addLoadEvent( init );
addUnloadEvent( GUnload );
