var FormEleGeocoding = function(_ele_id, _ymaps_key)
{
	this.ele_id = _ele_id;
	this.ymaps_key = _ymaps_key;
	
	this.input_ele = $('#' + this.ele_id);
	this.find_button_ele = $('#' + this.ele_id + '_find');
	this.lat_input_ele = $('#' + this.ele_id + '_lat');
	this.lng_input_ele = $('#' + this.ele_id + '_lng');
	
	this.input_ele.after('<div id="' + this.ele_id + '_chooser" class="geocoding_chooser"></div>');
	this.chooser_ele = $('#' + this.ele_id + '_chooser');
	
	this.input_ele.after('<div id="' + this.ele_id + '_lat_label" class="geocoding_lat_label"></div>');
	this.lat_label_ele = $('#' + this.ele_id + '_lat_label');
	this.input_ele.after('<div id="' + this.ele_id + '_lng_label" class="geocoding_lng_label"></div>');
	this.lng_label_ele = $('#' + this.ele_id + '_lng_label');

	this.min_length = 3;
	this.max_results = 10;
	this.delay = 1000;
	
	this.is_geocoding = false;
	this.is_geocoding_queued = false;
	this.results = [];
	this.mouse_is_over_chooser = false;
	
	var instance = this;
	
	this.find_button_ele.click(function() { instance.queueProcess(); return false; });
	
	this.input_ele.keyup
	(
		function(e)
		{
			instance.triggerFindButton();
			if (e.keyCode == 13)
			{
				instance.queueProcess();
				return false;
			}
		}
	);
	this.input_ele.focus(function() { instance.process(); });
	
	$('#' + this.ele_id + ', #' + this.ele_id + '_chooser').hover
	(
		function()
		{ 
			instance.mouse_is_over_chooser = true;
		},
		function()
		{ 
			instance.mouse_is_over_chooser = false;
		}
	);
	$('body').mouseup
	(
		function()
		{ 
			if(!instance.mouse_is_over_chooser && !instance.is_geocoding) instance.hideChooser();
		}
	);
	
	if (this.getLat()) this.setLat(this.getLat());
	if (this.getLng()) this.setLng(this.getLng());
	
	this.triggerFindButton();
}
FormEleGeocoding.prototype = 
{
	getAddress: function()
	{
		return this.input_ele.val();
	},
	
	queueProcess: function()
	{		
		if (!this.is_geocoding_queued)
		{
			this.setLoader();
			
			if (!this.is_geocoding)
			{
				this.is_geocoding_queued = false;
				this.process();
			}
			else
			{
				this.is_geocoding_queued = true;
				var instance = this;
				setTimeout
				(
					function()
					{
						instance.is_geocoding_queued = false;
						instance.queueProcess();
					},
					this.delay
				);
			}
		}
	},
	
	process: function()
	{		
		address = this.getAddress();
				
		if (address.length < this.min_length)
		{
			this.is_geocoding = false;
			
			this.setChooserLabel('Пожалуйста, уточните адрес.');
		}
		else
		{
			this.is_geocoding = true;
			
			this.setLoader();
			
			var instance = this;
			
			params =
			{
				geocode: address,
				key: this.ymaps_key,
				format: 'json',
				results: 11
			};
			
			$.ajax
			(
				{
					type: 'GET',
					url: 'http://geocode-maps.yandex.ru/1.x/?' + $.param(params) + '&callback=?',
					dataType: 'json',
					timeout: 30000, // 30 sec
					success: function (_data)
					{
						if (_data.response && _data.response.GeoObjectCollection && _data.response.GeoObjectCollection.featureMember)
						{
							results = _data.response.GeoObjectCollection.featureMember;
							
							if (results.length > instance.max_results) {
								
								instance.setChooserLabel('Пожалуйста, уточните адрес.');
								
							} else if (results.length) {
								
								instance.setChooserResults(results);
								
							} else {
								
								instance.setChooserResults();
								
							}
						}	
						else
						{
							console.log(_data);
							instance.setError('пожалуйста, повторите попытку позже');
						}
					},
					complete: function(_jqXHR, _text_status)
					{
						setTimeout(function() { instance.is_geocoding = false; }, instance.delay);
						
						switch (_text_status)
						{
							case 'error':
							case 'timeout':
							case 'abort':
							case 'parsererror':
								console.log(_text_status);
								instance.setError('пожалуйста, повторите попытку позже');
								break;
						}
					}
				}
			);
		}
	},
	
	getLat: function()
	{
		return this.lat_input_ele.val();
	},
	
	setLat: function(_value)
	{
		this.lat_input_ele.val(_value);
		this.lat_label_ele.html('Широта: ' + _value);
	},
	
	getLng: function()
	{
		return this.lng_input_ele.val();
	},
	
	setLng: function(_value)
	{
		this.lng_input_ele.val(_value);
		this.lng_label_ele.html('Долгота: ' + _value);
	},
	
	getChooserEle: function()
	{
		return this.chooser_ele;
	},
	
	setChooserLabel: function(_text)
	{
		chooser_ele = this.getChooserEle();
		
		chooser_ele.html('<p>' + _text + '</p>');
		
		this.showChooser();
	},
	
	setChooserResults: function(_results)
	{
		var instance = this;
		
		chooser_ele = this.getChooserEle();		
		chooser_ele.empty();
		this.results = [];
		
		html = '<ul>';
		
		if (_results && _results.length)
		{
			for (i = 0; i < _results.length && i < 50; i++)
			{
				cur_address = _results[i].GeoObject.metaDataProperty.GeocoderMetaData.text;
				
				cur_coord = _results[i].GeoObject.Point.pos.split(' ');
				cur_lng = cur_coord[0];
				cur_lat = cur_coord[1];
				
				this.results.push
				(
					{
						address: cur_address,
						lat: cur_lat,
						lng: cur_lng
					}
				);
				result_id = this.results.length - 1;
				
				html += '<li>'
					+ '<a class="result-item" rel="' + result_id + '"'
					+ ' href="javascript:void(0);"'
					+ '>' + cur_address + '</a>'
					+ '</li>';
			}
		}
		else
		{
			html += '<li>Адрес не найден</li>';
		}
		
//		html += '<li>'
//			+ '<a class="result-custom"
//			+ ' href="javascript:void(0);"'
//			+ '>-&nbsp;Указать вручную...</a>'
//			+ '</li>';
		
		html += '</ul>';
		
		chooser_ele.html(html);
		
		$('.result-item', chooser_ele).click
		(
			function()
			{
				instance.setResultItem($(this).attr('rel'));
			}
		);
		
		$('.result-custom', chooser_ele).click
		(
			function()
			{
				instance.openCustomResultPopup();
			}
		);
		
		this.showChooser();
	},
	
	showChooser: function()
	{
		this.chooser_ele.show();
	},
	
	hideChooser: function()
	{
		this.chooser_ele.hide();
	},
	
	setResultItem: function(_id)
	{
		if (this.results[_id])
		{
			this.setValue(this.results[_id].lat, this.results[_id].lng, this.results[_id].address);
			this.hideChooser();
		}
	},
	
	openCustomResultPopup: function()
	{
		cur_lat = this.getLat();
		cur_lng = this.getLng();
		if (cur_lat == cur_lng && cur_lng  == '0') cur_lat = cur_lng = '';
		popup_uri = '/popups/coordinates.html#' + this.ele_id;
		if (cur_lat != '' && cur_lng != '') popup_uri += ':' + cur_lat + ':' + cur_lng;
		
//		li_ele.innerHTML = '<a href="javascript:void(0);"'
//			+ ' onclick="'
//				+ 'window.open(\'' + popup_uri + '\', \'Coordinates\', \'menubar=no,location=no,resizable=yes\');'
//				+ ' document.getElementById(\'' + this.ele_id + '_chooser\').innerHTML = \'\';'
//				+ ' document.getElementById(\'' + this.ele_id + '_chooser\').style.display = \'none\';'
//			+ '">-&nbsp;Указать вручную...</a>';
	},
	
	setValue: function(_lat, _lng, _address)
	{
		this.setLat(_lat);
		this.setLng(_lng);
		
		if (_address) this.input_ele.val(_address);
	},
	
	setLoader: function()
	{
		this.setChooserLabel('Загрузка...');
	},
	
	setError: function(_text)
	{
		this.setChooserLabel('Ошибка: ' + _text);
	},
	
	triggerFindButton: function()
	{
		if (this.getAddress().length > 0) {
			this.find_button_ele.removeAttr('disabled');
		} else {
			this.find_button_ele.attr('disabled', 'disabled');
		}
	}
}
