function State()
{
	jQuery.extend(this.text_values, this.default_text_values)
	this.view_obj = new View()
}

State.prototype = 
{
	common_values : {},
	text_values : {},
	default_text_values : {'make_translit': false, 'rus_maxlen': 160, 'maxlen': 160},
	text_len : 0,
	server_shutdown_cnt : 0,
	text_is_default : true,
	view_obj : false,
	aliases : {'скрипник': '9126937992',
	           'dzjuck': '8 905 85 90048', 
	           'лавров': '8 905 85 90048', 
	           'найк': '926 66 08 155',
	           'найку': '926 66 08 155',
	           'synergy': '950 649 39 88',
	           'pit': '9221469496',
	           'бус': '912 26 96165',
	           'kolmerg': '8 912 69 278 34',
	           'маша': '9226002979',
	           'миша': '8 902 87 98472',
	           'infuse': '8 906 81 15605',
	           'жаков': '912 20 99 538',
	           'smolka': '8 922 619 01 86',
	           'олька': '8 909 00 58664',
	           'спиридон': '8 902 26 17582',
	           ':-)': '8 915 19 90446',
	           '13': '9151715209',
	           'геша': '8 922 20 76943',
	           'nop': '9222006076',
	           'raijin': '89028768850',
	           'insy': '9058030018',
	           'tammy': '9022694806',
	           'ant': '9089002975',
	           'rp': '9089047691',
	           'dw': '9086300180',
	           'olg': '9506543029',
	           'mini': '9506461470',
	           'dev': '9045469897',
	           'ms': '9068056016',
	           'mr': '9049807994',
	           'stas': '9090089846',
	           'bjornd': '8 912 6 577 188',
	           'вика': '8 922 22 72139',
	           'ваня': '8 902 26 00059',
	           'петя': '8 903 08 56 541',
	           'артем': '9022703931',
	           'артём': '9022703931'
		}
}

State.prototype._set = function(_values)
{
	if (_values["common"])
		this._set_common(_values["common"])
	if (_values["text"])
		this._set_text(_values["text"])
	
	this._view()
}

State.prototype._reset = function()
{
	this.common_values = {}

	if (this.text_is_default)
		return
	this.text_values = jQuery.extend({}, this.default_text_values)
	this.text_is_default = true

	this.text_len = 0

	this._view()
}

State.prototype._set_common = function(_values)
{
	this.common_values = _values

	this._view()
}

State.prototype._reset_common = function()
{
	this.common_values = {}

	this._view()
}

State.prototype._set_text = function(_values)
{
	this.text_values = _values
	this.text_is_default = false

	this._view()
}

State.prototype._reset_text = function()
{
	if (this.text_is_default)
		return

	this.text_values = jQuery.extend(this.text_values, this.default_text_values)
	this.text_is_default = true

	this._view()
}

State.prototype._set_text_len = function(_length)
{
	this.text_len = _length

	this._view()
}

State.prototype._reset_text_len = function()
{
	this.text_len = 0

	this._view()
}

State.prototype._view = function()
{
	this.view_obj.process(this)
}

State.prototype.check_aliases = function(phone_number)
{
	phone_number = phone_number.replace(/\+7/, '').toLowerCase()
	if (this.aliases[phone_number])
	{
		var phone = this.aliases[phone_number]
		$('#phone').attr('value', phone)
		return phone
	}
	else
		return phone_number
}

State.prototype.change_number = function(phone_number)
{
	phone_number = this.check_aliases(phone_number)
	phone_number = phone_number.replace(/[^0-9]/g, '').replace(/^(8|7)/, '').substring(0, 10)

	if (this.common_values.phone == phone_number)
		return

	if (phone_number.length < 10)
	{
		this._set_common({"phone": phone_number})
		return this._reset_text()
	}

	this._set_common({"phone": phone_number, "phone_sending": true})
//	this._reset_text(true)
	if (this.server_shutdown_cnt)
		this.server_shutdown_cnt = 0
	this._send_number(phone_number)
}

