/**
 * @author danyastuff
 */

function ExperienceChange(e) 
{
	var ins = e.data.parent.sets.inside,
		out = e.data.parent.sets.outside.find('.result'),
		notice = e.data.parent.sets.body.find('#notice');
		
	out.fss  = e.data.parent.sets.outside.find('.result-fss');
	out.days = e.data.parent.sets.outside.find('.result-days');
	
	var t, _t, d, m, y, tInd, valid = false;
	var expTime = 0, diff = -1;
	var LIs = ins.find('LI');
	notice.text('');
	
	if (e.target) { 
		updateDateForm(e);
		var t = $(e.target.parentNode.parentNode);
		t.assignDates();
		valid = t.from.d.isNum(1,2) && t.from.y.isNum(4) && t.to.d.isNum(1,2) && t.to.y.isNum(4);
		if (valid) { // check from < to
			if (t.data('diff') < MS_IN_DAY) {
				notice.text('Интервал задается как «дата начала — дата конца», а не наоборот.');
				t.addClass('wrong');
				valid = false;
			}	
		}//if valid
	} else {
		valid = true;
	}
	if (valid)
		LIs.each(function () {
			t = $(this);
			tInd = LIs.index(t);
			t.removeClass('wrong');
		// check cross intervals
			LIs.each(function () {
				_t = $(this) ;
				if ( !_t.hasClass('wrong') );
					if (LIs.index(_t) != tInd) {
						var _tDF = _t.data('from'), _tDT = _t.data('to'),
							 tDF =  t.data('from'),  tDT =  t.data('to');
						if ( (_tDF <= tDT && _tDT >= tDF) || (tDF <= _tDT && tDT >= _tDF) ) {
							notice.text('Интервалы не должны пересекаться');
							t.addClass('wrong');
							valid = false;
						}
					}
			})//each
			if (valid) expTime += t.data('diff');
		})//each
	
	if (valid) 
	{
		var expDays = Math.round(expTime / MS_IN_DAY),
			years, months, days;
			
		//seniority by days
		out.days.text(expDays + ' ' + dCase(expDays));
		
		//seniority by y-m-d
		years = Math.floor(expDays / 360);
		expDays %= 360;
		months = Math.floor(expDays / 30);
		expDays %= 30;
		days = expDays;
		
		out.text(
			getTimeSign(years,months,days)
		)
		
		//seniority by FSS
		var buf = [];
		LIs.each(function () 
		{
			var t = $(this),
				years = t.data('dateTo').getFullYear() - t.data('dateFrom').getFullYear();
			var	days  = years != 0
					? t.data('dateTo').daysExpired() + t.data('dateFrom').daysLeft()
					: t.data('dateTo').daysExpired() - t.data('dateFrom').daysExpired();
			if (years > 0) { //calendar length
				if (t.data('dateFrom').daysExpired() > 1) { // year already started
					years--;
					days--;
				} else 
					days -= t.data('dateFrom').daysLeft();
			}
			
			var months = Math.floor(days / 30);
			days %= 30;
			buf.push({y: years, m: months, d: days});
		})
		
		var i = 0;
		years = 0, months = 0, days = 0;
		for (i in buf) {
			years  += buf[i].y;
			months += buf[i].m;
			days   += buf[i].d;
		}
		months += Math.floor(days / 30);
		days %= 30;
		years += Math.floor(months / 12);
		months %= 12;
		
		out.fss.text(
			getTimeSign(years,months,days)
		)
	}
	
	function getTimeSign(years,months,days) {
		var resTime = '';
		if (years) 	resTime += years + yCase(years);
		if (months) resTime += months + mCase(months);
		if (days) 	resTime += days + dCase(days);
		return resTime;
	}
	
	function yCase (v) { 
		return ' ' + defCase(v, ['год','года','лет']) + ' '; 
	}
	function mCase (v) { 
		return ' ' + defCase(v, ['месяц','месяца','месяцев']) + ' '; 
	}
	function dCase (v) { 
		return ' ' + defCase(v, ['день','дня','дней']) + ' '; 
	}
	function defCase (num, cases) {
		num %= 100;
		if ((11 <= num) && (num <= 19))
			return cases[2];
		num %= 10;
		if (num == 1)
			return cases[0];		
		if ((2 <= num) && (num <= 4))
			return cases[1];
		return cases[2];
	}
}

function ExperienceAdd (e) {
	var sets = e.data.parent.sets,
		li = sets.inside.find('LI:last'),
		preDate = li.prev().find('.from-date');
		
	var	df = li.find('.from-date'),
		dt = li.find('.to-date'),
		curY = preDate.find('.year').attr('value'),
		curM = preDate.find('.month').get(0).selectedIndex,
		curD = preDate.find('.date').attr('value');

	var d = new Date();
	d.setFullYear(curY);
	d.setMonth(curM);
	d.setDate(curD - 1);
	
	dt.find('.date').attr('value', d.getDate());
	dt.find('.month').get(0).selectedIndex = d.getMonth();
	dt.find('.year').attr('value', d.getFullYear());
	
	d.setDate(d.getDate() - 360);
	df.find('.date').attr('value', d.getDate());
	df.find('.month').get(0).selectedIndex = d.getMonth();
	df.find('.year').attr('value', d.getFullYear());
	
	li.assignDates();
}

function ExperienceCreate (e) {
	e.data.parent.sets.inside.find('LI').assignDates();
}

function updateDateForm (e) {
	var $parent = $(e.target.parentNode),
		date = $parent.find('.date'),
		month = $parent.find('.month').get(0),
		year = $parent.find('.year'),
		curD = new Date();
	curD.setDate(1);
	curD.setFullYear(year.attr('value'));
	curD.setMonth(month.selectedIndex);
	curD.setDate(date.attr('value'));
	
	date.attr('value', curD.getDate());
	month.selectedIndex = curD.getMonth();
	year.attr('value', curD.getFullYear());
}

$.fn.assignDates = function () {
	
	this.from = {
		d : this.find('.from-date .date'), 
		m : this.find('.from-date .month').get(0), 
		y : this.find('.from-date .year')
	}
	this.to = {
		d : this.find('.to-date .date'), 
		m : this.find('.to-date .month').get(0), 
		y : this.find('.to-date .year')
	}
	dateFrom = new Date(
		this.from.y.attr('value'),
		this.from.m.selectedIndex,
		this.from.d.attr('value')
	)
	dateTo = new Date(
		this.to.y.attr('value'),
		this.to.m.selectedIndex,
		this.to.d.attr('value')
	)
	this.data('dateFrom', dateFrom);
	this.data('dateTo', dateTo);
	this.data('from', dateFrom.getTime());
	this.data('to', dateTo.getTime());
	this.data('diff', dateTo.getTime() - dateFrom.getTime());
}

var MS_IN_DAY = 1000 * 60 * 60 * 24;

Date.prototype.daysExpired = function () {
	var d = new Date(this.getFullYear(),0,0);
	return Math.round(
		( this.getTime() - d.getTime() ) / MS_IN_DAY
	)
}
Date.prototype.daysLeft = function () {
	var d = new Date(this.getFullYear() + 1,0,1);
	return Math.round(
		( d.getTime() - this.getTime() ) / MS_IN_DAY
	)
}

$.fn.setValid = function (on) {
	if (on) {
		this.css('color', '');
	} else { 
		this.css('color', '#E00');
	}
}
$.fn.isNum = function (from, to) {
	if (!to) { to = from }
	var num = this.attr('value'),
		len = num.toString().length,
		valid = !( (/[^0-9]+/).test(num) || !num || (len < from || len > to) );
	this.setValid(valid);
	return valid
}