
<!-------------------------------------------------------------------------------------------->

<!-----------------------------------------Subsidiary functions-------------------------------------------------->
		
function CheckAccount(newAccount)
{
	var sum = 0;
	var factors = Array(7,1,3,7,1,3,7,1,3,7,1,3,7,1,3,7,1,3,7,1,3,7,1);
	for(var i = 0; i < 23; i++)
		sum += newAccount.charAt(i)*factors[i]; 
	if (sum % 10 == 0)
		return true;
	else
		return false;
}
			
function CheckRegNumber(RegNumber)
{
	var numberLength = RegNumber.length;
	var controlDigit = RegNumber.substring(numberLength - 1) * 1;
	var newRegNumber = RegNumber.substring(0,(numberLength - 1))*1;
	if (newRegNumber-(parseInt(newRegNumber / (numberLength - 2)))*(numberLength - 2) == controlDigit)
		return true;
	else
		return false;
}

function CheckIndTaxNumber(IndTaxNumber)
{
	var sum = 0;
	if (IndTaxNumber.length == 12)   
	{
		var sControlDigit, fControlDigit;
		var factors1 = Array(7,2,4,10,3,5,9,4,6,8);
		var factors2 = Array(3,7,2,4,10,3,5,9,4,6,8);
		var tenIndTaxNumber = IndTaxNumber.substring(0,10);
		for(var i = 0; i < 10; i++)
			sum += tenIndTaxNumber.charAt(i)*factors1[i];
		fControlDigit = sum - parseInt(sum/11)*11;
		if (fControlDigit == 10)
			fControlDigit = 0;
		sum = 0;
		var elevenIndTaxNumber = IndTaxNumber.substring(0,11);
		
		for(i = 0; i < 11; i++)
			sum += elevenIndTaxNumber.charAt(i)*factors2[i];
		
		sControlDigit = sum - parseInt(sum/11)*11;
		
		if (sControlDigit == 10)
			sControlDigit = 0;
		
		if(IndTaxNumber.substring(10,11) == fControlDigit && IndTaxNumber.substring(11,12) == sControlDigit)
			return true;
		else
			return false;
	}
	
	if (IndTaxNumber.length == 10)   
	{
		var ControlDigit = 0;
		var factors = Array(2,4,10,3,5,9,4,6,8);
		var nineIndTaxNumber = IndTaxNumber.substring(0,9);
		for(var i = 0; i < 9; i++)
			sum += nineIndTaxNumber.charAt(i)*factors[i];
		ControlDigit = sum - parseInt(sum/11)*11;
		if (ControlDigit == 10)
			ControlDigit = 0;
		if(IndTaxNumber.substring(9,10) == ControlDigit)
			return true;
		else
			return false;
	}
}

function NoQuots(evt)
{
	var eventObj = evt || window.event;
	var unicode = (eventObj.which) ? eventObj.which : event.keyCode
		if( unicode == 34 || unicode == 39 )
			(document.all) ? eventObj.returnValue = false : eventObj.preventDefault();
}

function OnlyDigits(evt)
{
	var eventObj = evt || window.event;
	var unicode = (eventObj.which) ? eventObj.which : eventObj.keyCode;
//alert(unicode);
	var allowedKey = true;
	if ((unicode < 48 || unicode > 57) && !IsAllowedKey(unicode))
	{ 	
		(document.all) ? eventObj.returnValue = false : eventObj.preventDefault();
	}
}

function OnlyRussianChars(evt)
{
	var eventObj = evt || window.event;
	var unicode = (eventObj.which) ? eventObj.which : eventObj.keyCode
	//alert(unicode);
	if (((unicode < 1025) || (unicode > 1105)) && (!IsAllowedKey(unicode))) 
		(document.all) ? eventObj.returnValue = false : eventObj.preventDefault();
}

function CharsForLogin(evt)
{
	var eventObj = evt || window.event;
	var unicode = (eventObj.which) ? eventObj.which : eventObj.keyCode
	if (((unicode < 65) || (unicode > 90 && unicode < 97) || (unicode > 122)) && (!IsAllowedKey(unicode))) 
		(document.all) ? eventObj.returnValue = false : eventObj.preventDefault();
}

function EngCharsDigits(evt)
{
	var eventObj = evt || window.event;
	var unicode = (eventObj.which) ? eventObj.which : eventObj.keyCode
	if (((unicode < 48) || (unicode > 57  && unicode < 65) ||
	 (unicode > 90 && unicode < 97) || (unicode > 122)) && (!IsAllowedKey(unicode))) 
		(document.all) ? eventObj.returnValue = false : eventObj.preventDefault();
}

function isValidDate(date) //mm/dd/yyyy
{
	var today = new Date();
	var year = today.getFullYear();
	var dateArray = date.split("/");
	if(dateArray[1] > 31 || dateArray[1] < 1)
		{ return false; }
	if(dateArray[0] > 12 || dateArray[0] < 1)
		{ return false; }
	if((year - dateArray[2]) > 80 || (year - dateArray[2]) < 14)
		{  return false; }
	
	return true;
}

function isEmpty(str)
{
	for (var i = 0; i < str.length; i++)
		if (" " != str.charAt(i))
			return false;
	return true;
}

