$extend( FY, {

	attemptLocation: function( location, type )
	{	
		if ( !GBrowserIsCompatible() ) {
			$log( 'Browser not compatible with Google maps.' );
			return;
		}
			
		// If we are only passing in a string, make sure thats all we use
		if ( $type( location ) == 'string' )
			var stringAttempt = location;
			
		// Usually we pass in an object of data, check to see
		if ( $type( location ) == 'object' )
		{		
			var attempts = {};
		
			// 1st attempt - Location name and address (some chance of success)
			attempts['1'] = location.studioName + ', ' +
							location.studioAddress + ', ' +
						    location.city + ', ' +
						    location.zipcode + ' ' +
						    location.state + ' ' +
						    location.country;
				
			// 2nd attempt - Full address (good chance of success)
			attempts['2'] = location.studioAddress + ', ' +
						    location.city + ', ' +
						    location.zipcode + ' ' +
						    location.state + ' ' +
						    location.country;
			
			// 3rd attempt - General address (excellent chance of success)
			attempts['3'] = location.city + ', ' +
						    location.zipcode + ' ' +
						    location.state + ' ' +
						    location.country;
						   
			// 4th attempt - State address (99% chance of success, unlikely to run)
			attempts['4'] = location.zipcode + ' ' +
						    location.state + ' ' +
						    location.country;
						   
			// 5th attempt - Country (one of the last resorts, should never run)
			attempts['5'] = location.country;
			
			// 6th attempt - Country (last resort, default to united states)
			attempts['6'] = 'United States';
			
		}
		
		// Prepare the map
		var geocoder = new GClientGeocoder();
		var step = 1;
		
		// If its a teacher signup, start at attempt 3, as we don't pass a studio name or address
		if ( type == 'teacher' )
			step = 3;
		
		var foundLocation = false;
		var locationString = '';
		
		// Determine the address, increment each attempt until we find something
		var determineAddress = function( step )
		{
			var attempt = attempts[ step ].toString().clean();
		
			$log( 'Running attempt ' + step );
		
			geocoder.getLocations( attempt, function( results ) {
		
				// Do the next step along the chain
				var nextStep = function() {
				
					step++;
				
					if ( step <= 6 )
						determineAddress( step );
					else
						$log( 'We have a problem, nothing was matched.' );
				};
			
				// Abort if nothing was found
				if ( !results || results.Status && results.Status.code == 602 )
				{
					$log( 'No address found at attempt: ' + step )
					
					nextStep();
					return;
				}
				
				// If we are in step 1, 2 or 3, we need to check the accuracy and either go to
				// the next step, or use the address based on how accurate it is
				if ( step == 1 || step == 2 || step == 3 )
				{	
					// Check for a match first
					if ( !results.Placemark.length ) {
						$log( 'No address found at attempt: ' + step )
						nextStep();
						return;
					}
					
					// Check the accuracy
					var accuracy = results.Placemark[0].AddressDetails.Accuracy;
					
					if ( accuracy <= 7 ) {
						$log( 'No accurate address found at attempt: ' + step )
						nextStep();
						return;
					}
					else {
						// If successful and accurate, pin the address to the map
						$log( 'Address found matching: ' + attempt );
						
						// Mark that we found the location, which determines what kind of output the person sees
						foundLocation = true;
						
						// Set which address we used so we can set the text field if we need to refine it
						locationString = attempt;
						
						geocoder.getLatLng( attempt, function( point ) {
							pinAddress( point );
						});
						return;
					}
					
					$log( 'No addresss found at attempt: ' + step )
					nextStep();
					return;
				}
				
				// If no conditions were met, we have some sort of address to use, so pin it on the map
				$log( 'Address found matching: ' + attempt );
				
				// Mark that we didn't find the location, which determines what kind of output the person sees
				foundLocation = false;
				
				// Set which address we used so we can set the text field if we need to refine it
				locationString = attempt;
				
				geocoder.getLatLng( attempt, function( point ) {
					pinAddress( point );
				});
				
			}.bind( this ));
		}
		
		// Attempt finding the address, based on the users input into the field
		var attemptAddress = function( stringAttempt )
		{
			var attempt = stringAttempt.toString().clean();
			
			$log( 'Attempting to find: ' + attempt );
		
			geocoder.getLatLng( attempt, function( point ) {
		
				if ( !point )
				{
					$log( 'Address not found.' )
					
					alert( 'We couldn\'t find anything at that address, please try a simpler query.\n\nTry to eliminate any non-essential characters or words, you can also refine it yourself by setting the marker on the map.' )
										
					return;
				}
				
				// If successful, pin the address to the map
				$log( 'Address found matching: ' + attempt );
				
				// Set the location string to the one we tried
				locationString = stringAttempt;

				pinAddress( point );
				
			});
		}
		
		// Do one of the 2 methods of finding the address
		if ( stringAttempt )
			attemptAddress( stringAttempt ); // Simple
		else
			determineAddress( step ); // Complex
		
		// Pin the address to the map
		var pinAddress = function( point )
		{	
			// Show the map
			$( 'form_signup_locating' ).hide();
			$( 'form_signup_map' ).show();
			
			// Set the textfield of the map location we used (in case we need to refine it)
			$( 'form_signup_map_refine' ).set( 'value', locationString );

			// Set the text for the map screen, depending on whether we found a location
			FY.setMapInfo( foundLocation, type );
			
			// Create the map
			var $map = $( 'form_signup_map_render' );	
			var map = new GMap2( $map );
			
			// Center the map on the marker and add navigation tools
			var zoom = 15;
			
			switch( step )
			{
				case 3:
					zoom = 10;
				break;

				case 4:
					zoom = 9;
				break;
				
				case 5:
					zoom = 6;
				break;
				
				case 6:
					zoom = 6;
				break;
			}
			
			map.setCenter( point, 13 ); 
			map.setZoom( zoom );
			
			map.addControl( new GLargeMapControl() );
	        map.addControl( new GMapTypeControl() );
	
			var marker = new GMarker( point, { draggable: true } );
	
			// Store the coords we found initally, they might well be correct
			var coordinates = marker.getLatLng();
			
			$( 'longitude' ).set( 'value', coordinates.x );
			$( 'latitude' ).set( 'value', coordinates.y );
			
			// Add an event in case the user drags the marker, refining the location
			GEvent.addListener(marker, "dragend", function() {
	
				var coordinates = marker.getLatLng();
				
				$( 'longitude' ).set( 'value', coordinates.x );
				$( 'latitude' ).set( 'value', coordinates.y );
				
	        });
	
			// Add the marker to the map
	        map.addOverlay( marker );
		}
		
		// Add event to refine button (in case we need to refine it)
		$( 'form_signup_map_locate' ).addEvent( 'click', function() {
			attemptAddress( $( 'form_signup_map_refine' ).value.trim() );
		});
		
		// Go back button if need be
		$( 'form_signup_map_back' ).addEvent( 'click', function() {
			$( 'form_signup_map' ).hide();
			$( 'form_signup_details' ).show();
		});
		
		// Skip the map location, null the latitude and longitude fields and submit the form
		$( 'form_signup_map_skip' ).addEvent( 'click', function() {
		
			var jsonData = {
				location: {
					address: ( $( 'studioAddress' ) ? $( 'studioAddress' ).get( 'value' ).trim() : '' ),
					suburb: $( 'city' ).get( 'value' ).trim(),
					postcode: $( 'zipcode' ).get( 'value' ).trim(),
					state: $( 'state' ).get( 'value' ).trim(),
					country: $( 'country' ).get( 'value' ).trim(),
					longitude: '',
					latitude: ''
				}
			}
			
			$( 'jsonData' ).set( 'value', JSON.encode( jsonData ) );
		
			FY._signupComplete = true;
		
			$( 'latitude' ).set( 'value', '' );
			$( 'longitude' ).set( 'value', '' );
			$( 'form_signup_map' ).hide();
			$( 'form_signup_done' ).show();
			$( 'button_close' ).hide();
			$( 'form_signup' ).submit.click();
		});
		
		// Confirm the address
		$( 'form_signup_map_confirm' ).addEvent( 'click', function() {
		
			var jsonData = {
				location: {
					address: ( $( 'studioAddress' ) ? $( 'studioAddress' ).get( 'value' ).trim() : '' ),
					suburb: $( 'city' ).get( 'value' ).trim(),
					postcode: $( 'zipcode' ).get( 'value' ).trim(),
					state: $( 'state' ).get( 'value' ).trim(),
					country: $( 'country' ).get( 'value' ).trim(),
					longitude: $( 'longitude' ).get( 'value' ).trim(),
					latitude: $( 'latitude' ).get( 'value' ).trim()
				}
			}
			
			$( 'jsonData' ).set( 'value', JSON.encode( jsonData ) );
			
			FY._signupComplete = true;
	
			// And Submit...
			$( 'form_signup_map' ).hide();
			$( 'form_signup_done' ).show();
			$( 'button_close' ).hide();
			$( 'form_signup' ).submit.click();
		});
	},
	
	setMapInfo: function( foundLocation, type )
	{
		// Sets various parts of infomation, different for each situation, either when finding the location or not
		if ( foundLocation )
		{
			$( 'form_signup_map_refine_container' ).hide();
		
			$( 'form_signup_map_title' ).set( 'text', 'We found your ' + type + '!' );
			$( 'form_signup_map_subtitle' ).set( 'text', 'Have a look at the map below and confirm its the right location. This is what visitors will see when they find you.' );
		
			$( 'form_signup_map_help' ).set( 'html', '<strong>Wrong location?</strong><p style="margin-top: 10px;">The marker represents your location, if its in the wrong place simply click and drag the marker on the map above. Use the tools to move around the map.</p>' );
		
			$( 'form_signup_map_confirm' ).getElement( '.wrap2' ).set( 'text', 'That\'s my location!' );
			
			$( 'form_signup_map_buttons' ).setStyle( 'margin-left', '50px' );
		}
		else
		{
			$( 'form_signup_map_title' ).set( 'text', 'Hmm... we can\'t locate you' );
			$( 'form_signup_map_subtitle' ).set( 'text', 'We tried our best to find you, but cannot determine an exact location, can you help us? This location is what visitors will see when they find you.' );
	
			$( 'form_signup_map_help' ).set( 'html', '<strong>How to locate yourself:</strong><p style="margin-top: 10px;">Click and drag the marker on the map above and show us exactly where you are. If the map is in the wrong area, try typing in another location <strong>in the text field above</strong> and clicking <strong>Find</strong> to reposition the marker. Use the tools to move around the map.</p>' );
	
			$( 'form_signup_map_confirm' ).getElement( '.wrap2' ).set( 'text', 'I\'ve marked my location' );
		}
	}

});
