var locator = {
	API_LOCATION: 		'http://where.yahooapis.com/geocode',
	API_KEY:  			'[yourappidhere]',
	FLAGS: 				'J',
	
	ip_address: 		'',
	locations: 			[],
	
	find: 	function(address, callback) {
		callback = callback || function() {};
		
		$.ajax({
			url: locator.API_LOCATION,
			cache: false,
			data: {
				q: 		address,
				flags: 	locator.FLAGS,
				appid: 	locator.API_KEY
			},
			
			error: function(response, status, error) {
				console.error("Error while geocoding", response, status, error)
			},
			
			success: function(response, status) {
				if(status != 'success' || response.ResultSet.Error 
					|| response.ResultSet.Results == undefined) {
					console.error("Error while geocoding")
				} else locator.handleResult(response, callback)
			},
			dataType: 'json'
		})
		
	},
	
	check: function(callback) {
		locator.find(locator.ip_address, function() {
			
			// We only care about people in_bounds, so filter the results			
			locator.locations = _.filter(locator.locations, function(obj) {
				return obj.in_bounds
			})
			
			// If there's anything left, they're in-bounds in a target location
			if(locator.locations.length)
				callback( locator.locations[0] )

			// Otherwise, we've done all that work for pretty much no reason
		});
	},
	
	debug: function(callback) {
		locator.find(locator.ip_address, function() {
			callback( locator.locations )
		});
	},
	
	handleResult: function(response, callback) {
		var lat 	= parseFloat(response.ResultSet.Results[0].latitude),
			lon 	= parseFloat(response.ResultSet.Results[0].longitude),
			p 		= { lat: lat, lon: lon },
			obj		= null;
			
		locator.locations = _.map(locator.locations, function(obj) {
			obj.distance 		= locator.calcDistance(p, { lat: obj.lat, lon: obj.lon } );
			obj.out_of_bounds	= obj.distance > obj.threshold;
			obj.in_bounds 		= !obj.out_of_bounds;
			
			return obj;
		});

		callback();

	},
	
	calcDistance: function(point1, point2) {

		var dLat = locator.toRadians( point2.lat - point1.lat ),
			dLon = locator.toRadians( point2.lon - point1.lon ),
			arc	 = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos( locator.toRadians(point1.lat) ) *
					Math.cos( locator.toRadians(point2.lat) ) * Math.sin(dLon / 2) * Math.sin(dLon / 2);

		// 3959 miles
		// 6371 km
							
		return 2 * Math.atan2( Math.sqrt(arc), Math.sqrt(1 - arc) ) * 3959;
	},
	
	toRadians: function(degrees) {
		return degrees * Math.PI / 180;
	}
}
