/*
 * jCal calendar multi-day and multi-month datepicker plugin for jQuery
 *	version 0.3.7
 * Author: Jim Palmer
 * Released under MIT license.
 */
(function($) {
	var spacial_days = new Array('2011-12-30', '2011-12-31', '2012-1-3');
	var half_days = new Array('2011-12-28', '2011-12-29', '2012-1-4', '2012-1-5');

	$.fn.jCal = function (opt) {
		$.jCal(this, opt);
		return this;
	};
	$.jCal = function (target, opt) {
		opt = $.extend({
			day:			new Date(),									// date to drive first cal
			days:			1,											// default number of days user can select
			showMonths:		1,											// how many side-by-side months to show
			monthSelect:	false,										// show selectable month and year ranges via animated comboboxen
			dCheck:			function (day) { return 'day'; },			// handler for checking if single date is valid or not - returns class to add to day cell
			callback:		function (day, days) { return true; },		// callback function for click on date
			drawBack:		function () { return true; },				// callback function for month being drawn
			selectedBG:		'rgb(0, 143, 214)',							// default bgcolor for selected date cell
			defaultBG:		'rgb(255, 255, 255)',						// default bgcolor for unselected date cell
			dayOffset:		0,											// 0=week start with sunday, 1=week starts with monday
			scrollSpeed:	150,										// default .animate() speed used
			forceWeek:		false,										// true=force selection at start of week, false=select days out from selected day
			dow:			['S', 'M', 'T', 'W', 'T', 'F', 'S'],		// days of week - change this to reflect your dayOffset
			dow_en:			['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'],		// days of week - change this to reflect your dayOffset
			ml:				['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
			ms:				['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
			_target:		target										// target DOM element - no need to set extend this variable
		}, opt);
		opt.isSunday = function (year, month, day) {
			var week = new Date(year, month - 1, day).getDay();
		    if (week == 0) {
		        return true;
		    }
		    return false;
		};
		opt.hCheck = function (year, month, day) {
			var week = new Date(year, month - 1, day).getDay();
		    switch(parseInt(month,10)) {
		    case 1:
		        if (day == 1) {
		            return 'day holiday';
		        }
		        if (day == 2) {
		        	var week = new Date(year, month - 1, 1).getDay();
	                if (week == 0) {
	                	return 'day holiday';
	                }
		        }
	    	    var monday;
	    	    for(monday = 1; monday < 8; monday++) {
	    	        if(new Date(year, month - 1, monday).getDay() == 1) {
	    	            break;
	    	        }
	    	    }
		        if (day == (monday + 7)) {
		            return 'day holiday';
		        }
		        break;
		    case 2:
		        if (day == 11) {
		            return 'day holiday';
		        }
		        if (day == 12) {
	        		var week = new Date(year, month - 1, 11).getDay();
	        		if (week == 0) {
                		return 'day holiday';
                	}
		        }
		        break;
		    case 3:
		            if (day == parseInt(20.8431 + 0.242194 * (year - 1980) - parseInt((year - 1980) / 4))) {
		                return 'day holiday';
		            }
		            if (day == (parseInt(20.8431 + 0.242194 * (year - 1980) - parseInt((year - 1980) / 4)) + 1)) {
		            	var week = new Date(year, month - 1, day - 1).getDay();
		                if (week == 0) {
		                	return 'day holiday';
		                }
		            }
		        break;
		    case 4:
		        if (day == 29) {
		            return 'day holiday';
		        }
		        if (day == 30) {
	        		var week = new Date(year, month - 1, 29).getDay();
	        		if (week == 0) {
                		return 'day holiday';
                	}
		        }
		        break;
		    case 5:
		        if (day == 3 || day == 4 || day == 5) {
		            return 'day holiday';
		        }
		        if (day == 6) {
		        	var week = new Date(year, month - 1, 3).getDay();
	        		if (week == 0) {
                		return 'day holiday';
                	}
		        	var week = new Date(year, month - 1, 4).getDay();
	        		if (week == 0) {
                		return 'day holiday';
                	}
		        	var week = new Date(year, month - 1, 5).getDay();
	        		if (week == 0) {
                		return 'day holiday';
                	}
		        }
		        break;
		    case 7:
	    	    var monday;
	    	    for(monday = 1; monday < 8; monday++) {
	    	        if(new Date(year, month - 1, monday).getDay() == 1) {
	    	            break;
	    	        }
	    	    }
		        if (day == (monday + 14)) {
		            return 'day holiday';
		        }
		        break;
		    case 9:
		    	var monday;
	    	    for(monday = 1; monday < 8; monday++) {
	    	        if(new Date(year, month - 1, monday).getDay() == 1) {
	    	            break;
	    	        }
	    	    }
		        if (day == (monday + 14)) {
		            return 'day holiday';
		        }
		        if(year > 1979 && year < 2100) {
		            if (day == parseInt(23.2488 + 0.242194 * (year - 1980) - parseInt((year - 1980) / 4))) {
		                return 'day holiday';
		            }
		            if (day == (parseInt(23.2488 + 0.242194 * (year - 1980) - parseInt((year - 1980) / 4)) + 1)) {
		            	var week = new Date(year, month - 1, day - 1).getDay();
		        		if (week == 0) {
	                		return 'day holiday';
	                	}
		            }
		        }
		        var day2 = parseInt(day, 10);
		        if(day2 - 1 == (monday + 14))  {
		        	if (day2 + 1 == parseInt(23.2488 + 0.242194 * (year - 1980) - parseInt((year - 1980)  / 4))) {
		                return 'day holiday';
		        	}
		        	if (day2 + 1 == (parseInt(23.2488 + 0.242194 * (year - 1980) - parseInt((year - 1980) / 4)) + 1)) {
		        		var week = new Date(year, month - 1, day - 1).getDay();
		        		if (week == 0) {
	                		return 'day holiday';
	                	}
		            }
		        }
		        break;
		    case 10:
		    	    var monday;
		    	    for(monday = 1; monday < 8; monday++) {
		    	        if(new Date(year, month - 1, monday).getDay() == 1) {
		    	            break;
		    	        }
		    	    }

		        if (day == (monday + 7)) {
		            return 'day holiday';
		        }
		        break;
		    case 11:
		        if (day == 3 || day == 23) {
		            return 'day holiday';
		        }
		        if (day == 4) {
		        	var week = new Date(year, month - 1, 3).getDay();
	        		if (week == 0) {
                		return 'day holiday';
                	}
		        }
		        if (day == 24) {
		        	var week = new Date(year, month - 1, 23).getDay();
	        		if (week == 0) {
                		return 'day holiday';
                	}
		        }
		        break;
		    case 12:
		        if (day == 23) {
		            return 'day holiday';
		        }
		        if (day == 24) {
		        	var week = new Date(year, month - 1, 23).getDay();
	        		if (week == 0) {
                		return 'day holiday';
                	}
		        }
		        break;
		    }
		    for (var sm=0; sm < spacial_days.length; sm++) {
		    	if (year + '-' + month + '-' + day == spacial_days[sm]) {
	        		return 'day special';
			    }
		    }
		    for (var sm=0; sm < half_days.length; sm++) {
		    	if (year + '-' + month + '-' + day == half_days[sm]) {
	        		return 'day half';
			    }
		    }
		    if (month == (new Date().getMonth() + 1) && day == new Date().getDate()) {
        		return 'day today';
		    }
		    var week = new Date(year, month - 1, day).getDay();
		    if (week == 0) {
		        return 'day sun';
		    } else if(week == 6) {
		        return 'day sat';
		    }

			return 'day';
		};
		opt.day = new Date(opt.day.getFullYear(), opt.day.getMonth(), 1);
		if ( !$(opt._target).data('days') ) $(opt._target).data('days', opt.days);
		$(target).stop().empty();
		for (var sm=0; sm < opt.showMonths; sm++)
			$(target).append('<div class="jCalMo"></div>');
		opt.cID = 'c' + $('.jCalMo').length;
		$('.jCalMo', target).each(
			function (ind) {
				drawCalControl($(this), $.extend( {}, opt, { 'ind':ind,
						'day':new Date( new Date( opt.day.getTime() ).setMonth( new Date( opt.day.getTime() ).getMonth() + ind ) ) }
					));
				drawCal($(this), $.extend( {}, opt, { 'ind':ind,
						'day':new Date( new Date( opt.day.getTime() ).setMonth( new Date( opt.day.getTime() ).getMonth() + ind ) ) }
					));
			});
	};
	function drawCalControl (target, opt) {
		$(target).append(
			'<div class="jCal">' +
					'<div class="month">' +
						'<span class="monthYear">' + opt.day.getFullYear() + '年</span>' +
						'<span class="monthName">' + opt.ml[opt.day.getMonth()] + '</span>' +
					'</div>' +
			'</div>');
	};
	function drawCal (target, opt) {
		for (var ds=0, length=opt.dow.length; ds < length; ds++) {
			$(target).append('<div class="dow dow_' + opt.dow_en[ds] + '">' + opt.dow[ds] + '</div>');
		}
		var fd = new Date( new Date( opt.day.getTime() ).setDate(1) );
		var ldlm = new Date( new Date( fd.getTime() ).setDate(0) );
		var ld = new Date( new Date( new Date( fd.getTime() ).setMonth( fd.getMonth() + 1 ) ).setDate(0) );
		var copt = {fd:fd.getDay(), lld:ldlm.getDate(), ld:ld.getDate()};
		var offsetDayStart = ( ( copt.fd < opt.dayOffset ) ? ( opt.dayOffset - 7 ) : 1 );
		var offsetDayEnd = ( ( ld.getDay() < opt.dayOffset ) ? ( 7 - ld.getDay() ) : ld.getDay() );
		for ( var d = offsetDayStart, dE = ( copt.fd + copt.ld + ( 7 - offsetDayEnd ) ); d < dE; d++)
			$(target).append(
				(( d <= ( copt.fd - opt.dayOffset ) ) ?
					'<div id="' + opt.cID + 'd' + d + '" class="pday">' + ( copt.lld - ( ( copt.fd - opt.dayOffset ) - d ) ) + '</div>'
					: ( ( d > ( ( copt.fd - opt.dayOffset ) + copt.ld ) ) ?
						'<div id="' + opt.cID + 'd' + d + '" class="aday">' + ( d - ( ( copt.fd - opt.dayOffset ) + copt.ld ) ) + '</div>'
						: '<div id="' + opt.cID + 'd_' + (fd.getMonth() + 1) + '_' + ( d - ( copt.fd - opt.dayOffset ) ) + '_' + fd.getFullYear() + '" class="' +
							( opt.hCheck( fd.getFullYear(), (fd.getMonth() + 1), ( d - ( copt.fd - opt.dayOffset ) ) ) || 'invday' ) +
							'">' + ( d - ( copt.fd - opt.dayOffset ) )  + '</div>'
					)
				)
			);
		$(target).find('div[id^=' + opt.cID + 'd]:first, div[id^=' + opt.cID + 'd]:nth-child(7n+2)').before( '<br style="clear:both;" />' );
		$(target).find('div[id^=' + opt.cID + 'd_]:not(.invday)').bind("mouseover mouseout click", $.extend( {}, opt ),
			function(e){});
	};
})(jQuery);