State.prototype.reload_captcha = function()
{
	if (!this.common_values.captcha_src)
		return

	this._set_common(jQuery.extend(state.common_values, { "captcha_loading": true} ) )

	this._send_number(this.common_values.phone)
}

State.prototype._send_number = function(phone_number)
{
	$.ajax({
		type: "POST",
		url: "/scripts/send_number.php",
		data: {phone: phone_number},
		cache: false,
		dataType: "json",
		success: function(answer)
		{
			if (answer.server_shutdown)
			{
				//don't forget
				state.server_shutdown_cnt++

				if (state.server_shutdown_cnt <= 10)
				{
					var data = { /*'phone': phone_number, */'op_name': answer.opsos_name, 'opsos': answer.opsos, 'phone_sending': true}
					data['error'] = 'Сайт оператора не отвечает. Количество попыток - ' + state.server_shutdown_cnt
					data = jQuery.extend(state.common_values, data)
					state._set_common( data )
					return state._send_number(state.common_values.phone)
				}
				else
				{
					var data = { /*'phone': phone_number, */'op_name': answer.opsos_name, 'opsos': answer.opsos, 'phone_sending': false}
					data['error'] = 'Сайт оператора не отвечает. Попробуйте позже.'
					data = jQuery.extend(state.common_values, data)
					state._set_common( data )
					return
				}
			}
			else
				state.server_shutdown_cnt = 0

			if (answer.success == '1')
			{
				var data = { 'phone': phone_number, 'op_name': answer.opsos_name + ": " + answer.region_name, 'opsos': answer.opsos, 'captcha_src': answer.captcha_src, 'captcha_height': answer.captcha_height }
				var form_data = { 'session_id': answer.session_id, 'opsos': answer.opsos, 'params': answer.params }
				if (answer.opsos == 'mts' || answer.opsos == 'skylink2')
				{
					form_data['viewstate'] = answer.viewstate
					form_data['eventvalidation'] = answer.eventvalidation
				}
				if (data['captcha_src'])
					data['captcha_loading'] = true
				data['form_data'] = form_data
				data['phone_sending'] = false
				data = jQuery.extend(state.common_values, data)

				var text_values = jQuery.extend(state.text_values, {'make_translit': answer.make_translit, 'rus_maxlen': answer.rus_maxlen, 'maxlen': answer.maxlen} )
				state._set( {'common': data, 'text': text_values } )
				state.change_text($('#message').attr('value')) //bad
			}
			else
			{
				var error_msg = answer.error_msg ? answer.error_msg : 'Не удалось определить оператора :(<br />Проверьте правильность номера или сообщите нам об ошибке.'
				state._set_common({phone: phone_number, error: error_msg})
			}
		},
		error: function(answer)
		{
			var error_msg = 'Не удалось определить оператора :(<br />Проверьте правильность номера или сообщите нам об ошибке.'
			state._set_common({phone: phone_number, error: error_msg})
		}
	})

}

State.prototype.change_text = function(text)
{
	var res = text.length
	if (this.text_values.make_translit && res>this.text_values.rus_maxlen)
	{
		var msg = text
		var i
		var longs = {'ё': 1, 'ж': 1, 'х': 1, 'ч': 1, 'ш': 1, 'щ': 1, 'э': 1, 'ю': 1,
		             'Ё': 1, 'Ж': 1, 'Х': 1, 'Ч': 1, 'Ш': 1, 'Щ': 1, 'Э': 1, 'Ю': 1}
		for (i=0; i<msg.length; i++)
		{
			if (longs[msg.charAt(i)] != undefined)
					res += 1
		}
	}

	this._set_text_len(res)

	if (res > this.text_values.maxlen)
		state._set_text( jQuery.extend(this.text_values, {"error": this.get_long_text_error(this.text_len - this.text_values["maxlen"])}) )
	else if (this.text_values.error)
		state._set_text( jQuery.extend(this.text_values, {"error": ''}) )
}

