function calendar(){
	var self = this;

	/** @private */
	var allowPreviousDay = true;
	var allowPreviousMonth = true;
	var allowPreviousYear = true;
	var allowNextDay = true;
	var allowNextMonth = true;
	var allowNextYear = true;
	var excludedDays = new Array(1,1,1,1,1,1,1);
	var dayNameLength = 1;
	var now = new Date();
	var nowDay = now.getDate();
	var nowMonth = now.getMonth();
	var nowYear = now.getFullYear();
	var curMonth = "";
	var curYear = "";
	var selDay = "";
	var selMonth = "";
	var selYear = "";
	var calDiv = "";
	var arrDayNamesList = new Array("Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday");
	var arrMonthNamesList = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
	
	this.setCalendarDIV = function(el){
		calDiv = el;
	};
	
	this.setDayNameLength = function(l){
		dayNameLength = l;
	};
	
	this.getDay = function() {
		return nowDay;	
	}
	
	this.getMonth = function() {
    	return nowMonth;
	}	
	
	this.getYear = function(){
		return nowYear;	
	}
	
	this.getSelectedYear = function(){
		return selYear;
	};
	
	this.getSelectedDay = function(){
		return selDay;
	};
	
	this.getSelectedMonth = function(){
		return selMonth;
	};
	
	this.setExcludedDays = function(days){
		excludedDays = days.split(",");	
	};
	
	this.setAllowPreviousDays = function(bln){
		allowPreviousDay = bln;	
	}
	
	this.setAllowPreviousMonths = function(bln){
		allowPreviousMonth = bln;	
	}
	
	this.setAllowPreviousYears = function(bln){
		allowPreviousYear = bln;	
	}
	
	this.setAllAllowPrevious = function(bln){
		this.setAllowPreviousDays(bln);	
		this.setAllowPreviousMonths(bln);
		this.setAllowPreviousYears(bln);
	}
	
	this.setAllowNextDays = function(bln){
		allowNextDay = bln;	
	}
	
	this.setAllowNextMonths = function(bln){
		allowNextMonth = bln;	
	}
	
	this.setAllowNextYears = function(bln){
		allowNextYear = bln;	
	}
	
	this.setAllAllowNext = function(bln){
		this.setAllowNextDays(bln);	
		this.setAllowNextMonths(bln);
		this.setAllowNextYears(bln);
	};
	
	this.setDisplayMonthToday = function(){
		curYear = nowYear;
		curMonth = nowMonth;
		curDay = nowDay;
	};
	
	this.setDisplayMonth = function(yr,mn){
		curYear = yr;
		curMonth = mn;
	};
	
	this.setSelectedDate = function(yr,mn,dy){
		selYear = yr;
		selMonth = mn;
		selDay = dy;	
	};
	
	this.setPreviousMonth = function() {
	    if(!allowPreviousMonth){
	    	if(curMonth==nowMonth && curYear==nowYear){
	    		return;
	    	};
	    };
	    if (curMonth == 0) {
	    	if(!allowPreviousYear){
	    		if(curYear==nowYear){
	    			return;	
	    		};
	    	};
	    	curYear--;
	        curMonth = 11;
	    }else {
	     	curMonth--;
	    }
	    this.displayCalendar();
	};
	
	this.setNextMonth = function() {
		if(!allowNextMonth){
			if(curMonth==nowMonth && curYear==nowYear){
				return;
			};
		};
	    if(myMonth == 11){
	    	if(!allowNextYear){
	    		if(curYear==nowYear){
	    			return;
	    		};
	    	};
			curYear++;
			curMonth=0;
		}else{
			curMonth++;
		}
	    this.displayCalendar();
	};
	
	this.setCurrentDay = function(day){
		var tbl = document.getElementById("calControl");
		var blnDone = false;
		for(var i=1;i<tbl.rows.length;i++){
			for(var j=0;j<tbl.rows[i].cells.length;j++){
				if(tbl.rows[i].cells[j].innerText==day){
					tbl.rows[i].cells[j].className = "calOn";
					selDay = day;
					selMonth = curMonth;
					selYear = curYear;
				}else{
					tbl.rows[i].cells[j].className = "";
				};
			};
		};
	};
	
	this.displayCalendar = function() {
		var calendarFace = "<div id='calendarContainer'><div id='calendarHeader'><input type='button' id='previousMonth' name='previousMonth' class='calButton' value=' < ' onClick='moveMonth(0);'> <span id='calendarMonthYear'>" + arrMonthNamesList[curMonth] + " " + curYear + "</span> <input type='button' name='nextMonth' class='calButton' value=' > ' onClick='moveMonth(1)'></div><table id='calControl' class='calControl'><tr class='calDayNames'>";
		for(var i=0;i<arrDayNamesList.length;i++){
			calendarFace += "<td>" + arrDayNamesList[i].substr(0,dayNameLength) + "</td>";
		};
		calendarFace += "</tr><tr class='calDays'>";
	    myMonth			= parseInt(curMonth);
	    myYear			= parseInt(curYear);
	    if(selDay == ""){
	    	selDay = nowDay;
	    	selMonth = nowMonth;
	    	selYear = nowYear;	
	    };
	    var i			= 0;
	    var blnToday	= false;
	    var days        = this.getDaysInMonth(myMonth+1,myYear);
	    var firstOfMonth= new Date (myYear, myMonth, 1);
	    var startingPos = firstOfMonth.getDay();
	    days += startingPos;
		if(myMonth==selMonth && myYear==selYear){
			blnToday = true;
	    };
	    for (i = 0; i < startingPos; i++) {
	        calendarFace += "<td>&nbsp;</td>";
	    };
	    var blnHREF = false;
	    for (i = startingPos; i < days; i++){
	    	blnHREF = false;
	    	if(i%7==0){
	    		calendarFace += "</tr><tr class='calDays'>";
	    	};
	    	var dayValue = i-startingPos+1;
	    	var dayDisplay = dayValue;
	    	if(dayDisplay<10){
	    		dayDisplay = "0"+eval(dayDisplay);
	    	};
	    	calendarFace += "<td>";	        
	        if(excludedDays[i%7]==1){
	        	if(dayValue>=nowDay || allowPreviousDay || curMonth>nowMonth || curYear>nowYear){
	        		blnHREF = true;
	        	};
	        };
	        if(blnHREF){
	        	calendarFace += "<a href='javascript:returnDate("+ curYear + "," + curMonth + "," + dayValue + ",false);'>";
	        };
	        calendarFace += dayDisplay;
	        if(blnHREF){
	        	calendarFace += "</a>";
	        };
	        calendarFace += "</td>";
	    };
	    if(i%7!=0){
	    	var mod = 7-(i%7);
	    	for (i = 0; i < mod; i++) {
	        	calendarFace += "<td>&nbsp;</td>";
	    	};
	    };	    
	    calendarFace += "</tr></table></div>"
	    calDiv.innerHTML = calendarFace;
	    if(blnToday){
	    	this.setCurrentDay(selDay);
	    };
	};
	
	this.getDaysInMonth = function(myMonth,myYear)  {
	    var days;
	    if (myMonth==1 || myMonth==3 || myMonth==5 || myMonth==7 || myMonth==8 ||
	        myMonth==10 || myMonth==12)  days=31;
	    else if (myMonth==4 || myMonth==6 || myMonth==9 || myMonth==11) days=30;
	    else if (myMonth==2)  {
	        if (this.isLeapYear(myYear)) {
	            days=29;
	        }
	        else {
	            days=28;
	        }
	    }
	    return (days);
	};
	
	
	// CHECK TO SEE IF YEAR IS A LEAP YEAR
	this.isLeapYear = function(myYear) {
	    if (((myYear % 4)==0) && ((myYear % 100)!=0) || ((myYear % 400)==0)) {
	        return (true);
	    }
	    else {
	        return (false);
	    }
	};
	
	//FORMAT DATE FOR RETURN
	this.strGetFormattedDate = function(dtDate,strFormat){
		try{
			dtDate = new Date(Date.parse(dtDate));
		}catch(e){
			return dtDate;
		}
		var strCurrentPart = "";
		var blnParsingDate = false;
		var arrDateParts = new Array();
		var arrDateTypes = new Array();
		var intDatePartCounter = -1;
		var chr = "";
		var dtReturn = "";
		var intLiteral = -1;
		for(var i=0;i< strFormat.length;i++){
			chr = strFormat.substr(i,1);
			switch(chr){
				case "D":
				case "M":
				case "Y":
				case "H":
				case "N":
				case "S":
					if(intLiteral<0){
						if(chr==strCurrentPart){
							arrDateParts[intDatePartCounter] += "" + chr;
						}else{
							arrDateParts[++intDatePartCounter] = chr;
						}
						arrDateTypes[intDatePartCounter] = 1;
						blnParsingDate = true;
					}else{
						arrDateParts[intDatePartCounter] += "" + chr;
					}
					break;
				case "'":
					if(blnParsingDate){
						intDatePartCounter++;
						arrDateTypes[intDatePartCounter] = 0;
					};
					intLiteral *= -1;
					blnParsingDate = false;
					break;
				default:
					if(blnParsingDate){
						arrDateParts[++intDatePartCounter] = "" + chr;
						blnParsingDate = false;
					}else{
						arrDateParts[intDatePartCounter] += "" + chr;
					};
					arrDateTypes[intDatePartCounter] = 0;
			};
			strCurrentPart = chr;
		};
	
		var intSize = 0;
		var strAMPM = "";
	
		for(var i=0;i<arrDateParts.length;i++){
			intSize = arrDateParts[i].length;
			if(arrDateTypes[i]==0){
				dtReturn += arrDateParts[i];
			}else{
				switch(arrDateParts[i].substring(0,1)){
					case "D":
						switch(intSize){
							case 1:
								dtReturn += dtDate.getDate();
								break;
							case 3:
								dtReturn += arrDayNamesList[dtDate.getDay()].substring(0,3);
								break;
							case 4:
								dtReturn += arrDayNamesList[dtDate.getDay()];
								break;
							default:
								dtReturn += this.strPadDate(dtDate.getDate());
								break;
						};
						break;
					case "M":
						switch(intSize){
							case 1:
								dtReturn += dtDate.getMonth+1;
								break;
							case 3:
								dtReturn += f.month[dtDate.getMonth()].text.substring(0,3);
								break;
							case 4:
								dtReturn += f.month[dtDate.getMonth()].text;
								break;
							default:
								dtReturn += this.strPadDate(dtDate.getMonth()+1);
								break;
							};
						break;
					case "Y":
						switch(intSize){
							case 2:
								dtReturn += dtDate.getFullYear().toString().substring(2);
								break;
							default:
								dtReturn += dtDate.getFullYear();
								break;
						};
						break;
					case "H":
						switch(intSize){
							case 1:
								dtReturn += dtDate.getHours();
								break;
							case 2:
								dtReturn += this.strPadDate(dtDate.getHours());
								break;
							default:
								var dtHours = dtDate.getHours();
								if(dtHours>12){
									dtHours -= 12;
									strAMPM = "PM"
								}else{
									strAMPM = "AM"
								};
								switch(intSize){
									case 3:
										dtReturn += dtHours;
										break;
									default:
										dtReturn += this.strPadDate(dtHours);
										break;
								};
							break;
						};
						break;
					case "N":
						switch(intSize){
							case 1:
								dtReturn += dtDate.getMinutes();
								break;
							default:
								dtReturn += this.strPadDate(dtDate.getMinutes());
								break;
						};
						break;
					case "S":
						switch(intSize){
							case 1:
								dtReturn += dtDate.getSeconds();
								break;
							default:
								dtReturn += this.strPadDate(dtDate.getSeconds());
								break;
						};
						break;
					default:
						dtReturn += arrDateParts[i];
						break;
				};
			};
		};
		dtReturn += strAMPM;
		return dtReturn;
	};
	
	this.strPadDate = function(strDatePart){
		try{
			strDatePart = strDatePart.toString();
			while(strDatePart.length<2){
				strDatePart = "0" + "" + strDatePart;
			}
			return strDatePart;
		}catch(e){
			return strDatePart;
		};
	};

};