﻿// watermark plugin помещает watermark в input.value,
// поэтому сначала нужно убрать watermark, а потом вернуть
function getTextInputValue(input) {
	// в watermark plugin есть баг: 
	// если watermarkа нет и value нет, то после $.watermark.show value может стать "null"
	if (($.watermark) && ($(input).val() != "")) {
		$.watermark.hide(input);
		var value = $(input).val();
		$.watermark.show(input);
		return value;
	} else {
		return $(input).val();
	}
}

function isTextInputEmptyOrWhitespace(input) {
	return $.trim(getTextInputValue(input)).length == 0;
}

// watermark plugin помещает watermark в input.value,
// поэтому сначала нужно убрать watermark, а потом вернуть,
// а чтобы plugin узнал об изменении значения inputа,
// нужно вызвать специальную функцию watermark()
function setTextInputValue(input, value) {
	if ($.watermark)
		$.watermark.hide(input);

	$(input).val(value == null ? "" : value);

	if ($.watermark) {
		$(input).watermark();
		$.watermark.show(input);
	}
}

function switchHouseType() {
	var isEstate = $("#IsEstate").val() == "True";
	setHouseType(!isEstate);
}

function setHouseType(isEstate) {
	$("#IsEstate").val(isEstate ? "True" : "False");
	$("#HouseLabel").css("display", isEstate ? "none" : "");
	$("#EstateLabel").css("display", isEstate ? "" : "none");
	$(isEstate ? "#EstateWatermark" : "#HouseWatermark").each(function () { $("#House").watermark($(this).text()) });
}

function switchFlatType() {
	var isOffice = $("#IsOffice").val() == "True";
	setFlatType(!isOffice);
}

function setFlatType(isOffice) {
	$("#IsOffice").val(isOffice ? "True" : "False");
	$("#FlatLabel").css("display", isOffice ? "none" : "");
	$("#OfficeLabel").css("display", isOffice ? "" : "none");
	$(isOffice ? "#OfficeWatermark" : "#FlatWatermark").each(function () { $("#Flat").watermark($(this).text()) });
}

function disableSelectSeparators(select) {
	$("option[value^=separator]", $(select)).attr("disabled", "disabled");
}

function rebindSelect(select, data) {
	$("option", $(select)).remove();

	$.each(data, function () {
		$(select).append($("<option></option>").attr("value", this.Value).text(this.Text));
	});
	disableSelectSeparators(select);

	// Для нормальной работы uniform select нужно вызвать change при изменении options
	$(select).trigger("change", true);
}

function removeAllNonEmptyOptions(select) {
	$("option[value!=]", $(select)).remove();

	// Для нормальной работы uniform select нужно вызвать change при изменении options
	$(select).trigger("change", true);
}

function changeCityEnterMode(fromList) {
	if (fromList) {
		$("#IsUnknownCity").val("False");
		$("#CityFromListBlock").show();
		$("#CityByHandBlock").hide();
		$("#CityFromList").val("");
	} else {
		$("#IsUnknownCity").val("True");
		$("#CityFromListBlock").hide();
		$("#CityByHandBlock").show();

		if ($("#CityFromList").val().substr(0, 'unknown'.length) != 'unknown')
			$("#CityFromList").val("unknown1");

		$("#Street").attr("mandatory", "true");
	}

	setTextInputValue("#CityByHand", "");

	// Для нормальной работы uniform select нужно вызвать change при изменении value
	$("#CityFromList").trigger("change", true);

	enforcePostAddressRules();
}

function isNumericString(value) {
	return value.match(/^\d+$/) != null;
}

function setSelectDisabledState(select, isDisabled) {
	if (isDisabled)
		$(select).attr("disabled", "disabled");
	else
		$(select).removeAttr("disabled");

	// Для нормальной работы uniform select нужно вызывать change при изменении disabled
	$(select).trigger("change", true);
}

function setTextInputDisabledState(input, isDisabled) {
	if (isDisabled)
		$(input).attr("disabled", "disabled");
	else
		$(input).removeAttr("disabled");

	// watermark plugin использует встроенную в Google Chrome поддержку watermark,
	// но в ней есть баг: disabled watermark показывается другим цветом, 
	// но при изменении disabled, цвет не изменяется, пока не изменится значение watermark
	// или пока input не получит фокус
	$(input).each(
		function () {
			var oldPlaceholder = $(this).attr("placeholder");
			if (oldPlaceholder) {
				$(this).attr("placeholder", "");
				$(this).attr("placeholder", oldPlaceholder);
			}
		});
}

