var dontHideCal = false;


$(document).ready(function(){
	$('.calBtn').css('visibility','visible');
	$('.calBtn').click(function() {
			$('.calFrame').css({ left: $(this).position().left} );
		}
	);
	$(document).click (
		function(e) {
			if($(e.target).closest('.calWrapper').get(0) == null && e.target.className !== 'calBtn' && !dontHideCal)
				$('.calWrapper').hide();
			dontHideCal = false;
		}
	);

});

function cMassCalendar(name) {
	this.name = name;
	this.id = name;
	this.currentDate = new Date();
	this.minDate = new Date(1900, 0, 1);
	this.maxDate = new Date(2100, 11, 31);
	this.dayNames = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
	this.monthNames = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August',
										 'September', 'October', 'November', 'December');
	this.dependent = null;
	this.useDayNames = false;
	this.canBeEmpty = false;

	$("#"+this.id).hide();
	if ($("#"+this.id+'YM')) { // if has dd controls
		$("#"+this.id+'YM').change(
			function() {
				id = $(this).attr('id');
				id = id.substr(0, id.length-2);
				eval(id + '.updateYM("' + $(this).val() +'");');
			}
		);
		$("#"+this.id+'D').change(
			function() {
				id = $(this).attr('id');
				id = id.substr(0, id.length-1);
				eval(id + '.updateD("' + $(this).val() +'");');
			}
		);
	};

	this.updateYM = function(val) {
		if (!document.getElementById(this.id+'D').value || !document.getElementById(this.id+'YM').value)
			return; // don't update if empty
		var y = val.substr(0, 4);
		var m = parseInt(val.substr(5,2), 10)-1;
		var oldDay = parseInt(document.getElementById(this.id + 'D').value, 10);
		var d = oldDay;
		if (y == this.minDate.getFullYear() && m == this.minDate.getMonth())
			d = oldDay < this.minDate.getDate() ? this.minDate.getDate() : oldDay;
		if (y == this.maxDate.getFullYear() && m == this.maxDate.getMonth())
			d = oldDay > this.maxDate.getDate() ? this.maxDate.getDate() : oldDay;
		this.setDate(y, m+1, d);
	};

	this.updateD = function(val) {
		if (!document.getElementById(this.id+'D').value || !document.getElementById(this.id+'YM').value)
			return; // don't update if empty
		var d = parseInt(val, 10);
		this.setDate(this.currentYear, this.currentMonth+1, d, true);
	};

	this.setDate = function(y, m, d, quiet) {
		quiet = typeof(quiet) != 'undefined' ? quiet : false;
		this.currentDate = new Date(parseInt(y, 10), parseInt(m, 10)-1, parseInt(d, 10));
		this.currentYear = this.currentDate.getFullYear();
		this.currentMonth = this.currentDate.getMonth();

		if (!quiet)
			this._updateInputs();
		if (this.dependent)
			eval(this.dependent + '.setMinDate(' + this.currentYear + ', ' +
																(this.currentMonth+1) + ', ' + this.currentDate.getDate() + ')');
	};

	this.setDependent = function(dep) {
		this.dependent = dep;
	};

	this.canBeEmpty = function(flag) {
		this.canBeEmpty = flag;
	};

	this.setMinDate = function(y, m, d) {
		this.minDate = new Date(parseInt(y, 10), parseInt(m, 10)-1, parseInt(d, 10));
		if (this.currentDate.getTime() < this.minDate.getTime())
			this.setDate(this.minDate.getFullYear(), this.minDate.getMonth()+1, this.minDate.getDate());
		else
			this._updateInputs(); // should update input, to fill in new allowed values
	};

	this.setMaxDate = function(y, m, d) {
		this.maxDate = new Date(parseInt(y, 10), parseInt(m, 10)-1, parseInt(d, 10));
	};

	this.setDayNames = function (sun, mon, tue, wed, thu, fri, sat) {
		this.dayNames = new Array(sun, mon, tue, wed, thu, fri, sat);
	};

	this.setMonthNames = function(jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec) {
		this.monthNames = new Array(jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec);
	};

	this.setUseDayNames = function(flag) {
		this.useDayNames = flag;
	};

	this.toggle = function() {
		if ($("#"+this.id).is(":visible"))
			this._hide();
		else {
			$('.calWrapper').hide(); // hide others
			this._show();
		}
	};

	this.selectDay = function(d) {
		this._unmarkCurrentDay();
		this.setDate(this.currentYear, this.currentMonth+1, d);
		this._markCurrentDay();
		this._hide();
	};

	this.prev = function() {
		if (--this.currentMonth < 0) {
			this.currentMonth = 11;
			this.currentYear--;
		}
		this._initMonth();
	};

	this.next = function() {
		if (++this.currentMonth > 11) {
			this.currentMonth = 0;
			this.currentYear++;
		}
		this._initMonth();
	};

	this._show = function() {
		document.getElementById(this.id).innerHTML = this._drawFrame();
		document.getElementById(this.id + '_daynames').innerHTML = this._drawDayNames();
		this._initMonth();
		$("#"+this.id).show();
	};

	this._initMonth = function() {
		document.getElementById(this.id + '_monthnavig').innerHTML = this._drawMonthNavig();
		document.getElementById(this.id + '_months').innerHTML = this._drawCurrentMonth();
		this._markCurrentDay();
	};

	this._hide = function() {
		$("#"+this.id).hide();
	};

	/**
	 * Draw month navig
	 * @return string
	 */
	this._drawMonthNavig = function() {
		var navigTxt = '';
		navigTxt += this._drawPrevBtn(this.currentYear > this.minDate.getFullYear() ||
												this.currentMonth > this.minDate.getMonth());
		navigTxt += this._drawMonthLabel();
		navigTxt += this._drawNextBtn(this.currentYear < this.maxDate.getFullYear() ||
												this.currentMonth < this.maxDate.getMonth());
		navigTxt += this._drawBreak();
		return navigTxt;
	};

	/**
	 * Draw day names
	 * @return string
	 */
	this._drawDayNames = function() {
		var daysTxt = '';
		for (i=0; i<7; i++)
			daysTxt += this._drawDayName(i);
		daysTxt += this._drawBreak();
		return daysTxt;
	};

	/**
	 * Draw days for current month
	 * @return string
	 */
	this._drawCurrentMonth = function() {
		var daysTxt = '';
		var startDate = new Date(this.currentYear, this.currentMonth, 1);
		var endDate = new Date(this.currentYear, this.currentMonth+1, 0);
		var lastMonEndDate = new Date(this.currentYear, this.currentMonth, 0);
		var dow = startDate.getDay();
		var min = this._getMinDateBoundary();
		var max = this._getMaxDateBoundary();

		for (i=0; i<dow; i++)
			daysTxt += this._drawDay(lastMonEndDate.getDate()-dow+i+1, false);
		for (i=1; i<=endDate.getDate(); i++) {
			daysTxt += this._drawDay(i, i>=min && i<=max);
			if (++dow == 7) {
				daysTxt += this._drawBreak();
				dow = 0;
			}
		}
		var nextMon = 1;
		while (dow < 7) {
			daysTxt += this._drawDay(nextMon++, false);
			dow++;
		}

		return daysTxt;
	};

	/**
	 * Gets min date boundary for current month
	 * @return int
	 */
	this._getMinDateBoundary = function() {
		if (this.minDate.getFullYear() < this.currentYear)
			return 0;
		else if (this.minDate.getFullYear() > this.currentYear)
			return 32;
		if (this.minDate.getMonth() < this.currentMonth)
			return 0;
		else if (this.minDate.getMonth() > this.currentMonth)
			return 32;
		else
			return this.minDate.getDate();
	};

	/**
	 * Gets max date boundary for current month
	 * @return int
	 */
	this._getMaxDateBoundary = function() {
		if (this.maxDate.getFullYear() > this.currentYear)
			return 32;
		else if (this.maxDate.getFullYear() < this.currentYear)
			return 0;
		if (this.maxDate.getMonth() > this.currentMonth)
			return 32;
		else if (this.maxDate.getMonth() < this.currentMonth)
			return 0;
		else
			return this.maxDate.getDate();
	};


	this._markCurrentDay = function() {
		var id = this.name+'_'+this.currentDate.getFullYear()+'_'+this.currentDate.getMonth()+
								 '_'+this.currentDate.getDate();
		if (document.getElementById(id))
			document.getElementById(id).className = "calday selected";
	};

	this._unmarkCurrentDay = function() {
		var id = this.name+'_'+this.currentDate.getFullYear()+'_'+this.currentDate.getMonth()+
								 '_'+this.currentDate.getDate();
		if (document.getElementById(id))
			document.getElementById(id).className = "calday active";
	};

	/**
	 * Draw frame
	 * @return string
	 */
	 this._drawFrame = function() {
		 return '<div class="calFrame">'+
				  '<div class="monthnavig" id="'+this.id+'_monthnavig"></div>'+
				  '<div class="daynames" id="'+this.id+'_daynames"></div>'+
				  '<div class="months" id="'+this.id+'_months"></div>'+
				  '<div style="clear: both"></div></div>';
	 };

	this._drawDay = function(day, active) {
		return '<div style="float: left"'+
				 (active ? ' id="'+this.name+'_'+this.currentYear+'_'+this.currentMonth+'_'+day+'"' +
							  ' onclick="'+this.name+'.selectDay('+day+')" ' +
							  ' class="calday active"'
							: ' class="calday inactive"') +
				 '>'+day+'</div>';
	};

	this._drawEmpty = function() {
		return '<div class="calday empty" style="float: left"></div>';
	};

	this._drawDayName = function(i) {
		return '<div class="calday" style="float: left">' + this.dayNames[i].substr(0,1) + '</div>';
	};

	this._drawBreak = function() {
		return '<div style="clear: both"></div>';
	};

	this._drawMonthLabel = function() {
		return '<div style="float:left" class="monthlabel">' +
				 this.monthNames[this.currentMonth] + ' ' + this.currentYear +
				 '</div>';
	};

	this._drawPrevBtn = function(active) {
		return '<div style="float: left" ' +
				 (active ? ' onclick="'+this.name+'.prev(); dontHideCal=true" ' +
							  ' class="calday active"'
							: ' class="calday inactive"') +
				 '>&lt;</div>';
	};

	this._drawNextBtn = function(active) {
		return '<div style="float: left" ' +
				 (active ? ' onclick="'+this.name+'.next(); dontHideCal=true" ' +
							  ' class="calday active"'
							: ' class="calday inactive"') +
				 '>&gt;</div>';
	};

	this._updateInputs = function() {
		if ($('#' + this.id + 'YM')) {
			// has dropdowns
			this._updateYM();
			this._updateD();
		}
	};

	this._updateYM = function() {
		if (!this.currentYear || !this.currentMonth)
			return;
		else if (!document.getElementById(this.id+'D').value || !document.getElementById(this.id+'YM').value)
			return; // don't update if empty

		var target = document.getElementById(this.id+'YM');
		target.options.length = 0;
		if (this.canBeEmpty)
			target.options[target.options.length] = new Option('--', '');
		for (var i=this.minDate.getFullYear(); i<=this.maxDate.getFullYear(); i++) {
			for (var j=(i==this.minDate.getFullYear() ? this.minDate.getMonth() : 0);
				  j<=(i==this.maxDate.getFullYear() ? this.maxDate.getMonth() : 11);
				  j++) {
				target.options[target.options.length] = new Option(this.monthNames[j].substr(0,3).toLowerCase()+' '+i,
																					i+'-'+ (j<9 ? '0': '') + (j+1));
			}
		}
		target.value = this.currentYear + '-' + (this.currentMonth < 9 ? '0' : '') + (this.currentMonth+1);
	};

	this._updateD = function() {

		if (!this.currentYear || (!this.currentMonth && this.currentMonth !== 0)) // month can be zero (jan)
			return;
		if (!document.getElementById(this.id+'D').value || !document.getElementById(this.id+'YM').value)
			return; // don't update if empty

		var target = document.getElementById(this.id+'D');
		target.options.length = 0;
		if (this.canBeEmpty)
			target.options[target.options.length] = new Option('--', '');
		var firstDayInMonth = new Date(this.currentYear, this.currentMonth, 1);
		var lastDayInMonth = new Date(this.currentYear, this.currentMonth+1, 0);
		var dowStart = firstDayInMonth.getDay();
		for (i= (this.minDate.getFullYear() == this.currentYear && this.minDate.getMonth() == this.currentMonth
				   ? this.minDate.getDate() : 1);
			  i<=(this.maxDate.getFullYear() == this.currentYear && this.maxDate.getMonth() == this.currentMonth
				   ? this.maxDate.getDate() : lastDayInMonth.getDate());
			  i++) {
			target.options[target.options.length] =
				new Option((i<10 ? '0': '') + i +
									(this.useDayNames
									 ? ' (' + this.dayNames[(dowStart + i - 1) % 7].substr(0,3).toLowerCase() + ')'
									 : ''),
							  (i<10 ? '0': '') + i);
		}
		target.value = (this.currentDate.getDate()<10 ? '0': '') + this.currentDate.getDate();
	}
;
}

