// ============================LICENSE================================
/*	 Author: QiaoLu <jody@cpgroup.cn>
	 WWW: http://www.coolwen.com/

	* NOTICE: You may use this code for any purpose, commercial or
	* private, without any further permission from the author. You may
	* remove this notice from your final code if you wish, however it is
	* appreciated by the author if at least my web site address is kept.
	*
	* You may *NOT* re-distribute this code in any way except through its
	* use. That means, you can include it in your product, or your web
	* site, or any other form where the code is actually being used. You
	* may not put the plain javascript up on your site for download or
	* include it in your javascript libraries for download. 
	* If you wish to share this code with others, please just point them
	* to the URL instead.
	* Please DO NOT link directly to my .js files from your site. Copy
	* the files to your server and use them there. Thank you.
*/

// ==============================HISTORY==============================

/*
	
*/

// ============================DESCRIPTION============================

/*
	* This object implements a popup calendar to allow the user to
	* select a date, month, quarter, or year.
*/

// ============================COMPATABILITY==========================

/*
	* Works with Netscape 4.x, 6.x, IE 5.x on Windows. Some small
	* positioning errors - usually with Window positioning - occur on the 
	* Macintosh platform.
	* The calendar can be modified to work for any location in the world by 
	* changing which weekday is displayed as the first column, changing the month
	* names, and changing the column headers for each day.
*/

// ============================USAGE=================================

/*
// Create a new Calendar object of type WINDOW
var cal = new Calendar(); 


// Easy method to link the popup calendar with an input box. 
cal.select(inputObject,dateFormat, event);

// Same method, but passing a default date other than the field's current value
cal.select(inputObject, dateFormat,event, '01/02/2000');
// This is an example call to the popup calendar from a link to populate an 
// input box. Note that to use this, date.js must also be included!!
<A HREF="#" onClick="cal.select(document.forms[0].date,dateFormat,event); return false;">Select</A>

// Set the type of date select to be used. By default it is 'date'.

cal.setDisplayType(type);

// When a date, month, quarter, or year is clicked, a function is called and
// passed the details. You must write this function, and tell the calendar
// popup what the function name is.
// Function to be called for 'date' select receives y, m, d

// Set the month names to be used. Default are English month names
cal.setMonthNames("January","February","March",...);

// Set the month abbreviations to be used. Default are English month abbreviations
cal.setMonthAbbreviations("Jan","Feb","Mar",...);

// Show navigation for changing by the year, not just one month at a time
cal.showYearNavigation();

// Show month and year dropdowns, for quicker selection of month of dates
cal.showNavigationDropdowns();

// Set the text to be used above each day column. The days start with 
// sunday regardless of the value of WeekStartDay
cal.setDayHeaders("S","M","T",...);

// Set the day for the first column in the calendar grid. By default this
// is Sunday (0) but it may be changed to fit the conventions of other
// countries.
cal.setWeekStartDay(1); // week is Monday - Saturday

// Set the weekdays which should be disabled in the 'date' select popup. You can
// then allow someone to only select week end dates, or Tuedays, for example
cal.setDisabledWeekDays(0,1); // To disable selecting the 1st or 2nd days of the week

// Selectively disable individual days or date ranges. Disabled days will not
// be clickable, and show as strike-through text on current browsers.
// Date format is any format recognized by parseDate() in date.js
// Pass a single date to disable:
cal.addDisabledDates("2003-01-01");
// Pass null as the first parameter to mean "anything up to and including" the
// passed date:
cal.addDisabledDates(null, "01/02/03");
// Pass null as the second parameter to mean "including the passed date and
// anything after it:
cal.addDisabledDates("Jan 01, 2003", null);
// Pass two dates to disable all dates inbetween and including the two
cal.addDisabledDates("January 01, 2003", "Dec 31, 2003");

// When the 'year' select is displayed, set the number of years back from the 
// current year to start listing years. Default is 2.
// This is also used for year drop-down, to decide how many years +/- to display
cal.setYearSelectStartOffset(2);

// Text for the word "Today" appearing on the calendar
cal.setTodayText("Today");
*/ 