function enforcePostAddressRules() {
	var hasRegion = isNumericString($("#Region").val());

	if (!hasRegion) {
		$("#Rayon").val("");

		// Для нормальной работы uniform select нужно вызвать change при изменении value
		$("#Rayon").trigger("change", true);

		removeAllNonEmptyOptions("#Rayon");
	}
	setSelectDisabledState("#Rayon", !hasRegion || ($("#Rayon option").size() <= 1));

	if (!hasRegion) {
		$("#IsUnknownCity").val("False");
		$("#CityFromList").val("");

		// Для нормальной работы uniform select нужно вызвать change при изменении value
		$("#CityFromList").trigger("change", true);

		removeAllNonEmptyOptions("#CityFromList");
		setTextInputValue("#CityByHand", "");
		$("#CityFromListBlock").show();
		$("#CityByHandBlock").hide();
	}
	setSelectDisabledState("#CityFromList", !hasRegion);
	setTextInputDisabledState("#CityByHand", !hasRegion);
	var hasCity = isNumericString($("#CityFromList").val()) || !isTextInputEmptyOrWhitespace("#CityByHand");

	if (!hasCity) setTextInputValue("#Street", "");
	setTextInputDisabledState("#Street", !hasCity);
	var hasStreet = !isTextInputEmptyOrWhitespace("#Street");
	var streetIsRequired = ($("#Street").attr("mandatory") == "true") || ($("#IsUnknownCity").val() == "True");
	var canEnterDataAfterStreet = hasCity && (hasStreet || !streetIsRequired);

	if (canEnterDataAfterStreet) {
		$("#HouseSwitch,#EstateSwitch").removeAttr("disabled");
	} else {
		setTextInputValue("#House,#Building,#Stroenie", "");
		$("#HouseSwitch,#EstateSwitch").attr("disabled", "disabled");
		setHouseType(false);
	}
	setTextInputDisabledState("#House,#Building,#Stroenie", !canEnterDataAfterStreet);
	var hasHouse = !isTextInputEmptyOrWhitespace("#House");
	var hasBuilding = !isTextInputEmptyOrWhitespace("#Building");
	var hasStroenie = !isTextInputEmptyOrWhitespace("#Stroenie");
	var canEnterDataAfterStroenie = hasHouse || hasBuilding || hasStroenie;

	if (canEnterDataAfterStroenie) {
		$("#FlatSwitch,#OfficeSwitch").removeAttr("disabled");
	} else {
		setTextInputValue("#Flat", "");
		$("#FlatSwitch,#OfficeSwitch").attr("disabled", "disabled");
		setFlatType(false);
	}
	setTextInputDisabledState("#Flat", !canEnterDataAfterStroenie);
}

function onPostIndexChanged() {
	var postIndex = getTextInputValue("#PostIndex");

	if (!isNumericString(postIndex))
		return;

	if (postIndex.length != 6)
		return;

	$.ajax({
		url: '/postaddress/onpostindexchanged',
		dataType: 'json',
		data: {
			PostIndex: getTextInputValue("#PostIndex"),
			RegionId: $("#Region").val(),
			RayonId: $("#Rayon").val(),
			CityId: $("#CityFromList").val(),
			CityName: getTextInputValue("#CityByHand"),
			StreetName: getTextInputValue("#Street")
		},
		async: false,
		success: function (json) {
			if (json.RegionId != null) {
				if (json.RegionId != $("#Region").val()) {
					$("#Region").val(json.RegionId);
					$("#Region").trigger("change");
				}

				setFocusAfterRegion();
			}

			if (json.RayonId != null) {
				if (json.RayonId != $("#Rayon").val()) {
					$("#Rayon").val(json.RayonId);
					$("#Rayon").trigger("change");
				}

				$("#CityFromList").focus();
			}

			if (json.CityId != null) {
				if (json.CityId != $("#CityFromList").val()) {
					$("#CityFromList").val(json.CityId);
					$("#CityFromList").trigger("change");
				}

				if ((json.CityName != null) && (json.CityName != getTextInputValue("#CityByHand"))) {
					setTextInputValue("#CityByHand", json.CityName);
					enforcePostAddressRules();
				}

				$("#Street").focus();
			}

			if (json.StreetName != null) {
				if (json.StreetName != getTextInputValue("#Street")) {
					setTextInputValue("#Street", json.StreetName);
					enforcePostAddressRules();
				}

				$("#House").focus();
			}
		}
	});
}

function onRegionChanged() {
	$.ajax({
		url: '/postaddress/onregionchanged',
		dataType: 'json',
		data: {
			RegionId: $("#Region").val()
		},
		async: false,
		success: function (json) {
			rebindSelect("#Rayon", json.Rayons);
			rebindSelect("#CityFromList", json.Cities);
			$("#Rayon").val("");

			// Для нормальной работы uniform select нужно вызвать change при изменении value
			$("#Rayon").trigger("change", true);

			changeCityEnterMode(true);
			enforcePostAddressRules();
			setFocusAfterRegion();
		}
	});
}

function setFocusAfterRegion() {
	if ($("#Rayon option").size() <= 1)
		$("#CityFromList").focus();
	else
		$("#Rayon").focus();
}

function onRayonChanged() {
	$.ajax({
		url: '/postaddress/onrayonchanged',
		dataType: 'json',
		data: {
			RegionId: $("#Region").val(),
			RayonId: $("#Rayon").val()
		},
		async: false,
		success: function (json) {
			rebindSelect("#CityFromList", json);
			changeCityEnterMode(true);
			enforcePostAddressRules();
			$("#CityFromList").focus();
		}
	});
}

