var weekend = [6,7];

var gNow = new Date();
var ggPosX = -1;
var ggPosY = -1;

Calendar.Months = ["januari", "februari", "mars", "april", "maj", "juni",
"juli", "augusti", "september", "oktober", "november", "december"];

// Non-Leap year Month days..
Calendar.DOMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
// Leap year Month days..
Calendar.lDOMonth = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];


/**
 * Calendar input constructor function
 * Defaults can be changed.
 */
function CalendarInput() {
	this.calVarName = null;
	this.month = new String(gNow.getMonth());
	this.year = new String(gNow.getFullYear().toString());
	this.format = "YYYY-MM-DD";
	this.headerText = "Kalender";
	this.adminState = false;
	
	this.eventsByCustomerDates = [];
	
}

/**
 * Calendar constructor function
 */
function Calendar(ci) {
	this.adminState=ci.adminState;
	if (ci.adminState) {
		ci.month = '0';
		ci.year = '2008';
		ci.eventsByCustomerDates = [3, 8, 17, 30];
	}

	if (ci.month == null && ci.year == null) {
		return;
	}

	// Properties
	this.ci = ci;
	this.year = ci.year;
	this.format = ci.format;
	this.headerText = ci.headerText;
	this.month = null;
	this.yearly = null;

	this.winContent = "";
	
	// Methods
	this.getMonthName = getMonthName;
	this.getDaysOfMonth = getDaysOfMonth;
	this.calcMonthYear = calcMonthYear;
	this.getMonthlyCalendarCode = getMonthlyCalendarCode;
	this.show = show;
	this.formatData = formatData;
	this.calHeader = calHeader;
	this.calData = calData;
	this.formatDay = formatDay;
	this.isSelectedDate = isSelectedDate;
	
	// Properties init
	if (ci.month == null) {
		this.yearly = true;
	} else {
		this.month = new Number(ci.month);
		this.yearly = false;
	}
		
	// Inner function for Calendar
	function getMonthName(monthNo) {
		return Calendar.Months[monthNo];
	}

	// Inner function for Calendar
	function getDaysOfMonth(monthNo, p_year) {
		/*
		Check for leap year ..
		1.Years evenly divisible by four are normally leap years, except for...
		2.Years also evenly divisible by 100 are not leap years, except for...
		3.Years also evenly divisible by 400 are leap years.
		*/
		if ((p_year % 4) == 0) {
			if ((p_year % 100) == 0 && (p_year % 400) != 0) {
				return Calendar.DOMonth[monthNo];
			}
			return Calendar.lDOMonth[monthNo];
		} else
			return Calendar.DOMonth[monthNo];
	}

	/**
	 * Inner function for Calendar.
	 * Will return an 1-D array with 1st element being the calculated month
	 * and second being the calculated year.
	 * The month increment/decrement is applied as specified by 'incr' parameter.
	 * 'incr' will normally have 1/-1 to navigate thru the months.
	 */
	function calcMonthYear(p_Month, p_Year, incr) {
		var ret_arr = new Array();
	
		if (incr == -1) {
			// Backward
			if (p_Month == 0) {
				ret_arr[0] = 11;
				ret_arr[1] = parseInt(p_Year) - 1;
			}
			else {
				ret_arr[0] = parseInt(p_Month) - 1;
				ret_arr[1] = parseInt(p_Year);
			}
		} else if (incr == 1) {
			// Forward
			if (p_Month == 11) {
				ret_arr[0] = 0;
				ret_arr[1] = parseInt(p_Year) + 1;
			}
			else {
				ret_arr[0] = parseInt(p_Month) + 1;
				ret_arr[1] = parseInt(p_Year);
			}
		}
	
		return ret_arr;
	}

	// Inner function for Calendar
	function getMonthlyCalendarCode() {
		var vCode = "";
		var vHeader_Code = "";
		var vData_Code = "";
	
		// Begin Table Drawing code here..
		vCode += ("<table class=\"webgain-calendar-table\">");
	
		vHeader_Code = this.calHeader();
		vData_Code = this.calData();
		vCode += (vHeader_Code + vData_Code);
	
		vCode += "</table>";
	
		return vCode;
	}
	
	function show() {
		var vCode = "";

		// Show navigation buttons
		var prevMMYYYY = this.calcMonthYear(this.month, this.year, -1);
		var prevMM = prevMMYYYY[0];
		var prevYYYY = prevMMYYYY[1];
	
		var nextMMYYYY = this.calcMonthYear(this.month, this.year, 1);
		var nextMM = nextMMYYYY[0];
		var nextYYYY = nextMMYYYY[1];

		// Get year values
		var prevYear = parseInt(this.year) - 1;
		var nextYear = parseInt(this.year) + 1;
	
		// build content into var winContent
		this.winContent = "";
		this.winContent += ("<div><div class=\"webgain-calendar-header\">");
		this.winContent += this.ci.headerText;
		this.winContent += ("</div>");
		this.winContent += ("<div class=\"webgain-calendar-body\">");
	
		this.winContent += ("<a href=\"javascript:void(0);\" " +
			"onmouseover=\"window.status='G&aring; tillbaka ett &aring;r'; return true;\" " +
			"onmouseout=\"window.status=''; return true;\" " +
			"onclick=\"turnPage(" +	this.ci.calVarName + ", '" + this.month + "', '" + prevYear 
			+ "', '" + this.format + "'" +	"); return false;" +
			"\">&laquo;&laquo;<\/a>&nbsp;&nbsp;");

		this.winContent += ("<a href=\"javascript:void(0);\" " +
			"onmouseover=\"window.status='G&aring; tillbaka en m&aring;nad'; return true;\" " +
			"onmouseout=\"window.status=''; return true;\" " +
			"onclick=\"turnPage(" +	this.ci.calVarName + ", '" + prevMM + "', '" + prevYYYY 
			+ "', '" + this.format + "'" +	"); return false;" +
			"\">&laquo;<\/a>&nbsp;");

		this.winContent += (this.getMonthName(this.month) + " " + this.year);
	
		this.winContent += ("&nbsp;<a href=\"javascript:void(0);\" " +
			"onmouseover=\"window.status='G&aring; fram en m&aring;nad'; return true;\" " +
			"onmouseout=\"window.status=''; return true;\" " +
			"onclick=\"turnPage(" + this.ci.calVarName + ", '" + nextMM + "', '" + nextYYYY 
			+ "', '" + this.format + "'" +	"); return false;" +
			"\">&raquo;<\/a>&nbsp;&nbsp;");

		this.winContent += ("<a href=\"javascript:void(0);\" " +
			"onmouseover=\"window.status='G&aring; fram ett &aring;r'; return true;\" " +
			"onmouseout=\"window.status=''; return true;\" " +
			"onclick=\"turnPage(" +	this.ci.calVarName + ", '" + this.month + "', '" + nextYear 
			+ "', '" + this.format + "'" +	"); return false;" +
			"\">&raquo;&raquo;<\/a><div style=\"padding-top: 5px;\">");
		
		// Get the complete calendar code for the month, and add it to the
		//	content var
		vCode = this.getMonthlyCalendarCode();
		this.winContent += vCode + "</div></div>";
	}


	// Inner function for Calendar
	function formatData(p_day) {
		var vData;
		var vMonth = 1 + parseInt(this.month);
		vMonth = (vMonth.toString().length < 2) ? "0" + vMonth : vMonth;
		var vMon = this.getMonthName(this.month).substr(0,3).toUpperCase();
		var vFMon = this.getMonthName(this.month).toUpperCase();
		var vY4 = new String(this.year);
		var vY2 = new String(this.year.substr(2,2));
		var vDD = (p_day.toString().length < 2) ? "0" + p_day : p_day;
	
		switch (this.format) {
			case "MM\/DD\/YYYY" :
				vData = vMonth + "\/" + vDD + "\/" + vY4;
				break;
			case "MM\/DD\/YY" :
				vData = vMonth + "\/" + vDD + "\/" + vY2;
				break;
			case "MM-DD-YYYY" :
				vData = vMonth + "-" + vDD + "-" + vY4;
				break;
			case "YYYY-MM-DD" :
				vData = vY4 + "-" + vMonth + "-" + vDD;
				break;
			case "MM-DD-YY" :
				vData = vMonth + "-" + vDD + "-" + vY2;
				break;
			case "DD\/MON\/YYYY" :
				vData = vDD + "\/" + vMon + "\/" + vY4;
				break;
			case "DD\/MON\/YY" :
				vData = vDD + "\/" + vMon + "\/" + vY2;
				break;
			case "DD-MON-YYYY" :
				vData = vDD + "-" + vMon + "-" + vY4;
				break;
			case "DD-MON-YY" :
				vData = vDD + "-" + vMon + "-" + vY2;
				break;
			case "DD\/MONTH\/YYYY" :
				vData = vDD + "\/" + vFMon + "\/" + vY4;
				break;
			case "DD\/MONTH\/YY" :
				vData = vDD + "\/" + vFMon + "\/" + vY2;
				break;
			case "DD-MONTH-YYYY" :
				vData = vDD + "-" + vFMon + "-" + vY4;
				break;
			case "DD-MONTH-YY" :
				vData = vDD + "-" + vFMon + "-" + vY2;
				break;
			case "DD\/MM\/YYYY" :
				vData = vDD + "\/" + vMonth + "\/" + vY4;
				break;
			case "DD\/MM\/YY" :
				vData = vDD + "\/" + vMonth + "\/" + vY2;
				break;
			case "DD-MM-YYYY" :
				vData = vDD + "-" + vMonth + "-" + vY4;
				break;
			case "DD-MM-YY" :
				vData = vDD + "-" + vMonth + "-" + vY2;
				break;
			default :
				vData = vMonth + "\/" + vDD + "\/" + vY4;
		}
	
		return vData;
	}

	// Inner function for Calendar
	function calHeader() {
		var vCode = "";
		vCode = vCode + "<tr>";
		vCode = vCode + "<td style=\"\">v</td>";
		vCode = vCode + "<td style=\"width:12%;\">m&aring;n</td>";
		vCode = vCode + "<td style=\"width:12%;\">tis</td>";
		vCode = vCode + "<td style=\"width:12%;\">ons</td>";
		vCode = vCode + "<td style=\"width:12%;\">tor</td>";
		vCode = vCode + "<td style=\"width:12%;\">fre</td>";
		vCode = vCode + "<td style=\"width:12%;\">l&ouml;r</td>";
		vCode = vCode + "<td style=\"width:12%;\">s&ouml;n</td>";
		vCode = vCode + "</tr>";
		return vCode;
	}

	// Inner function for Calendar
	function calData() {
		var vDate = new Date();
		vDate.setDate(1);
		vDate.setMonth(this.month);
		vDate.setFullYear(this.year);
	
		var vFirstDay=vDate.getDay();
		if (vFirstDay == 0) {
			vFirstDay = 7;
		}
		var vDay=1;
		var vLastDay=this.getDaysOfMonth(this.month, this.year);
	        var vLastDayPreviousMonth;
	        if (this.month > 0) {
	            vLastDayPreviousMonth=this.getDaysOfMonth(this.month-1, this.year);
	        } else {
	            vLastDayPreviousMonth=this.getDaysOfMonth(11, this.year-1)
			}
	
		var vOnLastDay=0;
		var vCode = "";
	
		// Get day for the 1st of the requested month/year.
		// Place as many blank cells before the 1st day of the month as necessary.
		vCode = vCode + "<tr>";
	
		// Write weeknumber
		vCode = vCode + "<td>" + 	getWeekNumber(parseInt(this.year), this.month, vDay) + "</td>";
	
		// Write beginning of the 1st week
		for (i=1; i<vFirstDay; i++) {
	                var szDay = (vLastDayPreviousMonth-vFirstDay+i+1).toString();
			vCode = vCode + "<td class=\"webgain-calendar-different-month-date\">"  + szDay + "</td>";
		}
	
		// Write rest of the 1st week
		for (j=vFirstDay; j<8; j++) {
			vCode = vCode + "<td>" + this.formatDay(parseInt(this.year), this.month, vDay, j) + "</td>";
			vDay=vDay + 1;
		}
		vCode = vCode + "</tr>";
	
		// Write the rest of the weeks
		for (k=2; k<7; k++) {
			vCode = vCode + "<tr>";
	
			// Write weeknumber
			vCode = vCode + "<td>" + getWeekNumber(parseInt(this.year), this.month, vDay) + "</td>";
	
			for (j=1; j<8; j++) {
				vCode = vCode + "<td>" + this.formatDay(parseInt(this.year), this.month, vDay, j) +	"</td>";
				vDay=vDay + 1;
	
				if (vDay > vLastDay) {
					vOnLastDay = 1;
					break;
				}
			}

			if (j == 8)
				vCode = vCode + "</tr>";
			if (vOnLastDay == 1)
				break;
		}
	
		// Fill up the rest of last week with proper blanks, so that we get proper square blocks
		for (m=1; m<(8-j); m++) {
			vCode = vCode + "<td class=\"webgain-calendar-different-month-date\">" + m + "</td>";
		}
	
		vCode = vCode + "</tr>";
		return vCode;
	}


	// Inner function for Calendar
	function formatDay(year, month, vday, index) {
		var vNowDay = gNow.getDate();
		var vNowMonth = gNow.getMonth();
		var vNowYear = gNow.getFullYear();
		var dayFormat = vday;
		var clickable = false;
	
		if (isEventsByCustomerDates(vday)) {
			// Date is events by customer. Make number black and bold.
		    dayFormat = "<span class=\"webgain-calendar-events-date\">" + dayFormat + "</span>";
		    clickable = true;
		} 
	
	    if (index == -1) {
		    dayFormat = "<span class=\"webgain-calendar-different-month-date\">" + dayFormat + "</span>";
		} 
	
		if (this.isSelectedDate(year, month, vday)) {
		    dayFormat = "<span class=\"webgain-calendar-selected-date\">" + dayFormat + "</span>";
		}
	
		// If this is a highlighed date it should be clickable
		if (clickable) {
			return "<a href=\"javascript:void(0);\" " +
					"onclick=\"onClick(" + this.ci.calVarName + ", " + this.year + ", " + this.month + ", " + vday + "); return false;\">" +
						dayFormat +
					"</a>";
		} else {
			dayFormat = "<span class=\"webgain-calendar-date\">" + dayFormat + "</span>";
		}
		
		return dayFormat;
	}

	// Inner function for Calendar
	function isSelectedDate(year, month, vday) {
		if (this.ci.selectedDate != null) {
			var vSelectedDay = this.ci.selectedDate.getDate();
			var vSelectedMonth = this.ci.selectedDate.getMonth();
			var vSelectedYear = this.ci.selectedDate.getFullYear();
			if (vday == vSelectedDay && month == vSelectedMonth && year == vSelectedYear) {
				return true;
			} 
		}
		return false;
	}
	
	// Inner function for Calendar
	function isEventsByCustomerDates(vday) {
		for (i = 0; i < this.ci.eventsByCustomerDates.length; i++) {
			if (vday == this.ci.eventsByCustomerDates[i]) {
				return true;
			}
		}
	}
	
}