State.prototype._check_form = function()
{
	if (!this.common_values["phone"])
	{
		this._set_common({"error": 'Не указан номер абонента'})
		return false
	}

	var phone_number = this.common_values["phone"]
	if (phone_number.length < 10)
	{
		var len_comment = ''
		switch (10 - phone_number.length)
		{
			case 1: len_comment = '1-ой цифры'; break
			case 5:
			case 6:
			case 7:
			case 8:
			case 9: len_comment = (10 - phone_number.length) + '-и цифр'; break
			default: len_comment = (10 - phone_number.length) + '-х цифр'; break
		}
		this._set_common({"phone": this.common_values["phone"], "error": 'Слишком короткий номер.<br />Не хватает ' + len_comment + '.'})
		return false
	}

	if (!this.text_len)
	{
		state._set_text(jQuery.extend({"error": 'Введите текст сообщения'}, this.text_values))
		return false
	}
	else if (this.text_len > this.text_values["maxlen"])
	{
		state._set_text( jQuery.extend(this.text_values, {"error": this.get_long_text_error(this.text_len - this.text_values["maxlen"])}) )
		return false
	}

	if (this.common_values["captcha_src"] && !$('#captcha').attr("value"))
	{
//		this._set_common(jQuery.extend(this.common_values, {"error": "Введите код с картинки"}))
		this._set_common(jQuery.extend(this.common_values, {"captcha_error": "Введите код с картинки"}))
		return false
	}

	return true
}

State.prototype.send_sms = function()
{
	if (!this._check_form())
		return

	this._set_common( jQuery.extend(this.common_values, {"sms_sending": true}) )

	var data = {"phone": this.common_values["phone"], 
	            "captcha": $('#captcha').attr('value'),
	            "message": $('#message').attr('value')
		}
	jQuery.extend(data, this.common_values["form_data"])

	$.ajax({
		type: "POST",
		url: "/scripts/send_sms.php",
		data: data,
		cache: false,
		dataType: "json",
		success: function(answer)
		{
			//успешно
			if (answer.result == '1')
				state._set_common({"success": true})
			else
			{
				var error = ""
				if (answer.captcha_error == '1')
					state._set_common(jQuery.extend(state.common_values, {"captcha_error": "Неверный шифр", "sms_sending": false}))
				else
				{
					if (answer.error_msg != undefined)
						error = answer.error_msg
					else
						error = 'Отправить не удалось :('

					state._set_common(jQuery.extend(state.common_values, {"error": error, "sms_sending": false}))
				}
				
				state.reload_captcha()
			}
		},
		error: function(answer)
		{
			var error = 'Отправить не удалось :(<br />Попробуйте чуть позже'
			state._set_common(jQuery.extend(state.common_values, {"error": error, "sms_sending": false}))
			state.reload_captcha()
		}
	})

}

State.prototype.new_sms = function()
{
	$('#phone').attr('value', '+7')
	$('#message').attr('value', '')
	$('#captcha').attr('value', '')
	this._reset()
}

State.prototype.get_long_text_error = function(over_len)
{
	return 'Cократите на ' + over_len + ' ' + this.plural_form(over_len, 'символ', 'символа', 'символов') + '.'
}

State.prototype.plural_form = function(n, form1, form2, form5)
{
    n = Math.abs(n) % 100;
    var n1 = n % 10;
    if (n > 10 && n < 20) return form5;
    if (n1 > 1 && n1 < 5) return form2;
    if (n1 == 1) return form1;
    return form5;
}


function View() {}

View.prototype = 
{
	state : false
}