// CONSTRUCTOR for the Calendar Object

function Calendar() {
	this.modalwindow = new modalWindow(270,200);
	this.monthNames = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
	this.monthAbbreviations = new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec");
	this.dayHeaders = new Array("Sun.","Mon.","Tues.","Wed.","Thurs.","Friday","Sat.");
	this.weekStartDay = 0;
	this.isShowYearNavigation = false;
	this.isShowYearNavigationInput=false;
	this.isShowNavigationDropdowns=false;
	this.arguments = arguments;
	this.currentDate = null;
	this.serverDate = new Date();
	this.inputobj = null;
	this.displayType = "date"
	this.format = "yyyy-MM-dd";
	this.disabledWeekDays = new Object();
	this.yearSelectStartOffset = 2;
	this.todayText = "Today";
	this.disabledDatesExpression = "";
	this.returnValue = null;
	this.offsetX = (screen.width)/2;
	this.offsety = (screen.height)/2 
}

Calendar.prototype.setReturnValue = function(year,month,date,quarter,week){
   var obj = new Object();
   obj.year = year;
   obj.month = month;
   obj.date = date;
   obj.quarter = quarter;
   obj.week = this.dayHeaders[(week-1)];
   this.returnValue = obj;
}
Calendar.prototype.getReturnValue = function(year,month,date,week,quarter){
	this.setReturnValue(year,month,date,quarter,week);
}
Calendar.prototype.setWeekStartDay = function(value){
    this.weekStartDay = value;
}

Calendar.prototype.setDisplayType = function(value){
	if (value!="date"&&value!="week-end"&&value!="month"&&value!="quarter"&&value!="year") {
		alert("Invalid display type! Must be one of: date,week-end,month,quarter,year"); 
		return false; 
	}
	this.displayType=value;
}
Calendar.prototype.setSize = function(width,height){
	this.modalwindow = new modalWindow(width,height);
}
Calendar.prototype.setYearSelectStartOffset = function(value){
	this.yearSelectStartOffset = value;
}
Calendar.prototype.setMonthNames = function(){
	for (var i=0; i<arguments.length; i++) 
		this.monthNames[i] = arguments[i]; 
}
Calendar.prototype.setDayHeaders = function(){
	for (var i=0; i<arguments.length; i++)
		this.dayHeaders[i] = arguments[i]; 
}
Calendar.prototype.setMonthAbbreviations = function(){
	for (var i=0; i<arguments.length; i++) 
		this.monthAbbreviations[i] = arguments[i]; 
}
Calendar.prototype.setDisabledWeekDays = function(){
	this.disabledWeekDays = new Object();
	for (var i=0; i<arguments.length; i++) 
		this.disabledWeekDays[arguments[i]] = true;
}
Calendar.prototype.setTodayText = function(value){
	this.todayText = value;
}

Calendar.prototype.addDisabledDates = function(start, end){
	if (arguments.length==1) { end=start; }
	if (start==null && end==null) { return; }
	if (this.disabledDatesExpression!="") { this.disabledDatesExpression+= "||"; }
	if (start!=null) { start = parseDate(start); start=""+start.getFullYear()+LZ(start.getMonth()+1)+LZ(start.getDate());}
	if (end!=null) { end=parseDate(end); end=""+end.getFullYear()+LZ(end.getMonth()+1)+LZ(end.getDate());}
	if (start==null) { this.disabledDatesExpression+="(ds<="+end+")"; }
	else if (end  ==null) { this.disabledDatesExpression+="(ds>="+start+")"; }
	else { this.disabledDatesExpression+="(ds>="+start+"&&ds<="+end+")"; }	
}
Calendar.prototype.showYearNavigation = function(){
	this.isShowYearNavigation = (arguments.length>0)?arguments[0]:true;
}
Calendar.prototype.showNavigationDropdowns = function(){
	this.isShowNavigationDropdowns = (arguments.length>0)?arguments[0]:true;
}
Calendar.prototype.showYearNavigationInput = function(){
	this.isShowYearNavigationInput = (arguments.length>0)?arguments[0]:true;
}