/*
 * Writes the monthly calendar directly to the document
 */
function writeCalendar(calendar) {
	calendar.show();
	var mycal = document.getElementById('mycalendar');
	mycal.innerHTML = calendar.winContent;

}
	
function onClick(calendar, year, month, day) {
	if (!calendar.adminState) {
	    changeElemValById('webgainSelectedYear', year);
	    changeElemValById('webgainSelectedMonth', month);
	    changeElemValById('webgainSelectedDay', day);
	    submitForm('webgaincalendarform');
	}
}

function div(a,b) {
	return((a-a%b)/b)
}

function turnPage(calendar, p_month, p_year, p_format) {
	if (!calendar.adminState) {
		changeElemValById("webgainCalendarYear", p_year);
		changeElemValById("webgainCalendarMonth", p_month);
		submitForm('webgaincalendarform');
	}
}


function modifiedJulianDay(year, month, day) {
	var k = div((month+9),12);
	var t = 7*(year+k);
	var e = div(t, 4);
	var f = 367*year - e + div((275*month),9) + day;
	var d = f - 730530;
	var MJD = d + 51543.0;
	return MJD;
}


function getWeekNumber(year, month, day) {
	var year = parseInt(year);
	var month = parseInt(month);
	var day = parseInt(day);
	var MJD_Now = modifiedJulianDay(year,(month+1),day);
	var W = Math.floor ( (MJD_Now / 7) - 2144.64 );
	var WY = Math.floor( (W * 28/1461) - 0.0079);
	var WN = W - Math.floor( (WY * 1461/28) + 0.41);
	return WN;
}