/* TM */
var CharsRussianUpperCase = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЬЫЪЭЮЯ";
var CharsRussianLowerCase = "абвгдеёжзийклмнопрстуфхцчшщьыъэюя";
var CharsRussian = CharsRussianUpperCase+CharsRussianLowerCase;

var CharsLatinUpperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var CharsLatinLowerCase = "abcdefghijklmnopqrstuvwxyz";
var CharsLatin = CharsLatinUpperCase + CharsLatinLowerCase;
var CharsDigits = "0123456789";

function IsValidString(str, charset) {
	for (var i = 0; i < str.length; i++)
	{
		var c = str.charAt(i);
		if (charset.indexOf(c) < 0) {
			return false;
		}
	}
	return true;
}

function IsValidLastName(str) {
	if (str.length == 0 || !IsValidString(str, CharsRussian + "-")) {
		return false;
	}
	if (str[0] == "-" || str[str.length-1] == "-") {
		return false;
	}
	return true;
}
function IsValidFirstName(str) {
	return (str.length > 0 && IsValidString(str, CharsRussian));
}
function IsValidMiddleName(str) {
	return (str.length > 0 && IsValidString(str, CharsRussian));
}
function IsValidLogin(str) {
	return (str.length >= MinLoginLength && IsValidString(str, CharsLatin + CharsDigits));
}
function IsValidCityName(str) {
	str = trim(str);
	
	return (str.length >= 0 && IsValidString(str, CharsRussian + CharsDigits + " .-") && !IsValidString(str, CharsDigits + " .-"));
}

function isRussianString(str)
{
	for (var i = 0; i < str.length; i++)
	{
		var code = str.charCodeAt(i);
		if (((code < 1025) || (code > 1105)) && (!IsAllowedKey(code)) && (code != 32)) 
			return false;
	}
	return true;
}

function isEngCharsAndDigits(str)
{
	for (var i = 0; i < str.length; i++)
	{
		var code = str.charCodeAt(i);
		if ( (code < 48) || (code > 57  && code < 65) ||
				(code > 90 && code < 97) || (code > 122) 
			 || (!IsAllowedKey(code)) || (!IsAllowedSymbol(code)) )
		return false;
	}
	return true;
}

function IsAllowedKey(key)
{
						//  home,end,bcksp,tab,SYN,del,arrows
	var allowedKeys = Array(2, 3, 8, 9, 22, 127, 37, 38, 39, 40, 46, 72, 75, 77, 78);  

	for (var i in allowedKeys)
	{
		if (key == allowedKeys[i])
			return true;
	}
	return false;
}

function IsAllowedSymbol(key)
{
						  //    !  @  #  $  %  ^  &  * (   )  - _  +
	var allowedSymbols = Array(33,64,35,36,37,94,38,42,40,41,45,95,43);  

	for (var i in allowedSymbols)
	{
		if (key == allowedSymbols[i])
			return true;
	}
	return false;
}

function isGoodPassword(str)
{
	for (var i = 0; i < str.length; i++)
	{
		var code = str.charCodeAt(i);
		if ( ( (code < 48) || (code > 57  && code < 65) ||
				(code > 90 && code < 97 || code > 122) )
			 && (!IsAllowedKey(code)) && (!IsAllowedSymbol(code)) )
		return false;
	}
	return true;
}

function isGoodLogin(str)
{
	for (var i = 0; i < str.length; i++)
	{
		var code = str.charCodeAt(i);
			if (i == 0)	{
				if( ((code < 48) || 
				    (code > 57  && code < 65) ||
				    (code > 90 && code < 97) || 
				    (code > 122)) && 
			        (!IsAllowedKey(code)) 
				)
				return false;
			}
			else if(  ((code < 45) || (code == 47) || 
					(code == 96) ||
				    (code > 57  && code < 65) ||
				    (code > 90 && code < 95) || 
				    (code > 122)) && 
			        (!IsAllowedKey(code))  
			  )
				return false; 
	}
	return true;
}

function isDigitString(str)
{
	for (var i = 0; i < str.length; i++)
	{
		var code = str.charCodeAt(i);
		if (	((code < 48) || (code > 57) && (code != 32) ) ) 	
			return false;
	}
	return true;
}

function IsPhoneString(str)
{
	for (var i = 0; i < str.length; i++)
	{
		var code = str.charCodeAt(i);
		if (	((code < 48) || (code > 57)) 
				&& (code != 40 && code != 41 && code != 45 && code != 32) 
				&& (!IsAllowedKey(code))
			) 	
			return false;
	}
	return true;
}

function addLoadEvent(func)
{
	var oldonload = window.onload;
	
	if (typeof window.onload != 'function')
	{
		window.onload = func;
	}
	else
	{
		window.onload = function()
		{
			oldonload();
			func();
		}
	}
}

function encode(string)
{
	string = string.replace(/\r\n/g,"\n");
	var utftext = "";
	
	for (var n = 0; n < string.length; n++)
	{
		var c = string.charCodeAt(n);

		if (c < 128)
		{
			utftext += String.fromCharCode(c);
		}
		else if((c > 127) && (c < 2048))
		{
			utftext += "&#" + c + ";";
		}
	}
	return utftext;
}

var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