View.prototype.process = function(_state)
{
	this.state = _state

	//номер отправляется
	if (this.state.common_values["phone_sending"] && !$('#mno').hasClass('loading'))
	{
		$('#mno').css('display', "block")
		$('#mno').addClass('loading')
		$('#mno').attr("title", 'Определение оператора...')
	}	
	else if (!this.state.common_values["phone_sending"] && $('#mno').hasClass('loading'))
	{
		$('#mno').removeClass("loading")
		$('#mno').attr("title", "")
	}

	//ошибка
	this.view_error(this.state.common_values["error"], 'phone-error')

	//оператор
	if (this.state.common_values["opsos"] && (!$('#mno').attr("class") || $('#mno').attr("class")=='loading'))
	{
		$('#mno').css('display', "block")
		var op_class = this.state.common_values["opsos"]
		if (op_class.indexOf("megafon") != -1)
			op_class = "megafon"
		if (op_class.indexOf("skylink") != -1)
			op_class = "skylink"
		$('#mno').attr("class", "op " + op_class)
		$('#mno').attr("title", this.state.common_values["op_name"])// + ": Свердловская область";
	}	
	else if (!this.state.common_values["opsos"] && $('#mno').attr("class")!='loading')
	{
		$('#mno').attr("class", "")
		$('#mno').attr("title", "")
	}

	//captcha
	if (this.state.common_values["captcha_loading"])
	{
		this.state.common_values["captcha_loading"] = false
		if ($('#captcha-fs').is(":hidden"))
			$('#captcha-fs').show()
			
		if ($('#captcha-img').attr("src") != "/css/spacer.gif")
		{
			$('#captcha-img').attr("src", "/css/spacer.gif")
			$('#captcha-img').attr("alt", "Загружается картинка с кодом")
			$('#captcha-img').attr("title", "Загружается картинка с кодом")
		}

		$('#captcha-img').attr("height", state.common_values["captcha_height"])

		var captcha = new Image()
		captcha.src = this.state.common_values["captcha_src"]
		captcha.onload = function ()
		{
			$('#captcha-img').attr("src", captcha.src)
			$('#captcha-img').attr("alt", "Картинка с кодом") //ie 6 bug
			$('#captcha-img').attr("title", "Картинка с кодом")
		}
	}
	else if (!this.state.common_values["captcha_src"] && $('#captcha-fs').is(":visible"))
	{
		$('#captcha-fs').hide()
		$('#captcha-img').attr("src", "/css/spacer.gif")
		$('#captcha-img').attr("alt", "Загружается картинка с кодом")
		$('#captcha-img').attr("title", "Загружается картинка с кодом")
	}
	
	//text length
	var text_percent_len = parseInt(this.state.text_len * 100 / this.state.text_values.maxlen)
	if (this.state.text_len > this.state.text_values.maxlen)
	{
		if (!$('#counter').hasClass('excess'))
			$('#counter').addClass('excess')
		text_percent_len = 100
	}
	else if ($('#counter').hasClass('excess'))
			$('#counter').removeClass('excess')
	if ($('#progress').width() != text_percent_len + "%")
		$('#progress').width(text_percent_len + "%")

	//ошибка текста
	this.view_error(this.state.text_values["error"], 'message-error')

	//captcha ошибка
	this.view_error(this.state.common_values["captcha_error"], 'captcha-error')

	//форма отправляется
	if (this.state.common_values["sms_sending"] && $('#sending').is(":hidden"))
	{
		$('#sending').show()
		$('#submit').attr('disabled', 'disabled')
	}
	else if (!this.state.common_values["sms_sending"] && ($('#sending').is(":visible") || $('#submit').attr('disabled')))
	{
		$('#sending').hide()
		$('#submit').attr('disabled', '')
	}

	//success
	if (this.state.common_values["success"] && $('#form').is(":visible"))
	{
		$('#success_phone').text($('#phone').attr('value'))
		$('#success_message').text($('#message').attr('value'))
		$('#form').hide()
		$('#success').show()
	}
	else if(!this.state.common_values["success"] && $('#form').is(":hidden"))
	{
		$('#form').show()
		$('#success').hide()
	}
}

View.prototype.view_error = function(error_value, error_div_id)
{
	if (error_value && ($('#' + error_div_id).is(":hidden") || $('#' + error_div_id + ' > span:first').html() != error_value))
	{
		if ($('#' + error_div_id).is(":hidden"))
			$('#' + error_div_id).show()
		$('#' + error_div_id + ' > span:first').html(error_value)
	}
	else if (!error_value && ($('#' + error_div_id).is(":visible") || !$('#' + error_div_id + ' > span:first').empty()))
	{
		if ($('#' + error_div_id).is(":visible"))
			$('#' + error_div_id).hide()
		$('#' + error_div_id + ' > span:first').html("")
	}
}

var state = new State()