function onCityFromListChanged() {
	if ($("#CityFromList").val().substr(0, 'unknown'.length) == 'unknown') {
		changeCityEnterMode(false);
		$("#CityByHand").focus();
	} else if (isNumericString($("#CityFromList").val())) {
		$.ajax({
			url: '/postaddress/oncitychanged',
			dataType: 'json',
			data: {
				RayonId: $("#Rayon").val(),
				CityId: $("#CityFromList").val()
			},
			async: false,
			success: function (json) {
				var newRayon = json.RayonId == null ? "" : json.RayonId;
				if ($("#Rayon").val() != newRayon) {
					$("#Rayon").val(newRayon);

					// Для нормальной работы uniform select нужно вызвать change при изменении value
					$("#Rayon").trigger("change", true);

					rebindSelect("#CityFromList", json.NewRayonCities);
					$("#CityFromList").val(json.NewCityId);

					// Для нормальной работы uniform select нужно вызвать change при изменении value
					$("#CityFromList").trigger("change", true);

					if ($("#CityFromList").val().substr(0, 'unknown'.length) == 'unknown') {
						changeCityEnterMode(false);
						setTextInputValue("#CityByHand", json.CityName)
					}
				}

				$("#Street").attr("mandatory", json.StreetRequired);
				$("#Street").focus();
			}
		});
	}

	enforcePostAddressRules();
}

function trackTextInputChanges(input, handler) {
	$(input).bind(
		"keyup",
		function () {
			handler();
			$(this).attr("lastValue", getTextInputValue(this));
			return false;
		});
	$(input).each(
		function () {
			$(this).attr("lastValue", getTextInputValue(this));
		});
	window.setInterval(
		function () {
			$(input).each(
				function () {
					if (getTextInputValue(this) != $(this).attr("lastValue")) {
						handler();
						$(this).attr("lastValue", getTextInputValue(this));
					}
				});
		},
		500);
}

$(document).ready(
		function () {
			if ($("#Flat").size() == 0) return;

			disableSelectSeparators("#Region");

			var isUnknownCity = $("#IsUnknownCity").val();

			if (isUnknownCity == "False") {
				$("#CityFromListBlock").show();
				$("#CityByHandBlock").hide();
			} else {
				$("#CityFromListBlock").hide();
				$("#CityByHandBlock").show();
			}

			enforcePostAddressRules();

			$("#HouseSwitch,#EstateSwitch").bind(
				"click",
				function () {
					if ($(this).attr("disabled") != "disabled") switchHouseType();
					return false;
				}
			);

			$("#FlatSwitch,#OfficeSwitch").bind(
				"click",
				function () {
					if ($(this).attr("disabled") != "disabled") switchFlatType();
					return false;
				}
			);

			trackTextInputChanges("#PostIndex", onPostIndexChanged);

			// Для нормальной работы uniform select нужно вызывать change при изменении disabled
			// isFake предотвращает JSON запрос на сервер при этом
			$("#Region").bind(
				"change",
				function (e, isFake) {
					if (!isFake) onRegionChanged();
					return false;
				}
			);

			// Для нормальной работы uniform select нужно вызывать change при изменении disabled
			// isFake предотвращает JSON запрос на сервер при этом
			$("#Rayon").bind(
				"change",
				function (e, isFake) {
					if (!isFake) onRayonChanged();
					return false;
				}
			);

			// Для нормальной работы uniform select нужно вызывать change при изменении disabled
			// isFake предотвращает JSON запрос на сервер при этом
			$("#CityFromList").bind(
				"change",
				function (e, isFake) {
					if (!isFake) onCityFromListChanged();
					return false;
				}
			);

			$("#CityByHand").autocomplete(
				'/postaddress/cityautocomplete',
				{
					extraParams: {
						PostIndex: function () { return getTextInputValue("#PostIndex"); },
						RegionId: function () { return $("#Region").val(); },
						RayonId: function () { return $("#Rayon").val(); }
					},
					minChars: 3,
					max: 200,
					autoFill: true,
					selectFirst: false
				}
			);

			$("#CityEnterModeSwitch").bind(
				"click",
				function (e) {
					changeCityEnterMode(true);
					$("#CityFromList").focus();
					return false;
				}
			);

			$("#Street").autocomplete(
				'/postaddress/streetautocomplete',
				{
					extraParams: {
						PostIndex: function () { return getTextInputValue("#PostIndex"); },
						RegionId: function () { return $("#Region").val(); },
						RayonId: function () { return $("#Rayon").val(); },
						CityId: function () { return $("#CityFromList").val(); },
						CityName: function () { return getTextInputValue("#CityByHand"); }
					},
					minChars: 3,
					max: 200,
					autoFill: true,
					selectFirst: false
				}
			);

			trackTextInputChanges("#CityByHand,#Street,#House,#Building,#Stroenie", enforcePostAddressRules);
		}
	);