function base64_encode(input)
{
	var output = "";
	var chr1, chr2, chr3;
	var enc1, enc2, enc3, enc4;
	var i = 0;

	do
	{
		chr1 = input.charCodeAt(i++);
		chr2 = input.charCodeAt(i++);
		chr3 = input.charCodeAt(i++);

		enc1 = chr1 >> 2;
		enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
		enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
		enc4 = chr3 & 63;

		if (isNaN(chr2))
		{
			enc3 = enc4 = 64;
		} else if (isNaN(chr3))
		{
			 enc4 = 64;
		}

		output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + 

			 keyStr.charAt(enc3) + keyStr.charAt(enc4);
	}
	while (i < input.length);

	return output;
}

function base64_decode(input) 
{
	var output = "";
	var chr1, chr2, chr3;
	var enc1, enc2, enc3, enc4;
	var i = 0;

	// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
	input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

	do
	{
		enc1 = keyStr.indexOf(input.charAt(i++));
		enc2 = keyStr.indexOf(input.charAt(i++));
		enc3 = keyStr.indexOf(input.charAt(i++));
		enc4 = keyStr.indexOf(input.charAt(i++));

		chr1 = (enc1 << 2) | (enc2 >> 4);
		chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
		chr3 = ((enc3 & 3) << 6) | enc4;

		output = output + String.fromCharCode(chr1);

		if (enc3 != 64)
		{
			 output = output + String.fromCharCode(chr2);
		}
		if (enc4 != 64)
		{
			 output = output + String.fromCharCode(chr3);
		}
	}
	while (i < input.length);

	return output;
}


function trim(string)
{
	return string.replace(/(^\s+)|(\s+$)/g, "");
}


function ValidateBuyItem(ItemId, ColorId, SizeId) {
	if (trim(ItemId) == "") { DisplayErrorDialog("Не выбран товар"); return false; }
	if (trim(ColorId) == "" || trim(SizeId) == "") { DisplayErrorDialog("<b>Вы забыли указать цвет и размер.</b> <br/><br/>Чтобы положить модель в корзину, выберите желаемые цвет и размер в таблице размеров.<br/>"); return false; }
	return true;
}

function CheckIfFotoExist(colorId, itemId){
	//return;
	var callAjax = false;
	ajaxCache.currentColor = colorId; 
	if (ajaxCache.currentItem == null) ajaxCache.currentItem = itemId;
	if (ajaxCache.fotos ==null) ajaxCache.fotos = [];
	//alert(ajaxCache.fotos[colorId]);
	if (ajaxCache.fotos[colorId] == undefined) callAjax = true; 
	if (ajaxCache.fotos[colorId] == false){
		FotoNotExist();
		return;
	} else {
		ajaxCache.fotos[colorId] = true;
	}
	alert(callAjax);
	//*
	document.getElementById("hugeItemPict_"+itemId).style.display = "inline";
	document.getElementById("size3_"+itemId).style.display = "inline";
	document.getElementById("size4_"+itemId).style.display = "inline";
	document.getElementById("size3_nofoto").style.display = "none";
	document.getElementById("size4_nofoto").style.display = "none";
	document.getElementById("nofoto").style.display = "none";
	//*/
	if (callAjax) xajax_CheckIfFotoExist(colorId, itemId);
}
function FotoNotExist(){
	ajaxCache.fotos[ajaxCache.currentColor] = false;
	
	alert('Not Exist for '+ajaxCache.currentItem);
	
	document.getElementById("hugeItemPict_"+ajaxCache.currentItem).style.display = "none";
	document.getElementById("size3_"+ajaxCache.currentItem).style.display = "none";
	document.getElementById("size4_"+ajaxCache.currentItem).style.display = "none";
	document.getElementById("size3_nofoto").style.display = "inline";
	document.getElementById("size4_nofoto").style.display = "inline";
	document.getElementById("nofoto").style.display = "inline";
}


/* -------------------- */
Customer = function(lname, fname, mname, company, email, bdate, gender, type) {
	var LName;
	var FName;
	var MName;
	var Company;
	var EMail;
	var BirthDate;
	var Gender;
	var Type;

	this.LName = lname;
	this.FName = fname;
	this.MName = mname;

	this.Company = company;
	this.EMail = email;
	this.BirthDate = bdate;
	this.Gender = gender;
	this.Type = type;
}


StatusDisplay = function(id, separatorId) {
	this.DisplayElement = document.getElementById(id);
	if (typeof(separatorId) == "string") {
		this.SeparatorElement = document.getElementById(separatorId);
	}
	else {
		this.SeparatorElement = null;
	}
	
  
	this.ErrorClass = "bill_small_errors_wv";
	this.HintClass =  "bill_small_errors_grey";
	this.ClearClass = "bill_small_errors_grey";
}

