var Callback = {
	
	intervals: [10, 12, 14, 16, 18],

	week: [10, 19],
	holiday: [10, 18],
	
	serverTimeSource: '/php_lib/callback/time.php',
	requestSource: '/php_lib/callback/callback_handler.php',
		
	initialize: function() {

		jQuery.ajax({
			url: this.serverTimeSource,
			success: jQuery.proxy(function(time) {
				this.setTime(time);
			}, this)
		});

		this.Timezone.initialize();
		this.Backdrop.initialize();

		this.Tooltip.initialize();
		this.PlaseHolder.initialize();
		
		this.intervalsHook = $('#intervals');
		this.element = $('#callback');
		this.Backdrop.element.click(jQuery.proxy(this, 'close'));
		
		this.setTime(Math.floor(new Date().getTime()/1000));
		
		$('#comment').keydown(function(){
			var size = $(this).val().length;
			if ( size>499 ) {
			 $(this).val($(this).val().substr(0, size-1));
			 return(false);
			}
		});
		if (document.location.hash=='#opencallback')
		{
			Callback.open();
		}
	},

	Tooltip: {
	
		initialize: function() {
			if ( $('#tooltip') ) {
				this.elements = $('.tooltip');
				if ( this.elements.length ) {
					this.elements.hover(this.onMouseEnter, this.onMouseLeave);
				}
			}
		},

		onMouseEnter: function() {
			var pos = $(this).position(), offset = $(this).offset(), host = $('#tooltip'), title = $(this).attr('title');
	
			$(this).removeAttr('title');
			
			$('#tooltip').html(title).removeClass('hidden').css({
				left: offset.left + $(this).width(),
				top: offset.top  - $(host).height() - $(this).height()
			});
		},
		
		onMouseLeave: function() {
			$('#tooltip').addClass('hidden');
			$(this).attr('title', $('#tooltip').html());
		}

	
	},
	
	PlaseHolder: {
	
		initialize: function() {
		
			jQuery.each($('.with-placeholder'), jQuery.proxy(function(id, element){
				var title = $(element).attr('title');
				if ( title ) {
					// this.element = $(element);
					$(element).focus(this.onFocus).
						blur(this.onBlur);
					if ( !$(element).val() ) $(element).val(title);
				}
			}, this));
		},

		onFocus: function() {
			var title = $(this).attr('title'), value = $(this).val();
			if ( title == value ) $(this).val('');
		},
		
		onBlur: function() {
			var title = $(this).attr('title'), value = $(this).val();
			if ( !value ) $(this).val(title);
		}
	
	},	
	
	setTime: function(time) {
	  this.currentTime = new Date(time*1000);
	  var add = 4 - -1*this.currentTime.getTimezoneOffset()/60;
	  time = parseInt(time) + 60*60*add;
	  this.currentTime = new Date(time*1000);
	  this.Timezone.currentTime = this.currentTime;
	  this.Timezone.set(0);
	 },

	
	onChange: function() {
		$('#date').attr('checked', 'checked');
	},
	
	validate: function() {
		
		this.Validators.clearErrors();

		var phone =  $('#phone').val();
		phone = phone == $('#phone').attr('title') ? '' : phone;
		var subphone =  $('#sub-phone').val();
		var orderID =  $('#orderID').val();
		orderID = orderID == $('#orderID').attr('title') ? '' : orderID;
		var name =  $('#name').val();
		name = name == $('#name').attr('title') ? '' : name;
		var comment =  $('#comment').val();
		
		var msg, success = true;

		msg = this.Validators.isPhoneNumber(phone);
		if ( msg ) {
			$('#phone').addClass('field-with-error');
			$('#error-for-phone').html(msg).removeClass('hidden');
			success = false;
		} else $('#error-for-phone').addClass('hidden'); 

		msg = this.Validators.isNumber(orderID);
		if ( orderID && msg ) {
			$('#orderID').parent('.input-wrap').addClass('field-with-error');
			$('#error-for-orderID').html(msg).removeClass('hidden');
			success = false;
		} else $('#error-for-orderID').addClass('hidden'); 
		
		msg = this.Validators.isSubphoneNumber(subphone);
		if ( subphone && msg ) {
			$('#sub-phone').addClass('field-with-error');
			$('#error-for-subphone').html(msg).removeClass('hidden');
			success = false;
		} else $('#error-for-subphone').addClass('hidden'); 

		msg = this.Validators.isRequired(name);
		if ( msg ) {
			$('#name').parent('.input-wrap').addClass('field-with-error');
			$('#error-for-name').html(msg).removeClass('hidden');
			success = false;
		} else $('#error-for-name').addClass('hidden');
		
		return(success);
	},
	
	Validators: {
		
		clearErrors: function() {
			jQuery.each($('#callback-form .field-with-error'), function(id, element){
				$(element).removeClass('field-with-error');
			})
			jQuery.each($('#callback-form div.error'), function(id, element){
				$(element).text('');
			});
			
		},

		isPhoneNumber: function(value) {
			var r = new RegExp('^[0-9\u0028\u0029\u002B\\u002D\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029]{11,}$','g');
			return(r.test(value) ? false : 'Неверный формат телефонного номера. <nobr>Разрешено: 0-9, -, +, (, ),</nobr> пробел, минимум одиннадцать символов.');
		},
		
		isSubphoneNumber: function(value) {
                        var r = new RegExp('^[0-9]{3,5}$');
			return(r.test(value) ? false : 'Неверный формат добавочного номера. Разрешено: 0-9, от трех до пяти символов.');
		}, 
		
		isNumber: function(value) {
                        var r = new RegExp('^[0-9]*$');
			return(r.test(value) ? false : 'Неверный номер заказа.');
		},
		
		isRequired: function(value) {
			return('' != value ? false : 'Это поле обязательно к заполнению.');
		}
		
	},
	
	onSubmit: function() {
		if ( this.validate() ) {
			
			var data = {};
			
			var phone =  $('#phone').val();
			var subphone =  $('#sub-phone').val();
			var orderID =  $('#orderID').val();
			var name =  $('#name').val();
			var comment =  $('#comment').val();

			// Осноаные данные о пользователе
			if ( phone && phone != $('#phone').attr('title') ) data['phone'] = phone;
			if ( subphone ) data['subnumber'] = subphone;
			if ( orderID && orderID != $('#orderID').attr('title')  ) data['number'] = orderID;
			if ( name && name != $('#name').attr('title')  ) data['name'] = name;
			if ( comment ) data['comment'] = comment;
			
			// Данные о желаемом времени звонка
			if ( $('#now').attr('checked') ) {
				var when = Math.floor(this.currentTime.getTime()/1000)
				data['when'] = [when, when].join('-');
			}
			if ( $('#date').attr('checked') ) {
				var interval = $('#intervals').val().split('-');
				data['when'] = [Math.floor(interval[0]/1000), Math.floor(interval[1]/1000)].join('-');
			}

			data['zone'] = this.Timezone.getCurrentZone();
			data['nearestCity'] = this.Timezone.zones[this.Timezone.getCurrentZone()];
			
			jQuery.ajax({
				url: this.requestSource,
				type: 'post',
				data: data,
				dataType: 'json',
				success: function(data) {
					// if ( data.debug ) console.info(data.debug);
					// return(false);
					$('#callback').addClass('msg');
					var msg = data && 'OK' == data.status ? 'Спасибо.<br>Ожидайте звонка.' : 'Сервис временно недоступен.<br>Попробуйте воспользоваться им позже.';
					$('#callback div.message').html(msg);
				}
			});
		}
		this.toCenter();
		return(false);
	},
	
	toCenter: function() {
		var width = $(document).width(), 
			height = $(window).height(),
			cbWidth = this.element.width(),
			cbHeight = this.element.height();
			
		this.element.css({
			left: Math.ceil(width/2 - cbWidth/2),
			top: Math.ceil(height/2 - cbHeight/2)
		});
	},
	
	open: function() {
		this.Backdrop.show();
		this.element.removeClass('hidden')
		this.toCenter();
		$(window).resize(jQuery.proxy(this, 'toCenter'));
		this.fill();
		return(this);
	},
	
	close: function(save) {
		this.element.addClass('hidden');
		this.Backdrop.hide();
		this.Timezone.hide();
		this.Validators.clearErrors();
		$('#callback').removeClass('msg');
		jQuery.each($('#callback input[type=text]'), function(id, element){
			$(element).val('');
			if ( $(element).attr('title') ) $(element).val($(element).attr('title'));
		});
		
		$('#callback .comment').addClass('toggle');
		
		$(window).unbind('resize');
		return(this);
	},
	
	cloneDate: function(date) {
		return(new Date(date.getTime()));
	},

	getHours: function(date) {
		var hours = date.getHours().toString(); 
		return(2 == hours.length ? hours : '0'+hours);
	},

	getMinutes: function(date) {
		var minutes = date.getMinutes().toString(); 
		return(2 == minutes.length ? minutes : '0'+minutes);
	},

	
	isHolidays: function(date) {
		// Суббота или Воскресенье
		return(6 == date.getDay() || 0 == date.getDay());
	},

	isFri: function(date) {
		// Пятница
		return(5 == date.getDay());
	},

	isSun: function(date) {
		// Воскресенье
		return(0 == date.getDay());
	},
	
	getTimestampByHours: function(date, hours) {
		date = this.cloneDate(date);
		return(date.setHours(hours, 0));
	},
	
	disableNow: function() {
		// Disable «Сейчас»
		$('#now').attr('disabled', 'disabled').removeAttr('checked');
		$('#now-holder').css('opacity', 0.3);
		$('#date').attr('checked', 'checked');
	},
	
	fill: function() {
		this.intervalsHook.empty();
		
		var now = this.currentTime.getHours();

		// Сегодня
		if ( !this.isSun(this.currentTime) ) {
			var intervalEnd = this.isHolidays(this.currentTime) ? this.holiday[1] : this.week[1];
			if ( now + 2 <= intervalEnd ) this.intervalsHook.append($('<option />', {
				text: 'Сегодня',
				className: 'strong',
				value: this.currentTime.getTime()+'-'+this.getTimestampByHours(this.currentTime, intervalEnd)
			})); else this.disableNow();
		
			jQuery.each(this.intervals, jQuery.proxy(function(index, value){
				if ( value > now && value < intervalEnd ) {
					var begin = this.cloneDate(this.currentTime)
					begin.setHours(value, 0);							// Интервал в два часа
					var end = new Date(this.cloneDate(begin).getTime() + 3600000*2);
					if ( end.getHours() > intervalEnd ) end.setHours(intervalEnd);
					tzBegin = this.Timezone.getDateForTimezone(begin);
					tzEnd = this.Timezone.getDateForTimezone(end);
					this.intervalsHook.append($('<option />', {
						text: [this.getHours(tzBegin), ':00', '—', this.getHours(tzEnd), ':00'].join(''),
						value: [begin.getTime(), '-', end.getTime()].join('')
					}));
				}
			}, this));
		} else this.disableNow();
		
		// Завтра
		// Если суббота или Воскресенье => Понедельник
		if ( this.isHolidays(this.currentTime) ) {
			var tomorrowBegin = new Date(new Date(this.currentTime.getTime() + 60*60*24*1000*(this.isSun(this.currentTime) ? 1 : 2)).setHours(10, 0));
			var intervalEnd = this.isHolidays(tomorrowBegin) ? this.holiday[1] : this.week[1];
			var tomorrowEnd = new Date(this.cloneDate(tomorrowBegin).setHours(intervalEnd, 00));
			var text = 'Понедельник';
		} else {
			var tomorrowBegin = new Date(new Date(this.currentTime.getTime() + 60*60*24*1000).setHours(10, 0));
			var intervalEnd = this.isHolidays(tomorrowBegin) ? this.holiday[1] : this.week[1];
			var tomorrowEnd = new Date(this.cloneDate(tomorrowBegin).setHours(intervalEnd, 00));
			var text = 'Завтра';
		}

		this.intervalsHook.append($('<option />', {
			text: text,
			className: 'strong',
			value: [tomorrowBegin.getTime(), '-', tomorrowEnd.getTime()].join('')
		}));

		var intervalEnd = this.isHolidays(tomorrowBegin) ? this.holiday[1] : this.week[1];

		jQuery.each(this.intervals, jQuery.proxy(function(index, value){
			if ( value < intervalEnd) {
				var begin = this.cloneDate(tomorrowBegin)
				begin.setHours(value, 0);
				var end = new Date(this.cloneDate(begin).getTime() + 60*60*1000*2);
				tzBegin = this.Timezone.getDateForTimezone(begin);
				if ( end.getHours() > intervalEnd ) end.setHours(intervalEnd);
				tzEnd = this.Timezone.getDateForTimezone(end);
				this.intervalsHook.append($('<option />', {
					text: [this.getHours(tzBegin), ':00', '—', this.getHours(tzEnd), ':00'].join(''),
					value: [begin.getTime(), '-', end.getTime()].join('')
				}));
			}
		}, this));
		
		$($('option', this.intervalsHook).get(0)).attr('selected', 'selected');
	},
	
	Timezone: {
	
		zones: {
			'-1': 'Калининград',
			'0': 'Москва',
			'2': 'Екатеринбург',
			'3': 'Новосибирск',
			'4': 'Красноярск',
			'5': 'Иркутск',
			'6': 'Чита',
			'7': 'Владивосток',
			'8': 'Магадан'
		},
		
		zone: 0,
	
		initialize: function() {
			this.parent = Callback;
			
			this.element = $('#timezone ul');
			jQuery.each(this.zones, jQuery.proxy(function(id, value){
				this.element.append($('<li/>', {
					html: '<label onclick="Callback.Timezone.set('+id+')"><input type="radio" name="timezone" value="'+id+'"'+(this.getCurrentZone() == id ? ' checked="checked"' : '')+'> GMT+'+(3+parseInt(id))+', '+value+'</label>'
				}))
			}, this));

		},
		
		reposition: function() {
			var pos = $('#timezone-hook').offset();
			$('#timezone').css({
				left: pos.left,
				top: pos.top + $('#timezone-hook').height()
			})
		},
		
		toggle: function() {
			this.reposition();
			$('#timezone').toggleClass('hidden');
		},
		
		hide: function() {
			$('#timezone').addClass('hidden');
		},
		
		getDateForTimezone: function(date) {
			var newDate = new Date(date.getTime() + this.getCurrentZone() * 3600000);
			return(newDate);
		},
		
		set: function(timezone) {
			this.zone = timezone;
			var zoneTime = this.getDateForTimezone(this.currentTime, timezone);
			$('input[value = '+timezone+']', this.element).attr('checked', 'checked');
			$('#current-time').text(Callback.getHours(zoneTime)+':'+Callback.getMinutes(zoneTime)+' GMT+'+(3+parseInt(timezone)));
			$('#timezone-hook').text(this.zones[timezone]);
			this.hide();
			Callback.fill();
		},
		
		getCurrentZone: function() {
			return(this.zone);
		}
		
	},
	
	Backdrop: {
		
		options: {
			duration: 500,
			opacity: 0.7
		},
		
		initialize: function() {
			this.element = $('#backdrop');
			return(this);
		},
		
		show: function() {
			this.element.removeClass('hidden').fadeTo(0, this.options.opacity);
			return(this);
		},
		
		hide: function() {
			this.element.addClass('hidden');
			return(this);
		}
		
	}
	
	
}
 
jQuery(jQuery.proxy(Callback, 'initialize'));
