(function($) {
	
	var ELEMENT_DATA_KEY = 'address_state';
	var DEFAULT_VALUE = '0';
	var DEFAULT_OPTION = '<option value="0">- Choose -</option>';
	var OPTION_TEMPLATE = '<option value="${id}">${name}</option>';
	var QUERY_ARGUMENT = 'country_id';
	var EVENT_NAME = 'country_changed';

	var methods = 
	{
		init:function(options)
		{
			var defaults = 
			{
				countrySelector:'',
				stateSelector:'',
				url:''
			};
			
			return this.each(function(){
				
				$this = $(this);
				var state = $this.data(ELEMENT_DATA_KEY);
				
				//console.log('state:[%o]', state);
				
				if(!state)				
				{
					if(options)
					{					
						$.extend(defaults, options);
					}
					
					//console.log('new instance:[%o]', this);
					
					$this.data(ELEMENT_DATA_KEY, new SteinerAddress($this, defaults));
				}
			});
		}
	};
	
	function SteinerAddress(element, defaults)
	{
		var onChange = function(element, preserve)
		{
			//console.log(this);
    		var map = new Object(); 
    		map[QUERY_ARGUMENT] = $(this).val();
			
    		$.getJSON(defaults.url, map, function(response)
			{
				//console.log('response recieved');
				var selectedState = $(defaults.stateSelector).val();
				//console.log('preserved state:%s selected state:%s', preserve, selectedState);
				
				onResponse(response, defaults.stateSelector);
				
				if(preserve) 
				{
					$(defaults.stateSelector).val(selectedState);
				}
				else
				{
					$(defaults.stateSelector).val(DEFAULT_VALUE);
				}
			});
		};
		
		var onResponse = function(response, selector)
		{
			$(selector).children().remove();
			if(response.error) 
			{
				//console.log(response.msg);				
			}
			else
			{
				onParse(response.country, selector);
			}
			
			$(selector).prepend(DEFAULT_OPTION);
		}
		
		var setLabel = function(international)
		{
			if(international) 
			{
				$(defaults.stateSelector).prev('label').text('Province:');
			}
			else
			{
				$(defaults.stateSelector).prev('label').text('State:');
			}
		};
		
		var onParse = function(data, selector)
		{
			if(data.territories.length > 0) 
			{
				$.tmpl(OPTION_TEMPLATE, data.territories).appendTo(selector);
			}
									
			setLabel(data.international);
		};
		
		var init = function()
		{
			$(defaults.countrySelector).bind('change', onChange);
		
			if($(defaults.countrySelector).val() == DEFAULT_VALUE)
			{
				$(defaults.stateSelector).children().remove();
				$(defaults.stateSelector).prepend(DEFAULT_OPTION);
				$(defaults.stateSelector).val(DEFAULT_VALUE);
			}
			else
			{
				$(defaults.countrySelector).trigger('change', [true]);
			}
			
			//console.log('init called:')
			
			$(element).bind(EVENT_NAME, onCountryChange);
		};
		
		var onCountryChange = function(event, countryId, selector)
		{
			//console.log('event country_id:[%s] selector:[%s] this:[%o] event:[%o] ', countryId, selector, this, event);
			
			var map = new Object(); 
			map[QUERY_ARGUMENT] = countryId;
			
			$.getJSON(defaults.url, map, function(response)
			{
				//console.log('response recieved');
				onResponse(response, selector);
				$(selector).val('0');
			});			
		};
		
		init();
	}
	
	$.fn.steineraddress = function(method)
	{	
		//console.log('method:[%o]', method);
		if(methods[method]) 
		{			
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		} 
		else
		{
			if(typeof method === 'object' || !method) 
			{				
				return methods.init.apply(this, arguments);
			}
			else 
			{
				$.error('Method ' + method + ' DNE');
			}	
		} 
	};
})(jQuery);
