var cache = {}; // Cache for printable results

var Nearest = function (el, mid) {
	
	this.mid = mid;
	this.el = el;
	
	// Make HTML for one place
	this.formatResult = function (obj, location) {
		var address = [];
		if (obj.address_1) address.push(obj.address_1);
		if (obj.address_2) address.push(obj.address_2);
		if (obj.city) address.push(obj.city);
		
		// Gets the postcode formatted corrected, e.g. N51TU => N5 1TU
		address.push('<span class="postcode">' + obj.postcode.substr(0, obj.postcode.length-3) + "&nbsp;" + obj.postcode.substr(-3) + '</span>');
		
		return '<a href="/local/?lq=' + location + '&mid=' + this.mid + '&pid=' + obj.placeid + '">' + address.join(', ') + '</a>';
	};
	
	// Make HTML for results
	this.formatResults = function (location, data) {
		var results = $(this.el).find('ol.local_results');
		
		$(this.el).find('div').show();
		
		this.clearResults();
		if (data.length === 0) // No results
		{
			results.after('<p>No results within 10 miles of ' + location + '</p>');
		}
		else 
		{
			var str = '';
			
			// Get results strings
			for (i in data) {
				if (data.hasOwnProperty(i))
				{
					str += '<li>' + this.formatResult(data[i], location) + '</li>';
				}
			}
			
			results.append(str);
			
			// Append with "view on a map"
			results.after('<p><a href="/local/?lq=' + location + '&mid=' + this.mid + '">View on a map</a></p>');
			
		}
	};
	
	// Errored!
	this.error = function (errorcode) {
		var results = $(this.el).find('ul.local_results')
		var er = 'Please try again';
		this.clearResults();
		
		if (errorcode == 101)
		{
			er = 'We couldn\'t find that location';
		}
		else if (errorcode == 102)
		{
			er = 'No location entered, please enter a location!';
		}
		
		results.append('<li>' + er + '</li>');
	};
	
	// Remove all the previous results
	this.clearResults = function () {
		$(this.el).find('ol.local_results').next().remove();
		$(this.el).find('ol.local_results').empty();
	};
	
	// Get me some results
	this.getResults = function (location) {
		var e = this;
		var cached_results = this.getCache(location);
		if (!cached_results) // If no cached version
		{
			$.ajax({
				'type': 'GET',
				'url': '/xhr/getnearest/',
				'data': 'mid=' + this.mid + '&lq=' + encodeURIComponent(location),
				'dataType': 'json',
				'success': function (data) {
					if (data.error)
					{
						e.error(data.error);
					}
					else
					{
						e.formatResults(location, data);
						e.addCache(location, data);
					}
				},
				'error': function () {
					e.error(102);
				}
			});
		}
		else // Get cached version
		{
			this.formatResults(location, cached_results);
		}
	};
	
	// Add a result to the cache
	this.addCache = function (location, results) {
		if (!cache[this.mid]) {
			cache[this.mid] = {};
		}
		cache[this.mid][location] = results;
	};
	
	// Get a result from the cache
	this.getCache = function (location) {
		if (this.mid && cache[this.mid] && cache[this.mid][location]) // Get cached version
		{
			return cache[this.mid][location];
		}
		return false;
	};
	
	// When the form is added, bind events to it
	this.bindForm = function () {
		
		this.form = $(this.el).find('form');
		var e = this;
		
		this.form.submit(function () {
			var entry = $(this).find(':text').val();
			
			if (entry && entry != "Enter your address")
			{
				$.cookie('print_location', entry);
				e.getResults(entry);
			}
			else
			{
				e.error(102);
			}
			return false;
		});
		
	};
	
	// Make me a form!
	this.buildForm = function () {
		if ($(this.el).find('form:first').length === 0) // If no form
		{
			var defaultvalue = typeof(POSTCODE) != 'undefined' ? POSTCODE : "Enter your address";
			var f = '<div class="nearest"><form action="#" class="nearest"><input type="text" name="lq" value="' + ($.cookie('print_location') || defaultvalue) + '" size="30" /><input type="hidden" name="merchantid" value="' + this.mid + '" /> <input type="image" src="http://' + STATIC_ROOT + '/images/global/nearest_go.png" value="Go" /></form>';
			f += '<div><ol class="local_results"></ol></div></div>';
			
			$(this.el).find('h4.nearest').after(f);
			
			var input = $(this.el).find('input[type="text"]')[0];
			
			input.select();
			
			$(input).bind('click focus', function () {
				if ($(this).val() === defaultvalue)
				{
					$(this).val('');
				}
			});
			
			this.getCache($.cookie('print_location'));
		}
		
		this.bindForm();
	};
	
	// Bind the marker click to the event
	this.bind = function () {
		var e = this;
		
		$(this.el).find('h4.nearest a').click(function () {
			e.buildForm();
			return false;
		});
	};
	
	this.init = function () {
		this.bind();
	};
	
	this.init();
};

$(function () {
	// Attach to each printable
	$('div.printable').each(function () {
		var mid = parseInt($(this).attr('rel').replace('m', ''), 10);
		var n = new Nearest(this, mid);
	});
});
