(function(){
var strtrArr = {"f":"а",",":"б","<":"б","d":"в","u":"г","l":"д","t":"е","`":"ё","~":"ё",";":"ж",":":"ж","p":"з","b":"и","q":"й",
"r":"к","k":"л","v":"м","y":"н","j":"о","g":"п","h":"р","c":"с","n":"т","e":"у","a":"ф","[":"х","{":"х","w":"ц","x":"ч","i":"ш",
"o":"щ","m":"ь","s":"ы","]":"ъ","}":"ъ","'":"э","\"":"э",".":"ю",">":"ю","z":"я"};
function strtr(str){
	str = str.toLowerCase();
	str = str.replace(/./g, function(s){
		return strtrArr[s]?strtrArr[s]:s;
	});
	return str;
}

function fieldOnAfterKey(){ /* this = input */
	if (this.value == this.previousValue) return;
	this.previousValue = this.value;
	if (this.value == ""){
		$(".js-kladr-options", this.owner).css("display", "none").html("");
	} else {
		getOptions.call(this.owner);
	};
}
function fieldOnKey(e){ /* this = input */
	var self = this;
	setTimeout(function(){
		fieldOnAfterKey.call(self);
	}, 0)
}
function fieldOnKeyDown(e){ /* this = input */
	var key = (e.keyCode||e.which);
	if (key == 38 || key == 40){
		optionMove.call(this.owner, key==38);
		e.preventDefault();
		return false;
	};
	if (key == 27) {
		closeEdit.call(this.owner);
		return false;
	};
	if (key == 13) {
		optionApplyKeyboard.call(this.owner);
		return false;
	}
}
function fieldOnKeyPress(e){ /* this = input */
	var key = (e.keyCode||e.which);
	if (key == 38 || key == 40 || key == 27 || key == 13){
		return false;
	};
};
function getOptions(){ /* this = group DOM Element */
	var self = this;
	var selfFunction = arguments.callee;
	var val = strtr(this.field.value);
	var callback = function(){
		selfFunction.cache[val] = arguments[0];
		drawOptions.apply(self, arguments)
	};
	if (selfFunction.runawayXHR && selfFunction.runawayXHR.abort) selfFunction.runawayXHR.abort();
	if (!selfFunction.cache){
		selfFunction.cache = {};
	};
	if (selfFunction.cache[val]){
		callback(selfFunction.cache[val]);
	} else {
		// selfFunction.runawayXHR = jQuery.getJSON("/ajax/kladr/", {"kladr_name": val}, callback);
		selfFunction.runawayXHR = jQuery.ajax({
			"async": true,
			"cache": true,
			"success": function(data){callback(data)},
			"data": {"kladr_name": val},
			"dataType": "json",
			"type": "post",
			"url": "/ajax/kladr/"
		});
	};
}
function drawOptions(o){ /* this = group DOM Element */
	var self = this;
	var response = o.response;
	var highlight = o.request;
	var options = $(".js-kladr-options", this).get(0);
	if (!options) throw new Error("There is no options group!");
	$(options).html("");
	$(options).css({"left": "0px"});
	if (response.length == 0){
		$(options).html('<span class="js-kladr-options-message">Ничего не найдено</span>')
	} else {
		var addrFieldChunks = ["city", "district", "region"];
		
		for (var i=0; i<response.length; i++){
			var responseItem = response[i];
			var option = document.createElement("span");
			option.className = "js-kladr-option" + (j?'':' js-kladr-option-active');
			option.responseItem = responseItem;
			option.owner = this;
			
			var addrChunks = [];
			responseItem.foundName = "";
			
			for (var j=0; j<addrFieldChunks.length; j++){
				var addrType = responseItem[addrFieldChunks[j] + "_type"];
				var addrName = responseItem[addrFieldChunks[j] + "_name"];
				if (!addrName) continue;
				if (!responseItem.foundName) responseItem.foundName = (self.isSmall?"":(addrType||"") + " ") + addrName;
				if (addrName.toLowerCase().indexOf(highlight.toLowerCase()) == 0){
					// addrName = addrName.replace(highlight, '<span class="js-kladr-option-highlight">' + highlight + '</span>')
					addrName = ('<span class="js-kladr-option-highlight">' + addrName.substring(0, highlight.length) + '</span>' + addrName.substring(highlight.length));
				}
				addrChunks.push('<span class="js-kladr-option-type">' + addrType + '</span>' + " " + addrName);
			}
			$(option).html(addrChunks.join(' <span class="js-kladr-option-separator">&raquo;</span> '));
			options.appendChild(option);
			$(option).hover(optionHover);
			$(option).bind("click", optionApply);
		};
		$(options).css({"display": "block"});
		var screenWidth = $(document.body).outerWidth();
		var optOffset = $(options).offset().left;
		var optWidth = $(options).outerWidth();
		if (optWidth + optOffset > screenWidth){
			$(options).css({"left": Math.min(0, screenWidth - optOffset - optWidth) + "px"});
		}
	};
}
function optionHover(){ /* this = option DOM element */
	$(this).closest(".js-kladr-options").find(".js-kladr-option").removeClass("js-kladr-option-active");
	$(this).addClass("js-kladr-option-active");
}
function optionMove(up){ /* this = group DOM element */
	$options = $(".js-kladr-options .js-kladr-option", this);
	var count = $options.size();
	var index = $options.index($(".js-kladr-options .js-kladr-option-active", this));
	if (index < 0){
		index = 0;
	};
	$options.removeClass("js-kladr-option-active");
	$options.eq((index + count + (up?-1:1))%count).addClass("js-kladr-option-active");
}
function fieldOnBlur(e){ /* this = input DOM Element */
	var self = this;
	window.e = e;
	if (this.keepFocus){
		this.keepFocus = false;
		this.focus();
	} else {
		setTimeout(function(){
			closeEdit.call(self.owner)
		}, 0);
	};
}
function closeEdit(){ /* this = group DOM Element */
	$(this).removeClass("js-kladr-group-editmode");
	$(".js-kladr-options", this).css('display', 'none').html();
}
function changeMode(){ /* this = group DOM Element */
	var $this = $(this);
	this.isSmall = !!$this.hasClass("js-kladr-group-small");
	this.isInstall = !!$this.hasClass("js-kladr-group-install")
	if ($this.hasClass("js-kladr-group-editmode")){
		$this.removeClass("js-kladr-group-editmode");
	} else {
		$this.addClass("js-kladr-group-editmode");
		var field = $(".js-kladr-input", $this).get(0);
		if (!field) throw new Error('There is no input field!');
		this.field = field;
		field.previousValue = field.value = "";
		field.focus();
		field.keepFocus = false;
		field.owner = this;
		var $options = $(".js-kladr-options", $this);
		$options.css({'display': 'block', 'left': '0px'}).html('<span class="js-kladr-options-message">Введите первые буквы населенного пункта</span>');
		
		if ($options.offset().top + 400 > $(document).scrollTop() + $(window).height()){
			$options.addClass("js-kladr-options-above");
		} else {
			$options.removeClass("js-kladr-options-above");
		}
		
		if (!field.eventsApplied){
			$(field).bind('keyup', fieldOnKey);
			$(field).bind('keypress', fieldOnKeyPress);
			$(field).bind('keydown', fieldOnKeyDown);
			$(field).bind('blur', fieldOnBlur);
			field.eventsApplied = true;
		};
		$(field).css("width", "");
		if ($(field).width() < 100){
			$(field).width(100);
		}
	};
}
function optionApply(){ /* this = option DOM Element */
	var owner = this.owner;
	$("input.js-kladr-code-region", owner).val(this.responseItem['code_region']||"");
	$("input.js-kladr-code-district", owner).val(this.responseItem['code_district']||"");
	$("input.js-kladr-code-city", owner).val(this.responseItem['code_city']||"");
	$(".js-kladr-static", owner).html(this.responseItem.foundName);
	document.cookie = "kladr=" + (this.responseItem['code_region'] + '-' + this.responseItem['code_district'] + '-' + this.responseItem['code_city']) + "; path=/";
	$(".js-kladr-delivery-block").load((owner.isInstall?"/ajax/mounting_list/":"/ajax/delivery_list/") + "?" + this.responseItem['code_region'] + this.responseItem['code_district'] + this.responseItem['code_city'] + (owner.isSmall?"&delivery_list_small":""));
	closeEdit.call(owner);
	owner.field.keepFocus = false;
}
function optionApplyKeyboard(){ /* this = group DOM Element */
	var selectedOption = $(".js-kladr-option-active", this).get(0);
	if (!selectedOption) return false;
	optionApply.call(selectedOption);
}
$(".js-kladr-prompt").live('click', function(){
	var $owner = $(this).closest(".js-kladr-group");
	if ($owner.size()){
		changeMode.call($owner.get(0));
	};
	
	return false;
})

$(".js-kladr-group-editmode").live('mousedown', function(){
	this.field.keepFocus = true;

})
})()