Calendar.prototype.select = function(inputobj, format,event){
	var selectedDate=(this.arguments.length>3)?this.arguments[3]:null;
	
	var time=0;
	if (selectedDate!=null) {
		time = getDateFromFormat(selectedDate,format)
	}else if(inputobj.value!=""){
		time = getDateFromFormat(inputobj.value,format);
		
	}
	if (selectedDate!=null || inputobj.value!="") {
		if (time==0) { this.currentDate=null; }
		else { this.currentDate=new Date(time); }
	}

	if(event.pageX){
		this.offsetX = event.screenX-4;

		this.offsetY = (event.screenY - event.pageY) + 25;

	}else{
		this.offsetX = event.screenX - 4;
		this.offsetY = event.screenY - event.offsetY + 18;
	}
	this.format = format;
	this.inputobj = inputobj;
	var serverTime = 0;
	serverTime = getDateFromFormat(inputobj.getAttribute('serverDate'),format);
	if(serverTime > 0){
		this.serverDate = new Date(serverTime);
	}
	this.showCalendar();
}

Calendar.prototype.showCalendar = function(){
	this.modalwindow.setPosition(this.offsetX,this.offsetY);
	this.modalwindow.showModalDialog(systemDefine.webRoot+'/resource/js/Calendar.html',this);
}
Calendar.prototype.formatDate = function(){
	var dt = new Date((this.returnValue.year)?this.returnValue.year:0,(this.returnValue.month)?this.returnValue.month-1:0,(this.returnValue.date)?this.returnValue.date:0,0,0,0);
	return formatDate(dt,this.format);
}