StatusDisplay.prototype = {
	showError: function(text) {
		if (typeof(text) != "undefined" && text.length > 0) {
			if (this.SeparatorElement != null) {
				this.SeparatorElement.style.visibility = "visible";
				this.SeparatorElement.className = this.ErrorClass;
			}
			else {
				text = "&#160;&#151;&#160" + text;
			}

			if (this.DisplayElement != null) {
				this.DisplayElement.className = this.ErrorClass;
				this.DisplayElement.style.display = "";
				this.DisplayElement.innerHTML = text;
			}
		}
		
	},
	
	showHint: function(text) {
		if (typeof(text) != "undefined" && text.length > 0) {

			if (this.SeparatorElement != null) {
				this.SeparatorElement.style.visibility = "visible";
				this.SeparatorElement.className = this.HintClass;
			}
			else {
				text = "&#160;&#151;&#160" + text;
			}
		
			if (this.DisplayElement != null) {
				this.DisplayElement.className = this.HintClass;
				this.DisplayElement.style.display = "";
				this.DisplayElement.innerHTML = text;
			}
		}
		else {
			this.clear();
		}
	},
	
	clear: function() {
		if (this.DisplayElement != null) {
			this.DisplayElement.className = this.ClearClass;
			this.DisplayElement.style.display = "none";
		}
		
		if (this.SeparatorElement != null) {
			this.SeparatorElement.style.visibility = "hidden";
			this.SeparatorElement.className = this.ClearClass;
		}
	}
}

function attachEventHandler(obj, methodName){
    /* The returned inner function is intended to act as an event
       handler for a DOM element:-
    */
    return (function(e){
        /* The event object that will have been parsed as the - e -
           parameter on DOM standard browsers is normalised to the IE
           event object if it has not been passed as an argument to the
           event handling inner function:-
        */
        e = e||window.event;
        /* The event handler calls a method of the object - obj - with
           the name held in the string - methodName - passing the now
           normalised event object and a reference to the element to
           which the event handler has been assigned using the - this -
           (which works because the inner function is executed as a
           method of that element because it has been assigned as an
           event handler):-
        */
        return obj[methodName](e, this);
    });
}
 
EMailValidator = function(id, statusDisplay, form) {
  this.TextBox = document.getElementById(id);
  this.StatusDisplay = statusDisplay;
  this.Form = document.getElementById(form);

  this.Errors = new Array();
  this.Errors["Hint"] = "";
  
  this.Errors["InvalidEMail"] = "введите действительный электронный адрес"; // email_h
  
  this.Errors["EmptyEMail"] = "введите адрес электронной почты";	// email_f0
  this.Errors["EmptyEMailMessage"] = "Вы забыли ввести E-mail. Пожалуйста, заполните это поле.<br/>";	// email_w0

  this.Errors["InvalidChars"] = "исправьте недопустимые символы"; // email_f1
  this.Errors["InvalidCharsMessage"] = "<b>В поле E-mail вы использовали недопустимые символы. Исправьте, пожалуйста.</b>"	+
	"<br/><br/>Помните: электронный адрес может содержать латинские буквы и символы точка, @, тире, подчеркивание. Другие символы недопустимы.<br/>"; // email_w1
  
  this.Errors["InvalidEMail"] = "введите действительный электронный адрес"; // email_f2
  this.Errors["InvalidEMailMessage"] = "<b>Вы указали несуществующий адрес электронной почты. Исправьте, пожалуйста.</b>" +
	"<br/><br/>Все адреса E-mail имеют следующий формат: xxxx@xxxx.xx<br/>"; // email_w2
  
  this.Errors["EMailExist"] = "такой E-mail уже использовался"; // email_f3
  this.Errors["EMailExistMessage"] = "<b>E-mail, введенный Вами, к сожалению, уже использовался для регистрации на нашем сайте. Попробуйте, пожалуйста, другой.</b>"
	+ "<br/><br/>Вы ввели E-mail, который в нашей системе уже кто-то использовал. Если это были Вы, и не можете вспомнить пароль к учетной записи, воспользуйтесь формой восстановления паролей.<br/>"; // email_w3
  
  if (this.TextBox != null) {
	this.TextBox.onkeyup = attachEventHandler(this, "onEdit");
	this.TextBox.onchange = attachEventHandler(this, "onChange");
  
	if (this.Form != null) {
		this.Form.onsubmit = attachEventHandler(this, "validate");
	}
  }
}

