function PopUpCal() {
	//CONFIG
	var nextArrow = '/siteimages/btn_arrow_next.gif';
	var prevArrow = '/siteimages/btn_arrow_prev.gif';

	// CONSTANTS
	var daysOfWeek = new Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
	var monthsInYear = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
	var fullMonthsInYear = new Array('January','February','March','April','May','June','July','August','September','October','November','December');
	var daysInMonth = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
	var today = new Date();
	today = buildDate(today.getDate(), today.getMonth(), today.getFullYear());
	var oThis = this;
	var callback;
	
	// Basic Output Elements
	var calendarDiv;
	var monthNavCells = new Array();
	var navBackCell;
	var navForwardCell;
	var dispMonthCells = new Array();
	var dayCells1 = new Array();
	var dayCells2 = new Array();
	
	// Variables
	var initialized = false;
	var outputInput;
	var drawMonth = today.getMonth();
	var drawYear = today.getFullYear();
	var fromDate;
	var toDate;
	var noClose=false;

	function initCal() {
		calendarDiv = document.createElement('div');
		calendarDiv.className = 'PopupCalendar';
		
		//calendarDiv.appendChild(initMonthNav());
		calendarDiv.appendChild(initMonthCells());
		calendarDiv.appendChild(initCalCells());
		
		document.body.appendChild(calendarDiv);
		
		XBrowserAddHandler(calendarDiv, 'click', skipClose);
		XBrowserAddHandler(document.body, 'click', testClose);
		
		initialized = true;
	}
	
	function initMonthNav() {
		var monthNavTable = new TableHandler('MonthNav');
		
		for(var i=0; i < monthsInYear.length; i++) {
			var monthNavCell = monthNavTable.addCell();
			XBrowserAddHandler(monthNavCell, 'click', jumpToMonth);
			monthNavCell.innerHTML = monthsInYear[i];
			monthNavCells[i] = monthNavCell;
		}
		
		return monthNavTable.getTable();
	}
	
	function initMonthCells() {
		var selectedMonthTable = new TableHandler('SelectedMonth');
		
		navBackCell = selectedMonthTable.addCell('MonthScroll');

		navBackCell.innerHTML = '<img src="' + prevArrow + '">';
		XBrowserAddHandler(navBackCell, 'click', monthBack);
		
		for(var i=0; i < 2; i++) {
			var selectedMonthCell = selectedMonthTable.addCell();
			dispMonthCells[i] = selectedMonthCell;
		}
		
		navForwardCell = selectedMonthTable.addCell('MonthScroll');
		navForwardCell.innerHTML = '<img src="' + nextArrow + '">';
		XBrowserAddHandler(navForwardCell, 'click', monthForward);
		
		selectedMonthTable.addCell();
		
		return selectedMonthTable.getTable();
	}
	
	function initCalCells() {
		var calHolderTable = new TableHandler('CalHolder');
		
		var calHolderCell1 = calHolderTable.addCell();
		calHolderCell1.appendChild(initOneCal(dayCells1));
		
		var calHolderCell2 = calHolderTable.addCell();
		calHolderCell2.appendChild(initOneCal(dayCells2));
		
		return calHolderTable.getTable();
	}
	
	function initOneCal(cellList) {
		var calTable = new TableHandler('Calendar', true);
			
		var dowRow = calTable.addRow('DayOfWeek');
		
		for(var i=0; i < daysOfWeek.length; i++) {
			var calCell = calTable.addCell('DayOfWeek');
			calCell.innerHTML = daysOfWeek[i].substr(0,1);
		}
		
		for(j=0; j < 6; j++) {
			var calRow = calTable.addRow();
			
			for(var i=0; i < 7; i++) {
				var calCell = calTable.addCell();
				XBrowserAddHandler(calCell, 'click', selectDay);
				cellList.push(calCell);
			}
		}
		
		return calTable.getTable();
	}
	
	function jumpToMonth(evt) {
		var theTarget = getEventTarget(evt);
		for(var i=0; i < monthNavCells.length; i++) {
			if(theTarget == monthNavCells[i])  {
				drawMonth = i;
				refreshCal();
			}
		}
	}
	
	function selectDay(evt) {
		var theTarget = getEventTarget(evt);
		var drawDate = getDrawDate();
		for(var i=0; i < dayCells1.length; i++) {
			if(theTarget == dayCells1[i]) {
				var cellDate = buildDate(dayCells1[i].innerHTML, drawDate.getMonth(), drawDate.getFullYear());
				
				if(!isPast(cellDate)) {	
					outputInput.value = addZero(drawDate.getMonth()+1) + '/' + addZero(dayCells1[i].innerHTML) + '/' + drawDate.getFullYear();
					finalize();
				}
				return;
			}
		}
		
		for(var i=0; i < dayCells2.length; i++) {
			if(theTarget == dayCells2[i]) {
				var theDate = getFirstOfNextMonth(drawDate);
				
				var cellDate = buildDate(dayCells2[i].innerHTML, theDate.getMonth(), theDate.getFullYear());
				
				if(!isPast(cellDate)) {	
					outputInput.value = addZero(theDate.getMonth()+1) + '/' + addZero(dayCells2[i].innerHTML) + '/' + theDate.getFullYear();
					finalize();
				}
				return;
			}
		}
		
	}
	
	function finalize() {
		outputInput.focus();
		outputInput.select();
		//calendarDiv.style.display='none';
		window.setTimeout(function() {
			calendarDiv.style.display='none';
			if(callback) {
				callback(outputInput);
			}
		}, 100);
	}
	
	function addZero(num) {
		if(num < 10) {
			return '0' + num;
		}
		else return num;
	}
	
	function XBrowserAddHandler(target,eventName,handlerName) {
		if ( target.addEventListener )
			target.addEventListener(eventName, handlerName, false);
		else if ( target.attachEvent )
			target.attachEvent("on" + eventName, handlerName);
		else
			target["on" + eventName] = handlerName;
	}
	
	function blankCalendars() {
		blankCalendar(dayCells1);
		blankCalendar(dayCells2);
	}
	
	function blankCalendar(arr) {
		for(var i=0; i < arr.length; i++) {
			arr[i].innerHTML = '';
			arr[i].className = 'Calendar';
		}
	}
	
	function refreshCal(startDate) {
		if(!initialized) {
			initCal();
		}
		blankCalendars();
		
		var drawDate = getDrawDate();
		if(startDate) {
			drawDate = startDate;
		}
		
		var firstOfMonth = getFirstOfMonth(drawDate);
		drawCal(dayCells1, firstOfMonth);
		
		firstOfMonth = getFirstOfNextMonth(drawDate);
		drawCal(dayCells2, firstOfMonth);
		
		fillDispMonths(drawDate);
	}
	
	function fillDispMonths(theDate) {
		dispMonthCells[0].innerHTML = fullMonthsInYear[theDate.getMonth()] + ' ' + theDate.getFullYear();
		dispMonthCells[1].innerHTML = fullMonthsInYear[getFirstOfNextMonth(theDate).getMonth()] + ' ' + getFirstOfNextMonth(theDate).getFullYear();
	}
	
	function buildDate(day, month, year) {
		return parseDate((month + 1) + '/' + day + '/' + year);
	}
	
	function drawCal(dayCells, theDate) {
	
		var start = theDate.getDay();
		var end = getDaysInMonth(theDate.getFullYear(), theDate.getMonth()) + start;
		
		var count = 1;
		
		for(i=start; i < end; i++) {
			var cellClass = 'Calendar';
			
			var cellDate = buildDate(count, theDate.getMonth(), theDate.getFullYear());

			if(fromDate) {
				if(toDate) {
					if(cellDate.getTime() > fromDate.getTime() && cellDate.getTime() < toDate.getTime()) {
						cellClass += ' RangeSelected';
					}
					else if(cellDate.getTime() == toDate.getTime()) {
						cellClass += ' DateSelected';
					}
				}
				
				if(cellDate.getTime() == fromDate.getTime()) {
					cellClass += ' DateSelected';
				}
			}
			
			if(isPast(cellDate)) {
				cellClass += ' Past';
			}
			else if(isToday(cellDate)) {
				cellClass += ' Present';
			}
			else {
				cellClass += ' Future';
			}
			
			dayCells[i].className = cellClass;
			dayCells[i].innerHTML = count++;
		}
	}
	
	function getDaysInMonth(year, month) {
		if(month != 1) {
			return daysInMonth[month];
		}
		if((year - 2000) % 4 == 0) {
			return 29;
		}
		else {
			return 28;
		}
	}
	
	function isToday(theDate) {
		if(theDate.getTime() == today.getTime()) {
			return true;
		}
		else {
			return false;
		}
	}
	
	function isPast(theDate) {
		if(theDate && theDate.getTime() < today.getTime()) {
			return true;
		}
		else {
			return false;
		}
	}
	
	function getFirstOfMonth(theDate) {
		var dateStr = (theDate.getMonth() + 1) + '/' + 01 + '/' + theDate.getFullYear();
		return parseDate(dateStr);
	}
	
	function getFirstOfNextMonth(theDate) {
		if(theDate.getMonth()==11) {
			var dateStr = '01/01/' + (theDate.getFullYear() + 1);
			return parseDate(dateStr);
		}
		else {
			var dateStr = (theDate.getMonth() + 2) + '/' + 01 + '/' + theDate.getFullYear();
			return parseDate(dateStr);
		}
	}
	
	function getDrawDate() {
		return buildDate(1, drawMonth, drawYear);
	}
	
	function getTop(element) {
	var theElement = element;
	var newTop = 0;
	while(theElement.offsetParent) {
		newTop  += theElement.offsetTop;
		theElement = theElement.offsetParent;
	}
	return newTop;
	}
	
	function getBottom(element) {
		var theElement = element;
		
		return(getTop(theElement) + theElement.clientHeight);
	}
	
	function getLeft(element) {
		var theElement = element;
		var newLeft = 0;
		while(theElement.offsetParent) {
			newLeft  += theElement.offsetLeft;
			theElement = theElement.offsetParent;
		}
		return newLeft;
	}
	
	function getRight(element) {
		var theElement = element;
		
		return(getLeft(theElement) + theElement.clientWidth);
	}
	
	function monthForward() {
		drawMonth++;
		if(drawMonth == 12) {
			drawYear++;
			drawMonth = 0;
		}
		
		refreshCal();
	}
	
	function monthBack() {
		drawMonth--;
		if(drawMonth == -1) {
			drawYear--;
			drawMonth = 11;
		}
		
		refreshCal();
	}
	
	function testClose() {
		if(!noClose) {
			oThis.hide();
		}
		noClose = false;
	}
	
	function skipClose() {
		noClose = true;
	}

		function getEventTarget(evt) {
		var e;
		if(!evt) {
			e = window.event;
		}
		else {
			e = evt;
		}
		if(e.srcElement) {
			return e.srcElement;
		}
		else {
			return e.target;
		}
	}
	
	
	this.popup = function(output, ci, co, cb) {
		noClose = true;
		outputInput = output;
		callback = cb;
	
		if(ci) {
			fromDate = parseDate(ci);
		}
		else {
			fromDate = null;
		}
		if(co) {
			toDate = parseDate(co);
		}
		else {
			toDate = null;
		}
		
		if(fromDate) {
			if(!((drawMonth == (fromDate.getMonth()-1) && drawYear == fromDate.getFullYear()) || (drawMonth == 11 && fromDate.getMonth() == 0 && drawYear == (fromDate.getFullYear()-1)))) { // don't jump if chosen from date is in frame 2 of the calendar
				drawMonth = fromDate.getMonth();
				drawYear = fromDate.getFullYear();
			}
			if(toDate) {
				if(toDate < fromDate) {
					toDate = null;
				}
			}
		}
		else {
			drawMonth = today.getMonth();
			drawYear = today.getFullYear();
		}
		
		refreshCal();
		
		calendarDiv.style.left = getLeft(output) + 'px';
		calendarDiv.style.top = (getTop(output)) + 'px';
		calendarDiv.style.display='block';
	}
	
	this.hide = function() {
		if(calendarDiv) {
			calendarDiv.style.display='none';
		}
	}
		
	this.isInitialized = function() {
		return initialized;
	}
	
}

function TableHandler(clazz, skipFirstRow) {
	var mainClass = clazz;
	var currentRow;

	var theTable = document.createElement('table');
	if(mainClass) {
		theTable.className=mainClass;
	}
		
	var theBody = document.createElement('tbody');
	if(mainClass) {
		theBody.className=mainClass;
	}
	theTable.appendChild(theBody);
	
	
	this.addRow = function(theClass) {
		var theRow = document.createElement('tr');
		if(theClass) {
			theRow.className=theClass;
		}
		else {
			theRow.className=mainClass;
		}
		theBody.appendChild(theRow);
		currentRow = theRow;
		return theRow;
	}
	
	this.addCell = function(theClass) {
		var theCell = document.createElement('td');
		if(theClass) {
			theCell.className=theClass;
		}
		else {
			theCell.className=mainClass;
		}
		
		currentRow.appendChild(theCell);
		return theCell;
	}
	
	this.getTable = function() {
		return theTable;
	}
	
	if(!skipFirstRow) {
		this.addRow();
	}
}
