﻿/*!
* Title:  jMonthCalendar 1.2.1
* Dependencies:  jQuery 1.3.0 +
* Author:  Kyle LeNeau
* Email:  kyle.leneau@gmail.com
* Project Hompage:  http://www.bytecyclist.com/projects/jmonthcalendar
* Source:  http://code.google.com/p/jmonthcalendar
*
*/

(function($) {
	var ids = {
			container: "#jMonthCalendar",
			head: "#CalendarHead",
			body: "#CalendarBody"
	};
	var _startBorder;
	var _endBorder;
	var _selectedDate;
	var _beginDate;
	var _endDate;
	var calendarEvents;
	var defaults = {
			width: 150,
			navHeight: 25,
			labelHeight: 25,
			firstDayOfWeek: 1,
			calendarStartDate:new Date(),
			navLinks: {
				p:'&larr;', 
				n:'&rarr;', 
				t:''
			},
			onMonthChanging: function(dateIn) { return true; },
			onMonthChanged: function(dateIn) { return true; },
			onEventLinkClick: function(event) { return true; },
			onEventBlockClick: function(event) { return true; },
			onEventBlockOver: function(event) { return true; },
			onEventBlockOut: function(event) { return true; },
			onDayLinkClick: function(date) { return true; },
			onDayCellClick: function(date) { return true; },
			locale: {
				days: ["Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"],
				daysShort: ["Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"],
				daysMin: ["Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"],
				months: ["Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"],
				monthsShort: ["jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep", "oct", "nov", "dec"],
				weekMin: 'нед'
			}
		};
	
	var getDateFromId = function(dateIdString) {
		//c_01012009		
		return new Date(dateIdString.substring(6, 10), dateIdString.substring(2, 4)-1, dateIdString.substring(4, 6));
	};
	var getDateId = function(date) {
		var month = ((date.getMonth()+1)<10) ? "0" + (date.getMonth()+1) : (date.getMonth()+1);
		var day = (date.getDate() < 10) ? "0" + date.getDate() : date.getDate();
		return "c_" + month + day + date.getFullYear();
	};
	var GetJSONDate = function(jsonDateString) {
		//check conditions for different types of accepted dates
		var tDt, k;
		if (typeof jsonDateString == "string") {
			
			//  "2008-12-28T00:00:00.0000000"
			var isoRegPlus = /^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2}).([0-9]{7})$/;
			
			//  "2008-12-28T00:00:00"
			var isoReg = /^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})$/;
		
			//"2008-12-28"
			var yyyyMMdd = /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/;
			
			//  "new Date(2009, 1, 1)"
			//  "new Date(1230444000000)
			var newReg = /^new/;
			
			//  "\/Date(1234418400000-0600)\/"
			var stdReg = /^\\\/Date\(([0-9]{13})-([0-9]{4})\)\\\/$/;
			
			if (k = jsonDateString.match(isoRegPlus)) {
				return new Date(k[1],k[2]-1,k[3]);
			} else if (k = jsonDateString.match(isoReg)) {
				return new Date(k[1],k[2]-1,k[3]);
			} else if (k = jsonDateString.match(yyyyMMdd)) {
				return new Date(k[1],k[2]-1,k[3]);
			}
			
			if (k = jsonDateString.match(stdReg)) {
				return new Date(k[1]);
			}
			
			if (k = jsonDateString.match(newReg)) {
				return eval('(' + jsonDateString + ')');
			}
			
			return tdt;
		}
	};
	jQuery.jMonthCalendar = jQuery.J = function() {};


			
		
	jQuery.J.ExtendDate = function(options) {
		if (Date.prototype.tempDate) {
			return;
		}
		Date.prototype.tempDate = null;
		Date.prototype.months = defaults.locale.months;
		Date.prototype.monthsShort = defaults.locale.monthsShort;
		Date.prototype.days = defaults.locale.days;
		Date.prototype.daysShort = defaults.locale.daysShort;
		Date.prototype.getMonthName = function(fullName) {
			return this[fullName ? 'months' : 'monthsShort'][this.getMonth()];
		};
		Date.prototype.getDayName = function(fullName) {
			return this[fullName ? 'days' : 'daysShort'][this.getDay()];
		};
		Date.prototype.getShortDate = function() {
			this.setHours(0,0,0,0);
			return this;
		};
		Date.prototype.toShortDateString = function() {
			return (this.getMonth()+1) + "/" + this.getDate() + "/" + this.getFullYear();
		};
		Date.prototype.addDays = function (n) {
			this.setDate(this.getDate() + n);
			this.tempDate = this.getDate();
		};
		Date.prototype.addMonths = function (n) {
			if (this.tempDate == null) {
				this.tempDate = this.getDate();
			}
			this.setDate(1);
			this.setMonth(this.getMonth() + n);
			this.setDate(Math.min(this.tempDate, this.getMaxDays()));
		};
		Date.prototype.addYears = function (n) {
			if (this.tempDate == null) {
				this.tempDate = this.getDate();
			}
			this.setDate(1);
			this.setFullYear(this.getFullYear() + n);
			this.setDate(Math.min(this.tempDate, this.getMaxDays()));
		};
		Date.prototype.getMaxDays = function() {
			var tmpDate = new Date(Date.parse(this)),
				d = 28, m;
			m = tmpDate.getMonth();
			d = 28;
			while (tmpDate.getMonth() == m) {
				d ++;
				tmpDate.setDate(d);
			}
			return d - 1;
		};
		Date.prototype.getFirstDay = function() {
			var tmpDate = new Date(Date.parse(this));
			tmpDate.setDate(1);
			return tmpDate.getDay();
		};
		Date.prototype.getWeekNumber = function() {
			var tempDate = new Date(this);
			tempDate.setDate(tempDate.getDate() - (tempDate.getDay() + 6) % 7 + 3);
			var dms = tempDate.valueOf();
			tempDate.setMonth(0);
			tempDate.setDate(4);
			return Math.round((dms - tempDate.valueOf()) / (604800000)) + 1;
		};
		Date.prototype.getDayOfYear = function() {
			var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
			var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0);
			var time = now - then;
			return Math.floor(time / 24*60*60*1000);
		};
	}
	
	jQuery.J.DrawCalendar = function(dateIn){
		var today = defaults.calendarStartDate;
		var d;
		
		if(dateIn == undefined) {
			//start from this month
			d = new Date(today.getFullYear(), today.getMonth(), 1);
		} else {
			//start from the passed in date
			d = dateIn;
			d.setDate(1);
		}
		
		
		// Create Previous Month link for later
		var prevMonth = d.getMonth() == 0 ? new Date(d.getFullYear()-1, 11, 1) : new Date(d.getFullYear(), d.getMonth()-1, 1);
		prevMonth = prevMonth.getMonth() == 0 ? new Date(prevMonth.getFullYear()-1, 11, 1) : new Date(prevMonth.getFullYear(), prevMonth.getMonth()-1, 1);
		var prevMLink;
		if ((prevMonth.getMonth() >= _startBorder.getMonth()) && (prevMonth.getFullYear() == _startBorder.getFullYear()) ) {
			prevMLink = jQuery('<div class="MonthNavPrev"><a href="" class="link-prev">'+ defaults.navLinks.p +'</a></div>').click(function() {
				jQuery.J.ChangeMonth(prevMonth);
				return false;
			});
		}
		else {
			prevMLink = jQuery('<div class="MonthNavPrev"></div>');
		}
		
		//Create Next Month header
		var nextMonth = d.getMonth() == 11 ? new Date(d.getFullYear()+1, 0, 1) : new Date(d.getFullYear(), d.getMonth()+1, 1);
		
		//Create Next Month link for later
		var nextMonth2 = nextMonth.getMonth() == 11 ? new Date(nextMonth.getFullYear()+1, 0, 1) : new Date(nextMonth.getFullYear(), nextMonth.getMonth()+1, 1);
		var nextMLink;
		if ((nextMonth2.getMonth() <= _endBorder.getMonth() && (nextMonth2.getFullYear() == _endBorder.getFullYear())) || ((nextMonth2.getMonth() > _endBorder.getMonth()) && (nextMonth2.getFullYear() != _endBorder.getFullYear()))) {
			nextMLink = jQuery('<div class="MonthNavNext"><a href="" class="link-next">'+ defaults.navLinks.n +'</a></div>').click(function() {
				jQuery.J.ChangeMonth(nextMonth2);
				return false;
			});
		}
		else {
			nextMLink = jQuery('<div class="MonthNavNext"></div>');
		}
		
		
		//Build up the Header first,  Navigation
		var navRow = jQuery('<div><div><div class="FormHeader MonthNavigation"></div></div></div>');
		
		jQuery('.MonthNavigation', navRow).append(prevMLink, nextMLink);
		jQuery('.MonthNavigation', navRow).append(jQuery('<div class="MonthName"></div>').append(defaults.locale.months[d.getMonth()]));
		
		
		//  Days
		var headRow = jQuery("<div class=\"DaysRowHeader\"></div>");
		
		for (var i=defaults.firstDayOfWeek; i<defaults.firstDayOfWeek+7; i++) {
			var weekday = i%7;
			var wordday = defaults.locale.days[weekday];
			headRow.append('<div class="DateHeader' + (weekday == 0 || weekday == 6 ? ' Weekend' : '') + '">' + wordday + '</div>');
		}
		
		headRow = jQuery("<div id=\"CalendarHead\"></div>").append(headRow);
		headRow = headRow.prepend(navRow);


		//Build up the Body
		var tBody = jQuery('<div id="CalendarBody"></div>');
		var isCurrentMonth = (d.getMonth() == today.getMonth() && d.getFullYear() == today.getFullYear());
		var maxDays = d.getMaxDays();
		
		
		//what is the current day #
		var curDay = defaults.firstDayOfWeek - d.getDay();
		if (curDay > 0) curDay -= 7
		
		var t = (maxDays + Math.abs(curDay));
		
		_beginDate = new Date(d.getFullYear(), d.getMonth(), curDay+1);
		_endDate = new Date(d.getFullYear(), d.getMonth()+1, (7-(t %= 7)) == 7 ? 0 : (7-(t %= 7)));
		var _currentDate = new Date(_beginDate.getFullYear(), _beginDate.getMonth(), _beginDate.getDate());


		var toDayIs = new Date;
		
		// Render calendar
		var rowCount = 0;
		var rowHeight = (defaults.height - defaults.labelHeight - defaults.navHeight) / Math.ceil((maxDays + Math.abs(curDay)) / 7);
		
		do {
	  		var thisRow = jQuery("<div class=\"DaysRow\"></div>");
			
			for (var i=0; i<7; i++) {
				var weekday = (defaults.firstDayOfWeek + i) % 7;
				var atts = {'class':"DateBox" + (weekday == 0 || weekday == 6 ? ' Weekend ' : '')
				};

				if (curDay < 0 || curDay >= maxDays) {
					atts['class'] += ' Inactive';
				} else {
					d.setDate(curDay+1);
				}
					
				if (isCurrentMonth && curDay+1 == today.getDate()) {
					dayStr = curDay+1;
					atts['class'] += ' Today';
				}
			
				var dayLink;
				if ( ($('a[name=' + _currentDate.getDate() + defaults.locale.monthsShort[_currentDate.getMonth()] + ']').length) && ( (_currentDate.getFullYear() != toDayIs.getFullYear()) || (_currentDate.getMonth() > toDayIs.getMonth()) || (((_currentDate.getDate() >= toDayIs.getDate()) && (_currentDate.getMonth() == toDayIs.getMonth()))) ) ) {
					dayLink = jQuery('<a href="#' + _currentDate.getDate() + defaults.locale.monthsShort[_currentDate.getMonth()] + '">' + _currentDate.getDate() + '</a>');
				}
				else {
					dayLink = jQuery('<span>' + _currentDate.getDate() + '</span>');

				}
				thisRow.append(jQuery("<div></div>").attr(atts).append(dayLink));
					
				curDay++;
				_currentDate.addDays(1);
			}
			
			rowCount++;
			tBody.append(thisRow);
		} while (curDay < maxDays);


		var a = jQuery(ids.container);
		var cal = jQuery('<div class="MonthlyCalendar"></div>').append(headRow, tBody);
		
		
		if ((nextMonth.getMonth() <= _endBorder.getMonth()) || ((nextMonth.getMonth() > _endBorder.getMonth()) && (nextMonth.getFullYear() != _endBorder.getFullYear()))) {
			var navRow2 = jQuery('<div><div><div class="FormHeader MonthNavigation"></div></div></div>').append(jQuery('<div class="MonthName"></div>').append(defaults.locale.months[nextMonth.getMonth()]));
			var headRow2 = jQuery("<div class=\"secondMonth\"></div>").append(navRow2);
			
			//Build up the Body
		var tBody2 = jQuery('<div class="secondMonthBody"></div>');
		maxDays = nextMonth.getMaxDays();
		
		
		//what is the currect day #
		curDay = defaults.firstDayOfWeek - nextMonth.getDay();
		if (curDay > 0) curDay -= 7
		
		t = (maxDays + Math.abs(curDay));
		
		_beginDate = new Date(nextMonth.getFullYear(), nextMonth.getMonth(), curDay+1);
		_endDate = new Date(nextMonth.getFullYear(), nextMonth.getMonth()+1, (7-(t %= 7)) == 7 ? 0 : (7-(t %= 7)));
		_currentDate = new Date(_beginDate.getFullYear(), _beginDate.getMonth(), _beginDate.getDate());

		
		// Render calendar
		rowCount = 0;
		rowHeight = (defaults.height - defaults.labelHeight - defaults.navHeight) / Math.ceil((maxDays + Math.abs(curDay)) / 7);
		
		do {
	  		var thisRow = jQuery("<div class=\"DaysRow\"></div>");
			
			for (var i=0; i<7; i++) {
				var weekday = (defaults.firstDayOfWeek + i) % 7;
				var atts = {'class':"DateBox" + (weekday == 0 || weekday == 6 ? ' Weekend ' : '')
				};

				if (curDay < 0 || curDay >= maxDays) {
					atts['class'] += ' Inactive';
				} else {
					d.setDate(curDay+1);
				}
					
				if (isCurrentMonth && curDay+1 == today.getDate()) {
					dayStr = curDay+1;
					atts['class'] += ' Today';
				}
			
				var dayLink;
				if ($('a[name=' + _currentDate.getDate() + defaults.locale.monthsShort[_currentDate.getMonth()] + ']').length) {
					dayLink = jQuery('<a href="#' + _currentDate.getDate() + defaults.locale.monthsShort[_currentDate.getMonth()] + '">' + _currentDate.getDate() + '</a>');
				}
				else {
					dayLink = jQuery('<span>' + _currentDate.getDate() + '</span>');

				}
				thisRow.append(jQuery("<div></div>").attr(atts).append(dayLink));
					
				curDay++;
				_currentDate.addDays(1);
			}
			
			rowCount++;
			tBody2.append(thisRow);
		} while (curDay < maxDays);
			
			
			cal = cal.append(headRow2, tBody2);
		}
		
	
		a.hide();
		a.html(cal);		
		a.show();
		
		
	}
	
	jQuery.J.ChangeMonth = function(dateIn) {
		defaults.onMonthChanging(dateIn);
		jQuery.J.DrawCalendar(dateIn);
		defaults.onMonthChanged(dateIn);
	}

	jQuery.J.Initialize = function(options) {
		var today = new Date();
		
		options = jQuery.extend(defaults, options);
		jQuery.J.ExtendDate(options);
		
		_startBorder = new Date();
		var aName = $('#columnmain h5:first a').attr('name');
		if (aName.length == 5) {
			_startBorder.setDate(aName.substring(0,2));
			_startBorder.setMonth(in_array(aName.substring(2), defaults.locale.monthsShort));
		}
		else {
			_startBorder.setDate(aName.substring(0,1));
			_startBorder.setMonth(in_array(aName.substring(1), defaults.locale.monthsShort));
		}


		_endBorder = new Date();
		aName = $('#columnmain h5:last a').attr('name');
		if (aName.length == 5) {
			_endBorder.setDate(aName.substring(0,2));
			_endBorder.setMonth(in_array(aName.substring(2), defaults.locale.monthsShort));
		}
		else {
			_endBorder.setDate(aName.substring(0,1));
			_endBorder.setMonth(in_array(aName.substring(1), defaults.locale.monthsShort));
		}
		
		if (_endBorder.getMonth() < _startBorder.getMonth()) {
			_endBorder.setFullYear(_endBorder.getFullYear()+1);
		}

		
		jQuery.J.DrawCalendar();
		
	};
})(jQuery);


function in_array(needle, haystack) {    // Checks if a value exists in an array
    // 
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
 
    var found, key;
 
    for (key in haystack) {
        if (haystack[key] === needle) {
            found = key;
            break;
        }
    }
 
    return found;
}