EMailValidator.prototype = {
	showHint: function() {
		if (this.StatusDisplay != null) {
			this.StatusDisplay.showHint(this.Errors["Hint"]);
		}
	},
	
	onChange: function(event, element) {
		var filter = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
		var value = trim(this.TextBox.value);
		
		if (value.length > 0) {
			if (!filter.test(value)) {
				if (this.StatusDisplay != null) {
					this.StatusDisplay.showError(this.Errors["InvalidEMail"]);
				}
				return false;
			}
			xajax_CheckEmail(value);
		}
		this.showHint();
		return true;
	},

	onEdit: function(event, element) {
		var value = trim(this.TextBox.value);

		if (value.length > 0) {
			if (isRussianString(value)) {
				if (this.StatusDisplay != null) {
					this.StatusDisplay.showError(this.Errors["InvalidChars"]);
				}
				return false;
			}
		}
		this.showHint();
		return true;
	},
	
	validate: function() {
		var filter = /\w+([-+.’]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/;
	
		var value = trim(this.TextBox.value);

		if (value.length == 0) {
			if (this.StatusDisplay != null) {
				this.StatusDisplay.showError(this.Errors["EmptyEMail"]);
			}
			DisplayErrorDialog(this.Errors["EmptyEMailMessage"], this.TextBox);
			return false;
		}
	
		if (isRussianString(this.TextBox.value)) {
			if (this.StatusDisplay != null) {
				this.StatusDisplay.showError(this.Errors["InvalidChars"]);
			}
			DisplayErrorDialog(this.Errors["InvalidCharsMessage"], this.TextBox);
			return false;
		}
		
		if (!filter.test(this.TextBox.value)) {
			if (this.StatusDisplay != null) {
				this.StatusDisplay.showError(this.Errors["InvalidEMail"]);
			}
			DisplayErrorDialog(this.Errors["InvalidEMailMessage"], this.TextBox);
			return false;
		}
		this.showHint();
		return true;
	}
}

CustomerNameValidator = function(id, statusDisplay) {
  this.TextBox = document.getElementById(id);
  this.StatusDisplay = statusDisplay;
  this.Errors = new Array();
  this.Errors["Hint"] = "";
  this.Errors["InvalidValue"] = "Введите имя на русском языке";	// f0
  this.Errors["EmptyNameMessage"] = "Вы забыли указать имя. Пожалуйста, заполните это поле.<br/>";	// w0
  this.Errors["InvalidCharsMessage"] = "<b>В поле «имя» вы ввели недопустимые символы. Исправьте, пожалуйста.</b><br/>" +
	"<br/>Помните: имя нужно вводить на русском языке. Цифры и небуквенные символы недопустимы.<br/>";	// w1
  
  this.Part = "firstname";
  this.Required = true;
  
  if (this.TextBox != null) {
	this.TextBox.onkeyup = attachEventHandler(this, "onEdit");
	this.TextBox.onchange = attachEventHandler(this, "onChange");
  }
}

CustomerNameValidator.prototype = {
	showHint: function() {
		if (this.StatusDisplay != null) {
			this.StatusDisplay.showHint(this.Errors["Hint"]);
		}
	},
	
	validate: function() {
		var value = trim(this.TextBox.value);
		if (this.Required && value.length == 0) {
			if (this.StatusDisplay != null) {
				this.StatusDisplay.showError(this.Errors["InvalidValue"]);
			}
			DisplayErrorDialog(this.Errors["EmptyNameMessage"], this.TextBox);
			return false;
		}
		
		if (!this.validateCharsPart(value)) {
			if (this.StatusDisplay != null) {
				this.StatusDisplay.showError(this.Errors["InvalidValue"]);
			}
			DisplayErrorDialog(this.Errors["InvalidCharsMessage"], this.TextBox);
			return false;
		}

		this.showHint();
		return true;
	},
	
	validateCharsPart: function(value) {
		if (this.Part == "firstname") {
			return IsValidFirstName(value);
		}
		else if (this.Part == "middlename") {
			return IsValidMiddleName(value);
		}
		else if (this.Part == "lastname") {
			return IsValidLastName(value);
		}
		return isRussianString(value);
	},
	
	onChange: function(event, element) {
		var value = trim(this.TextBox.value);
		
		if (value.length > 0) {
			if (!this.validateCharsPart(value)) {
				if (this.StatusDisplay != null) {
					this.StatusDisplay.showError(this.Errors["InvalidValue"]);
				}
				return false;
			}
		}

		this.showHint();
		return true;
	},
	
	onEdit: function(event, element) {
		var value = trim(this.TextBox.value);

		if (value.length > 0) {
			if (!this.validateCharsPart(value)) {
				if (this.StatusDisplay != null) {
					this.StatusDisplay.showError(this.Errors["InvalidValue"]);
				}
				return false;
			}
		}
		
		this.showHint();
		return true;
	}
}

CityNameValidator = function(id, statusDisplay) {
  this.TextBox = document.getElementById(id);
  this.StatusDisplay = statusDisplay;
  this.AfterChange = null;
  
  this.Errors = new Array();
  this.Errors["InvalidChars"] = "название населенного пункта должно быть на русском языке";
  this.Errors["Hint"] = "введите название населенного пункта";
  this.Errors["EmptyName"] = "введите название населенного пункта";
  
  if (this.TextBox != null) {
	this.TextBox.onkeyup = attachEventHandler(this, "onEdit");
	this.TextBox.onchange = attachEventHandler(this, "onChange");
  }
}

CityNameValidator.prototype = {
	validate: function() {
		var cityName = trim(this.TextBox.value);
		if (cityName.length == 0) {
			if (this.StatusDisplay != null) {
				this.StatusDisplay.showError(this.Errors["EmptyName"]);
			}
			DisplayErrorDialog(this.Errors["EmptyName"], this.TextBox);
			return false;
		}
		if (!IsValidCityName(cityName)) {
			if (this.StatusDisplay != null) {
				this.StatusDisplay.showError(this.Errors["InvalidChars"]);
			}
			DisplayErrorDialog(this.Errors["InvalidChars"], this.TextBox);
			return false;
		}
		
		if (this.StatusDisplay != null) {
			this.StatusDisplay.showHint(this.Errors["Hint"]);
		}
		return true;
	},
	
	onChange: function(event, element) {
		var cityName = trim(this.TextBox.value);
		
		if (cityName.length == 0) {
			if (this.StatusDisplay != null) {
				this.StatusDisplay.showError(this.Errors["EmptyName"]);
			}
			return false;
		}
		if (!IsValidCityName(cityName)) {
			if (this.StatusDisplay != null) {
				this.StatusDisplay.showError(this.Errors["InvalidChars"]);
			}
			return false;
		}
		
		if (this.StatusDisplay != null) {
			this.StatusDisplay.showHint(this.Errors["Hint"]);
		}
		if (this.AfterChange != null) {
			this.AfterChange(element);
		}
	},
	onEdit: function(event, element) {
		var cityName = trim(this.TextBox.value);
		
		if (cityName.length > 0) {
			if (!IsValidCityName(cityName)) {
				if (this.StatusDisplay != null) {

					this.StatusDisplay.showError(this.Errors["InvalidChars"]);
				}
				return false;
			}
		}
		
		if (this.StatusDisplay != null) {
			this.StatusDisplay.showHint(this.Errors["Hint"]);
		}
	}
}

PhoneNumberValidator = function(areaId, numberId, statusDisplay) {
  this.StatusDisplay = statusDisplay;
  
  this.AreaTextBox = document.getElementById(areaId);
  
  if (this.AreaTextBox != null) {
	this.AreaTextBox.onkeyup = attachEventHandler(this, "onEdit");
	this.AreaTextBox.onchange = attachEventHandler(this, "onChange");
  }

  this.NumberTextBox = document.getElementById(numberId);
  
  if (this.NumberTextBox != null) {
	this.NumberTextBox.onkeyup = attachEventHandler(this, "onEdit");
	this.NumberTextBox.onchange = attachEventHandler(this, "onChange");
  }
  
  this.Errors = new Array();
  this.Errors["Hint"] = "введите код и номер телефона (без восьмерки)";	// number_f0
  this.Errors["EmptyNumber"] = "введите код и номер телефона (без восьмерки)"; // number_f0
  this.Errors["EmptyNumberMessage"] = "Вы забыли ввести номер телефона. Пожалуйста, заполните это поле.<br/>"; //w0
  
  this.Errors["InvalidChars"] = "исправьте недопустимые символы"; // number_f1
  this.Errors["InvalidCharsMessage"] = "<b>В номере телефона присутствуют недопустимые символы. Исправьте, пожалуйста.</b>" +
	"<br/><br/>Помните, что телефонный номер может содержать цифры и символы: пробел, скобки, тире. Другие символы недопустимы.<br/>"; // number_w1
  
  this.Errors["InvalidLength"] = "введите действительный номер (10 цифр, без восьмерки)"; // number_f2
  this.Errors["InvalidLengthMessage"] = "<b>Вы указали несуществующий номер телефона. Исправьте, пожалуйста.</b>" +
	"<br/><br/>Напоминаем: вводить номер нужно без «восьмерки». У Вас в сумме должно получиться 10 цифр (российский стандарт телефонного номера).<br/>";
}

PhoneNumberValidator.prototype = {
	showHint: function() {
		if (this.StatusDisplay != null) {
			this.StatusDisplay.showHint(this.Errors["Hint"]);
		}
	},
	
	validate: function() {
		var area = trim(this.AreaTextBox.value);
		var number = trim(this.NumberTextBox.value);

		if (number.length == 0) {
			if (this.StatusDisplay != null) {
				this.StatusDisplay.showError(this.Errors["EmptyNumber"]);
			}
			DisplayErrorDialog(this.Errors["EmptyNumberMessage"], this.NumberTextBox);
			return false;
		}

		if (!IsPhoneString(number)) {
			if (this.StatusDisplay != null) {
				this.StatusDisplay.showError(this.Errors["InvalidChars"]);
			}
			DisplayErrorDialog(this.Errors["InvalidCharsMessage"], this.NumberTextBox);
			return false;
		}
		
		if (area.length == 0 && number.replace(/\(/gi, "").replace(/\)/gi, "").replace(/ /gi, "").replace(/-/gi, "").length != 10) {
			if (this.StatusDisplay != null) {
				this.StatusDisplay.showError(this.Errors["InvalidLength"]);
			}
			DisplayErrorDialog(this.Errors["InvalidLengthMessage"], this.NumberTextBox);
			return false;
		}
		
		if (!IsPhoneString(area)) {
			if (this.StatusDisplay != null) {
				this.StatusDisplay.showError(this.Errors["InvalidChars"]);
			}
			DisplayErrorDialog(this.Errors["InvalidCharsMessage"], this.AreaTextBox);
			return false;
		}
		
		var phone = (area + number).replace(/\(/gi, "").replace(/\)/gi, "").replace(/ /gi, "").replace(/-/gi, "");
		if (phone.length != 10) {
			if (this.StatusDisplay != null) {
				this.StatusDisplay.showError(this.Errors["InvalidLength"]);
			}
			DisplayErrorDialog(this.Errors["InvalidLengthMessage"], this.NumberTextBox);
			return false;
		}
		this.showHint();
		return true;
	},
	
	onChange: function(event, element) {
		var area = trim(this.AreaTextBox.value);
		var number = trim(this.NumberTextBox.value);
		
		if (number.length == 0) {
			if (this.StatusDisplay != null) {
				this.StatusDisplay.showError(this.Errors["EmptyNumber"]);
			}
			return false;
		}
		
		if (!IsPhoneString(number)) {
			if (this.StatusDisplay != null) {
				this.StatusDisplay.showError(this.Errors["InvalidChars"]);
			}
			return false;
		}
		
		var phone = (area + number).replace(/\(/gi, "").replace(/\)/gi, "").replace(/ /gi, "").replace(/-/gi, "");
		if (phone.length != 10) {
			if (this.StatusDisplay != null) {
				this.StatusDisplay.showError(this.Errors["InvalidLength"]);
			}
			return false;
		}
		this.showHint();
		return true;
	},
	onEdit: function(event, element) {
		var area = trim(this.AreaTextBox.value);
		var number = trim(this.NumberTextBox.value);
		
		if (area.length > 0 && !IsPhoneString(area) || number.length > 0 && !IsPhoneString(number)) {
			if (this.StatusDisplay != null) {
				this.StatusDisplay.showError(this.Errors["InvalidChars"]);
			}
			return false;
		}
		this.showHint();
		return true;
	}
}

PasswordValidator = function(passwordId, repeatId, passwordStatusDisplay, repeatStatusDisplay) {
  this.PasswordStatusDisplay = passwordStatusDisplay;
  this.RepeatStatusDisplay = repeatStatusDisplay;
  
  this.PasswordTextBox = document.getElementById(passwordId);
  
  if (this.PasswordTextBox != null) {
	this.PasswordTextBox.onkeyup = attachEventHandler(this, "onPasswordEdit");
	this.PasswordTextBox.onchange = attachEventHandler(this, "onPasswordChange");
  }

  this.RepeatTextBox = document.getElementById(repeatId);
  
  if (this.RepeatTextBox != null) {
	this.RepeatTextBox.onkeyup = attachEventHandler(this, "onRepeatEdit");
	this.RepeatTextBox.onchange = attachEventHandler(this, "onRepeatChange");
  }
  
  this.Errors = new Array();
  this.Errors["PasswordHint"] = "только a-z, A-Z, 0-9 и знаки препинания, минимум — " + MinPasswordLength.toString() + " символов";	// password_h
  this.Errors["EmptyPassword"] = "введите пароль"; // password_f0
  this.Errors["EmptyPasswordMessage"] = "Вы забыли ввести пароль. Пожалуйста, заполните это поле.<br/>"; // password_w0
  
  this.Errors["InvalidLength"] = "минимально допустимая длина — " + MinPasswordLength.toString() + " символов"; // password_f1
  this.Errors["InvalidLengthMessage"] = "<b>Вы ввели слишком короткий пароль. Исправьте, пожалуйста.</b>" +
	"<br/><br/>Помните: минимально допустимая длина пароля — " + MinPasswordLength.toString() + " символов"; // password_w1
  
  this.Errors["InvalidChars"] = "допустимы только латинские буквы, цифры и знаки препинания";	// password_f2
  this.Errors["InvalidCharsMessage"] = "<b>В поле пароля вы ввели недопустимые символы. Исправьте, пожалуйста.</b>" +
	"<br/><br/>Помните: пароль может состоять только из латинских букв, цифр и знаков препинания. Другие символы недопустимы.<br/>";	// password_w2
  
  this.Errors["RepeatHint"] = "";
  this.Errors["RepeatMatch"] = "пароль повторен верно"; // repeatpassword_h
  
  this.Errors["EmptyRepeat"] = "введите пароль повторно"; // repeatpassword_f0
  this.Errors["EmptyRepeatMessage"] = "Вы не заполнили поле «Повторите пароль». Заполните, пожалуйста.<br/>"; // repeatpassword_w0
  
  this.Errors["RepeatMismatch"] = "пароль повторен неверно"; //repeatpassword_f1
  this.Errors["RepeatMismatchMessage"] = "<b>Введенные пароли не совпадают. Попробуйте, пожалуйста, еще раз.</b>"; //repeatpassword_w1
}

PasswordValidator.prototype = {
	showPasswordHint: function() {
		if (this.PasswordStatusDisplay != null) {
			this.PasswordStatusDisplay.showHint(this.Errors["PasswordHint"]);
		}
	},
	showRepeatHint: function() {
		if (this.RepeatStatusDisplay != null) {
			this.RepeatStatusDisplay.showHint(this.Errors["RepeatHint"]);
		}
	},
	
	validate: function() {
		var password = trim(this.PasswordTextBox.value);
		var repeat = trim(this.RepeatTextBox.value);

		if (password.length == 0) {
			if (this.PasswordStatusDisplay != null) {
				this.PasswordStatusDisplay.showError(this.Errors["EmptyPassword"]);
			}
			DisplayErrorDialog(this.Errors["EmptyPasswordMessage"], this.PasswordTextBox);
			return false;
		}

		if (password.length < MinPasswordLength) {
			if (this.PasswordStatusDisplay != null) {
				this.PasswordStatusDisplay.showError(this.Errors["InvalidLength"]);
			}
			DisplayErrorDialog(this.Errors["InvalidLengthMessage"], this.PasswordTextBox);
			return false;
		}
		
		if (!isGoodPassword(password)) {
			if (this.PasswordStatusDisplay != null) {
				this.PasswordStatusDisplay.showError(this.Errors["InvalidChars"]);
			}
			DisplayErrorDialog(this.Errors["InvalidCharsMessage"], this.PasswordTextBox);
			return false;
		}
		this.showPasswordHint();
		
		if (repeat.length == 0) {
			if (this.RepeatStatusDisplay != null) {
				this.RepeatStatusDisplay.showError(this.Errors["EmptyRepeat"]);
			}
			DisplayErrorDialog(this.Errors["EmptyRepeatMessage"], this.RepeatTextBox);
			return false;
		}
		
		if (password != repeat) {
			if (this.RepeatStatusDisplay != null) {
				this.RepeatStatusDisplay.showError(this.Errors["RepeatMismatch"]);
			}
			DisplayErrorDialog(this.Errors["RepeatMismatchMessage"], this.RepeatTextBox);
			return false;
		}
		this.showRepeatHint();
		
		return true;
	},
	
	onPasswordChange: function(event, element) {
		var password = trim(this.PasswordTextBox.value);
		var repeat = trim(this.RepeatTextBox.value);

		if (password.length > 0) {
			if (password.length < MinPasswordLength) {
				if (this.PasswordStatusDisplay != null) {
					this.PasswordStatusDisplay.showError(this.Errors["InvalidLength"]);
				}
				return false;
			}
			
			if (!isGoodPassword(password)) {
				if (this.PasswordStatusDisplay != null) {
					this.PasswordStatusDisplay.showError(this.Errors["InvalidChars"]);
				}
				return false;
			}
			this.showPasswordHint();
			
			if (repeat.length > 0 && password != repeat) {
				if (this.RepeatStatusDisplay != null) {
					this.RepeatStatusDisplay.showError(this.Errors["RepeatMismatch"]);
				}
				return false;
			}
		}
		this.showPasswordHint();
		this.showRepeatHint();
		
		return true;
	},
	onPasswordEdit: function(event, element) {
		var password = trim(this.PasswordTextBox.value);
		var repeat = trim(this.RepeatTextBox.value);
		
		if (password.length > 0 && !isGoodPassword(password)) {
			if (this.PasswordStatusDisplay != null) {
				this.PasswordStatusDisplay.showError(this.Errors["InvalidChars"]);
			}
			return false;
		}
		this.showPasswordHint();
		
		if (repeat.length > 0 && password != repeat) {
			if (this.RepeatStatusDisplay != null) {
				this.RepeatStatusDisplay.showError(this.Errors["RepeatMismatch"]);
			}
			return false;
		}
		this.showRepeatHint();
		
		return true;
	},
	onRepeatChange: function(event, element) {
		var password = trim(this.PasswordTextBox.value);
		var repeat = trim(this.RepeatTextBox.value);
		
		if (repeat.length >= password.length) {
			if (repeat != password) {
				if (this.RepeatStatusDisplay != null) {
					this.RepeatStatusDisplay.showError(this.Errors["RepeatMismatch"]);
				}
				return false;
			}
			else {
				if (this.RepeatStatusDisplay != null) {
					this.RepeatStatusDisplay.showHint(this.Errors["RepeatMatch"]);
				}
				return true;
			}
		}
		this.showRepeatHint();
		return true;
	},
	onRepeatEdit: function(event, element) {
		var password = trim(this.PasswordTextBox.value);
		var repeat = trim(this.RepeatTextBox.value);
		
		if (repeat.length >= password.length) {
			if (repeat != password) {
				if (this.RepeatStatusDisplay != null) {
					this.RepeatStatusDisplay.showError(this.Errors["RepeatMismatch"]);
				}
				return false;
			}
			else {
				if (this.RepeatStatusDisplay != null) {
					this.RepeatStatusDisplay.showHint(this.Errors["RepeatMatch"]);
				}
				return true;
			}
		}
		this.showRepeatHint();
		return true;
	}
}

FormValidator = function(id, formValidator) {
	this.Form = document.getElementById(id);
	this.Validators = new Array();
	
	this.FormValidator = null;
	if (typeof(formValidator) == "function") {
		this.FormValidator = formValidator;
	}
	
	if (this.Form != null) {
		this.Form.onsubmit = attachEventHandler(this, "onValidate");
	}
}

FormValidator.prototype = {
	addValidator: function(validator) {
		this.Validators[this.Validators.length] = validator;
	},

	validate: function() {
		for (var i=0; i < this.Validators.length; i++) {
			var v = this.Validators[i];
			if (!v.validate()) {
				return false;
			}
		}
		return true;
	},
	
	onValidate: function(event, element) {
		if (!this.validate()) {
			return false;
		}
		if (this.FormValidator != null) {
			if (!this.FormValidator()) {
				return false;
			}
		}
		return true;
	}
}

ImageLoader = function(element, src, isBackground) {
	this.Element = element;
	this.IsBackground = isBackground;
	this.SaveBackgroundPosition = element.style.backgroundPosition;
	this.Element.style.backgroundPosition = "center center";
	this.displayImage("/images/design/indicator.gif", false);
	
	this.Image = new Image();
	this.Image.onload = attachEventHandler(this, "onLoad");
	this.Image.src = src;
}

ImageLoader.prototype = {
	onLoad: function(event, element) {
		this.displayImage(this.Image.src, true);
	},
	
	displayImage: function(src, restore) {
		if (this.IsBackground) {
			if (restore) {
				this.Element.style.backgroundPosition = this.SaveBackgroundPosition;
			}
			this.Element.style.backgroundImage = "url('" + src + "')";
		}
		else {
			this.Element.src = src;
		}
	}
}