Calendar.prototype.getCalendar = function(){
	var now =this.serverDate;// new Date();
	var result = "";
	result += '<CENTER><TABLE WIDTH=100% BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>\n';

// Code for DATE display (default)
	
	// -------------------------------
	if (this.displayType=="date" || this.displayType=="week-end") {
		
		if (this.currentDate==null) { this.currentDate = now; }
		if (arguments.length > 0) { var month = arguments[0]; }
			else { var month = this.currentDate.getMonth()+1; }
		if (arguments.length > 1 && arguments[1]>0 && arguments[1]-0==arguments[1]) { var year = arguments[1]; }
			else { var year = this.currentDate.getFullYear(); }
		var daysinmonth= new Array(0,31,28,31,30,31,30,31,31,30,31,30,31);
		if ( ( (year%4 == 0)&&(year%100 != 0) ) || (year%400 == 0) ) {
			daysinmonth[2] = 29;
			}
		var current_month = new Date(year,month-1,1);
		var display_year = year;
		var display_month = month;
		var display_date = 1;
		var weekday= current_month.getDay();
		var offset = 0;
		
		offset = (weekday >= this.weekStartDay) ? weekday-this.weekStartDay : 7-this.weekStartDay+weekday ;
		if (offset > 0) {
			display_month--;
			if (display_month < 1) { display_month = 12; display_year--; }
			display_date = daysinmonth[display_month]-offset+1;
			}
		var next_month = month+1;
		var next_month_year = year;
		if (next_month > 12) { next_month=1; next_month_year++; }
		var last_month = month-1;
		var last_month_year = year;
		if (last_month < 1) { last_month=12; last_month_year--; }
		var date_class;
		result += '<TR>\n\<TD align=center><TABLE WIDTH=100% BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0><TR>';
		if (this.isShowNavigationDropdowns) {
			
			result += '<TD CLASS="cpMonthNavigation" width="50%" COLSPAN="3" align="center"><select CLASS="cpMonthNavigation" name="cpMonth" onChange="doDrow(window.dialogArguments.getCalendar(this.options[this.selectedIndex].value-0,'+(year-0)+'))">';
			for( var monthCounter=1; monthCounter<=12; monthCounter++ ) {
				var selected = (monthCounter==month) ? 'SELECTED' : '';
				result += '<option value="'+monthCounter+'" '+selected+'>'+this.monthNames[monthCounter-1]+'</option>';
			}
			result += '</select></TD>';
				
			result += '<TD CLASS="cpMonthNavigation" COLSPAN="3" width="50%" align="center"><select CLASS="cpMonthNavigation" name="cpYear" onChange="doDrow(window.dialogArguments.getCalendar('+month+',this.options[this.selectedIndex].value-0));">';
			for( var yearCounter=year-this.yearSelectStartOffset; yearCounter<=year+this.yearSelectStartOffset; yearCounter++ ) {
				var selected = (yearCounter==year) ? 'SELECTED' : '';
				result += '<option value="'+yearCounter+'" '+selected+'>'+yearCounter+'</option>';
			}
			result += '</select></TD>';
		}else {
			if (this.isShowYearNavigation) {
				result += '<TD CLASS="cpMonthNavigation" align="center" WIDTH="10%"><A CLASS="cpMonthNavigation" HREF="#" onClick="doDrow(window.dialogArguments.getCalendar('+last_month+','+last_month_year+'));">&lt;</A></TD>';
				result += '<TD CLASS="cpMonthNavigation" align="center" WIDTH="30%"><SPAN CLASS="cpMonthNavigation">'+this.monthNames[month-1]+'</SPAN></TD>';
				result += '<TD CLASS="cpMonthNavigation" align="center" WIDTH="10"><A CLASS="cpMonthNavigation" HREF="#" onClick="doDrow(window.dialogArguments.getCalendar('+next_month+','+next_month_year+'));">&gt;</A></TD>';
	
				result += '<TD CLASS="cpYearNavigation" align="center" WIDTH="10%"><A CLASS="cpYearNavigation" HREF="#" onClick="doDrow(window.dialogArguments.getCalendar('+month+','+(year-1)+'));">&lt;</A></TD>';
				if (this.isShowYearNavigationInput) {
					result += '<TD CLASS="cpYearNavigation" align="center" WIDTH="30%"><INPUT NAME="cpYear" CLASS="cpYearNavigation" SIZE="4" MAXLENGTH="4" VALUE="'+year+'" onBlur="doDrow(window.dialogArguments.getCalendar('+month+',this.value-0));"></TD>';
				}else {
					result += '<TD CLASS="cpYearNavigation" align="center" WIDTH="0%"><SPAN CLASS="cpYearNavigation">'+year+'</SPAN></TD>';
				}
				result += '<TD CLASS="cpYearNavigation" align="center" WIDTH="10%"><A CLASS="cpYearNavigation" HREF="#" onClick="doDrow(window.dialogArguments.getCalendar('+month+','+(year+1)+'));">&gt;</A></TD>';
			}else {
				result += '<TD CLASS="cpMonthNavigation" align="center" WIDTH="20%"><A CLASS="cpMonthNavigation" HREF="#" onClick="doDrow(window.dialogArguments.getCalendar('+last_month+','+last_month_year+'));">&lt;&lt;</A></TD>\n';
				result += '<TD CLASS="cpMonthNavigation" align="center" WIDTH="60%"><SPAN CLASS="cpMonthNavigation">'+this.monthNames[month-1]+' '+year+'</SPAN></TD>\n';
				result += '<TD CLASS="cpMonthNavigation" align="center" WIDTH="20%"><A CLASS="cpMonthNavigation" HREF="#" onClick="doDrow(window.dialogArguments.getCalendar('+next_month+','+next_month_year+'));">&gt;&gt;</A></TD>\n';
				}
			}
			result += '</tr></TD></TABLE></TR></TABLE>\n';
			result += '<TABLE WIDTH="100%" border="0" cellspacing="1" cellpadding="1" ALIGN=CENTER>\n';
			result += '<TR>\n';
		for (var j=0; j<7; j++) {
			result += '<TD CLASS="all" WIDTH="14%" nowrap bgcolor="#CCCCCC" background="'+systemDefine.webRoot+'/resource/extra/images/table_header.gif" height="25"><SPAN CLASS="cpDayColumnHeader">'+this.dayHeaders[(this.weekStartDay+j)%7]+'</TD>\n';
		}
		result += '</TR>\n';
		for (var row=1; row<=6; row++) {
			result += '<TR>\n';
			for (var col=1; col<=7; col++) {
				var disabled=false;
				if (this.disabledDatesExpression!="") {
					var ds=""+display_year+LZ(display_month)+LZ(display_date);
					eval("disabled=("+this.disabledDatesExpression+")");
					}
				var dateClass = "";
				if ((display_month == this.currentDate.getMonth()+1) && (display_date==this.currentDate.getDate()) && (display_year==this.currentDate.getFullYear())) {
					dateClass = "cpCurrentDate";
				}
				else if (display_month == month) {
					dateClass = "cpCurrentMonthDate";
				}else {
					dateClass = "cpOtherMonthDate";
				}
				if (disabled || this.disabledWeekDays[col-1]) {
					
						result += '	<TD CLASS="all" nowrap><span CLASS="'+dateClass+'Disabled">'+display_date+'</span></TD>\n';
				}else {
					var selected_date = display_date;
					var selected_month = display_month;
					var selected_year = display_year;
					if (this.displayType=="week-end") {
						var d = new Date(selected_year,selected_month-1,selected_date,0,0,0,0);
						d.setDate(d.getDate() + (7-col));
						selected_year = d.getYear();
						if (selected_year < 1000) { selected_year += 1900; }
							selected_month = d.getMonth()+1;
							selected_date = d.getDate();
						}
					
						result += '	<TD CLASS="'+dateClass+'" nowrap onClick="window.dialogArguments.getReturnValue('+selected_year+','+selected_month+','+selected_date+','+col+');window.close();" style="cursor:pointer"><A CLASS="'+dateClass+'" HREF="#"  CLASS="'+dateClass+'">'+display_date+'</A></TD>\n';
				}
				display_date++;
				if (display_date > daysinmonth[display_month]) {
					display_date=1;
					display_month++;
					}
				if (display_month > 12) {
					display_month=1;
					display_year++;
					}
				}
			result += '</TR>';
			}
		var current_weekday = now.getDay() - this.weekStartDay;
		if (current_weekday < 0) {
			current_weekday += 7;
			}
		result += '<TR>\n';
		result += '	<TD COLSPAN=7 ALIGN=CENTER CLASS="cpTodayText">\n';
		
		if (this.disabledDatesExpression!="") {
			var ds=""+now.getFullYear()+LZ(now.getMonth()+1)+LZ(now.getDate());
			eval("disabled=("+this.disabledDatesExpression+")");
		}
		if (disabled || this.disabledWeekDays[current_weekday+1]) {
			result += '		<SPAN CLASS="cpTodayTextDisabled">'+this.todayText+'</SPAN>\n';
		}else {
			result += '		<A CLASS="cpTodayText" HREF="#" onClick="window.dialogArguments.getReturnValue('+now.getFullYear()+','+(now.getMonth()+1)+','+now.getDate()+','+(now.getDay()+1)+');window.close();">'+this.todayText+'</A>\n';
		}
		result += '		<BR>\n';
		result += '	</TD></TR></TABLE></CENTER></TD></TR></TABLE>\n';
	}
	

		// Code common for MONTH, QUARTER, YEAR
	// ------------------------------------
	if (this.displayType=="month" || this.displayType=="quarter" || this.displayType=="year") {
		if (arguments.length > 0) { 
			var year = arguments[0]; 
		}else { 
			if (this.displayType=="year") {
				var year = now.getFullYear()-this.yearSelectStartOffset;
			}else {
				var year = now.getFullYear(); }
			}
		if (this.displayType!="year" && this.isShowYearNavigation) {
			result += "<TR>\n\<TD align=center>";
			result += "<TABLE WIDTH=100% BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>";
			result += '<TR>\n';
			result += '	<TD ALIGN="center" WIDTH="40%"><A  HREF="#" onClick="doDrow(window.dialogArguments.getCalendar('+(year-1)+'));">&lt;&lt;</A></TD>\n';
			result += '	<TD ALIGN="center" WIDTH="20%">'+year+'</TD>\n';
			result += '	<TD ALIGN="center" WIDTH="40%"><A HREF="#" onClick="doDrow(window.dialogArguments.getCalendar('+(year+1)+'));window.close();">&gt;&gt;</A></TD>\n';
			result += '</TR></TABLE>\n';
			}
		}
			// Code for MONTH display 
	// ----------------------
	if (this.displayType=="month") {
		// If POPUP, write entire HTML document
		result += '<TABLE WIDTH=120 BORDER=0 CELLSPACING=1 CELLPADDING=0 ALIGN=CENTER>\n';
		for (var i=0; i<4; i++) {
			result += '<TR>';
			for (var j=0; j<3; j++) {
				var monthindex = ((i*3)+j);
				result += '<TD WIDTH=33% ALIGN=CENTER><A HREF="#" onClick="window.dialogArguments.getReturnValue('+year+','+(monthindex+1)+');window.close();" CLASS="'+date_class+'">'+this.monthAbbreviations[monthindex]+'</A></TD>';
			}
			result += '</TR>';
		}
		result += '</TABLE></CENTER></TD></TR></TABLE>\n';
	}

	if (this.displayType=="quarter") {
		result += '<BR><TABLE WIDTH=120 BORDER=1 CELLSPACING=0 CELLPADDING=0 ALIGN=CENTER>\n';
		for (var i=0; i<2; i++) {
			result += '<TR>';
			for (var j=0; j<2; j++) {
				var quarter = ((i*2)+j+1);
				result += '<TD WIDTH=50% ALIGN=CENTER><BR><A HREF="#" onClick="window.dialogArguments.getReturnValue('+year+',null,null,null,'+quarter+');window.close();" CLASS="'+date_class+'">Q'+quarter+'</A><BR><BR></TD>';
				}
			result += '</TR>';
			}
		result += '</TABLE></CENTER></TD></TR></TABLE>\n';
		}

		if (this.displayType=="year") {
			var yearColumnSize = 4;
			result += "<TABLE WIDTH=100% BORDER=0 BORDERWIDTH=0 CELLSPACING=0 CELLPADDING=0>";
			result += '<TR>\n';
			result += '	<TD WIDTH="50%" align="center"><A  HREF="#" onClick="doDrow(window.dialogArguments.getCalendar('+(year-(yearColumnSize*2))+'));">&lt;&lt;</A></TD>\n';
			result += '	<TD  align="center" WIDTH="50%"><A HREF="#" onClick="doDrow(window.dialogArguments.getCalendar('+(year+(yearColumnSize*2))+'));">&gt;&gt;</A></TD>\n';
			result += '</TR></TABLE>\n';
			result += '<TABLE WIDTH=120 BORDER=0 CELLSPACING=1 CELLPADDING=0 ALIGN=CENTER>\n';
			for (var i=0; i<yearColumnSize; i++) {
				for (var j=0; j<2; j++) {
					var currentyear = year+(j*yearColumnSize)+i;
					result += '<TD WIDTH=50% ALIGN=CENTER><A HREF="#" onClick="window.dialogArguments.getReturnValue('+currentyear+');window.close();" CLASS="'+date_class+'">'+currentyear+'</A></TD>';
				}
				result += '</TR>';
			}
			result += '</TABLE></CENTER></TD></TR></TABLE>\n';
		}
	return result;
}

