/*
 * @author Sergey Chikuyonok (gonarch@design.ru)
 * @copyright Art.Lebedev Studio (http://www.artlebedev.ru)
 */

/*
 * Простая проверялка формы. Смотрит, заполнены ли все required-поля в форме
 * и при необходимости проверяет правильность введенных данных
 * @param {Element, jQuery} form Форма, которую нужно проверять
 */
function FormChecker(form){
	/* Корневой элемент (форма) */
	this.root = $(form);

	/* Кнопка отправки данных */
	this.submit_btn = this.root.find('input:submit');

	/* Поля, которые должны быть заполненными */
	this.required_fields = this.root.find('.required');

	this.attachEvents();
	this.check();
};

FormChecker.prototype = {
	/*
	 * Вешает необходимые события на элементы формы
	 */
	attachEvents: function(){
		var me = this;

		var f = function(){
			return me.check();
		};

		this.root.submit(f);
		this.required_fields.blur(f).keyup(f).change(f);
	},

	/*
	 * Проверяет правильность заполения всей формы
	 * @return {Boolean}
	 */
	check: function(){
		var ok_fields = 0;
		var me = this;
		this.required_fields.each(function(){
			var obj = $(this), field = obj.find('input, select, textarea');

			var result = false;

			if(obj.is('.check_email')){
				result = me.checkEmail(field);
			}
			else if(obj.is('.check_date')){
				result = me.checkDate(field);
			}
			else{
				result = me.checkField(field);
			}

			ok_fields += Number(result);
		});

		var is_ok = (ok_fields == this.required_fields.length);
		this.submit_btn.attr('disabled', !is_ok);
		return is_ok;
	},

	/*
	 * Проверяет, заполнено ли поле
	 * @param {jQuery} field Поле, которое нужно проверить
	 * @return {Boolean}
	 */
	checkField: function(field){
		return Boolean($.trim(field.val()));
	},

	/*
	 * Проверяет, заполнено ли поле и имеет ли оно
	 * правильный формат электронной почты
	 * @param {jQuery} field Поле, которое нужно проверить
	 * @return {Boolean}
	 */
	checkEmail: function(field){
		var regexp = /^\s*[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\s*$/i;
		if(this.checkField(field)){
			var is_correct = regexp.test(field.val());
			return is_correct;
		}
		return false;
	},

	/*
	 * Проверяет, заполнено ли поле и имеет ли оно
	 * правильный формат даты
	 * @param {jQuery} field Поле, которое нужно проверить
	 * @return {Boolean}
	 */
	checkDate: function(field){
		var dtCh= ".";

		function isInteger(s){
			var i;
			for(i='0'; i<s.length; i++){   
				// Check that current character is number.
				var c = s.charAt(i);
				if(((c < "0") || (c > "9"))) return false;
			}
			// All characters are numbers.
			return true;
		}

		function stripCharsInBag(s, bag){
			var i;
			var returnString = "";
			// Search through string's characters one by one.
			// If character is not in bag, append to returnString.
			for(i='0'; i<s.length; i++){   
				var c = s.charAt(i);
				if(bag.indexOf(c) == -1) returnString += c;
			}
			return returnString;
		}

		function daysInFebruary (year){
			// February has 29 days in any year evenly divisible by four,
			// EXCEPT for centurial years which are not also divisible by 400.
			return (((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28 );
		}
		function DaysArray(n) {
			for(var i='1'; i<=n; i++){
				this[i] = 31;
				if(i==4 || i==6 || i==9 || i==11) {this[i] = 30}
				if(i==2) {this[i] = 29}
			} 
			return this;
		}

		function isDate(dtStr){
			var daysInMonth = DaysArray(12);
			var pos1 = dtStr.indexOf(dtCh);
			var pos2 = dtStr.indexOf(dtCh,pos1+1);
			var strDay = dtStr.substring(0,pos1);
			var strMonth = dtStr.substring(pos1+1,pos2);
			var strYear = dtStr.substring(pos2+1);
			strYr = strYear;

			if(strDay.charAt(0)=="0" && strDay.length>1) strDay = strDay.substring(1);
			if(strMonth.charAt(0)=="0" && strMonth.length>1) strMonth = strMonth.substring(1);

			for (var i='1'; i<=3; i++) {
				if(strYr.charAt(0)=="0" && strYr.length>1) strYr = strYr.substring(1);
			}

			month = parseInt(strMonth);
			day = parseInt(strDay);
			year = parseInt(strYr);

			if(pos1==-1 || pos2==-1) return false;
			if(strMonth.length<1 || month<1 || month>12) return false;
			if(strDay.length<1 || day<1 || day>31 || (month==2 && day>daysInFebruary(year)) || day > daysInMonth[month]) return false;
			if(strYear.length!='4' || year==0) return false;
			if(dtStr.indexOf(dtCh,pos2+1)!=-1 || isInteger(stripCharsInBag(dtStr, dtCh))==false) return false;

			return true;
		}

		if(!isDate(field.val()))
			return false;
		return true;
	}
};

$(function(){
	$('form').each(function(){
		new FormChecker(this);
	});
});
