function Geolocator() {}
Geolocator.prototype = {
	geocoder: new GClientGeocoder(),
	type: {
		full: 1,
		address: 2,
		town: 3,
		postal_code: 4
	},
	/**
	 * Get Geodata
	 * 
	 * @param (Hash) params
	 * @param (function) callback
	 */
	locate: function(params, callback, type) {
		if(type == undefined) {
			type = this.type.full; // default to full address lookup
		}
		var geo_params = new Array();
		var keys = params.keys();
		// standardize format of postal code
		if(keys.include("postal_code")) {
			var pc = params.get('postal_code');
			pc = pc.toUpperCase();
			pc = pc.replace(/^([A-Z]\d[A-Z])(\d[A-Z]\d)$/, "$1 $2");
			params.set('postal_code', pc);			
		}
		switch(type) {
			case this.type.full:
				if(!this.hasFull(params)) {
					throw "Invalid Parameters";
				}
				geo_params.push(params.get('street_address'));
				geo_params.push(params.get('town') + " " + params.get('postal_code'));
				break;
			case this.type.address:
				if(!this.hasAddress(params)) {
					throw "Invalid Parameters";
				}
				geo_params.push(params.get('street_address'));
				geo_params.push(params.get('town'));
				break;
			case this.type.town:
				if(!this.hasTown(params)) {
					throw "Invalid Parameters";
				}
				geo_params.push(params.get('town'));
				break;			
			case this.type.postal_code:
				if(!this.hasPostalCode(params)) {
					throw "Invalid Parameters";
				}
				geo_params.push(params.get('postal_code'));				
				break;
			default:
				throw "Invalid Type";
				break;				
		}
		// add default province and country data
		geo_params.push("NL");
		geo_params.push("Canada");
		// generate geo id and get geodata
		var geo_id = geo_params.join(', ');
		this.geocoder.getLocations(geo_id, callback);
		return geo_id; // this should always make it back in time
	},
	hasFull: function(hash) {
		return this.hasPostalCode(hash) && this.hasAddress(hash);
	},
	hasAddress: function(hash) {
		var has_street_address = hash.keys().include('street_address') && hash.get('street_address').length > 0;
		return has_street_address && this.hasTown(hash);
	},
	hasTown: function(hash) {
		return hash.keys().include('town') && hash.get('town').length > 0;
	},	
	hasPostalCode: function(hash) {
		return hash.keys().include('postal_code') && hash.get('postal_code').isPostalCode();
	}	
}
