var hjsDatePicker = new Class({

	/* set and create the ctl00_ContentPlaceHolder1_date picker text box */
	initialize: function(hjs){

		// Options defaults
		this.dayChars = 1; // number of characters in day names abbreviation
		this.dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
		this.daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
		this.format = 'mm/dd/yyyy';
		this.monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
		this.startDay = 7; // 1 = week starts on Monday, 7 = week starts on Sunday
		this.yearOrder = 'asc';
		this.yearRange = 10;
		this.yearStart = (new Date().getFullYear());


		// Finds the entered ctl00_ContentPlaceHolder1_date, or uses the current ctl00_ContentPlaceHolder1_date
		if(hjs.value != '') {
			hjs.then = new Date(hjs.value);
			hjs.today = new Date();
		} else {
			hjs.then = hjs.today = new Date();
		}
		// Set beginning time and today, remember the original
		hjs.oldYear = hjs.year = hjs.then.getFullYear();
		hjs.oldMonth = hjs.month = hjs.then.getMonth();
		hjs.oldDay = hjs.then.getDate();
		hjs.nowYear = hjs.today.getFullYear();
		hjs.nowMonth = hjs.today.getMonth();
		hjs.nowDay = hjs.today.getDate();

		// Pull the rest of the options from the alt attr
		if(hjs.alt) {
			options = Json.evaluate(hjs.alt);
		} else {
			options = [];
		}
		hjs.options = {
			monthNames: (options.monthNames && options.monthNames.length == 12 ? options.monthNames : this.monthNames) || this.monthNames, 
			daysInMonth: (options.daysInMonth && options.daysInMonth.length == 12 ? options.daysInMonth : this.daysInMonth) || this.daysInMonth, 
			dayNames: (options.dayNames && options.dayNames.length == 7 ? options.dayNames : this.dayNames) || this.dayNames,
			startDay : options.startDay || this.startDay,
			dayChars : options.dayChars || this.dayChars, 
			format: options.format || this.format,
			yearStart: options.yearStart || this.yearStart,
			yearRange: options.yearRange || this.yearRange,
			yearOrder: options.yearOrder || this.yearOrder
		};
		/*hjs.setProperties({'id':hjs.getProperty('name'), 'readonly':true});*/
		hjs.setProperties({'ctl00_ContentPlaceHolder1_date':hjs.getProperty('ctl00$ContentPlaceHolder1$date'), 'readonly':true});
		hjs.container = false;
		hjs.calendar = false;
		hjs.interval = null;
		hjs.active = false;
		hjs.onclick = hjs.onfocus = this.create.pass(hjs, this);
	},

	/* create the calendar */
	create: function(hjs){
		if (hjs.calendar) return false;

		// Hide select boxes while calendar is up
		if(window.ie6){
			$$('select').addClass('hjs_hide');
		}
		
		/* create the outer container */
		hjs.container = new Element('div', {'class':'hjs_container'}).injectBefore(hjs);
		
		/* create timers */
		hjs.container.onmouseover = hjs.onmouseover = function(){
			$clear(hjs.interval);
		};
		hjs.container.onmouseout = hjs.onmouseout = function(){
			hjs.interval = setInterval(function(){
				if (!hjs.active) this.remove(hjs);
			}.bind(this), 500);
		}.bind(this);
		
		/* create the calendar */
		hjs.calendar = new Element('div', {'class':'hjs_cal'}).injectInside(hjs.container);
		
		/* create the ctl00_ContentPlaceHolder1_date object */
		var ctl00_ContentPlaceHolder1_date = new Date();
		
		/* create the ctl00_ContentPlaceHolder1_date object */
		if (hjs.month && hjs.year) {
			ctl00_ContentPlaceHolder1_date.setFullYear(hjs.year, hjs.month, 1);
		} else {
			hjs.month = ctl00_ContentPlaceHolder1_date.getMonth();
			hjs.year = ctl00_ContentPlaceHolder1_date.getFullYear();
			ctl00_ContentPlaceHolder1_date.setDate(1);
		}
		hjs.year % 4 == 0 ? hjs.options.daysInMonth[1] = 29 : hjs.options.daysInMonth[1] = 28;
		
		/* set the day to first of the month */
		var firstDay = (1-(7+ctl00_ContentPlaceHolder1_date.getDay()-hjs.options.startDay)%7);
		
		
		
		/* create the month select box */
		monthSel = new Element('select', {'id':hjs.id + '_monthSelect'});
		for (var m = 0; m < hjs.options.monthNames.length; m++){
			monthSel.options[m] = new Option(hjs.options.monthNames[m], m);
			if (hjs.month == m) monthSel.options[m].selected = true;
		}
		
		/* create the year select box */
		yearSel = new Element('select', {'id':hjs.id + '_yearSelect'});
		i = 0;
		hjs.options.yearStart ? hjs.options.yearStart : hjs.options.yearStart = ctl00_ContentPlaceHolder1_date.getFullYear();
		if (hjs.options.yearOrder == 'desc'){
			for (var y = hjs.options.yearStart; y > (hjs.options.yearStart - hjs.options.yearRange - 1); y--){
				yearSel.options[i] = new Option(y, y);
				if (hjs.year == y) yearSel.options[i].selected = true;
				i++;
			}
		} else {
			for (var y = hjs.options.yearStart; y < (hjs.options.yearStart + hjs.options.yearRange + 1); y++){
				yearSel.options[i] = new Option(y, y);
				if (hjs.year == y) yearSel.options[i].selected = true;
				i++;
			}
		}
		
		/* start creating calendar */
		calTable = new Element('table');
		calTableThead = new Element('thead');
		calSelRow = new Element('tr');
		calSelCell = new Element('th', {'colspan':'7'});
		monthSel.injectInside(calSelCell);
		yearSel.injectInside(calSelCell);
		calSelCell.injectInside(calSelRow);
		calSelRow.injectInside(calTableThead);
		calTableTbody = new Element('tbody');
		
		/* create day names */
		calDayNameRow = new Element('tr');
		for (var i = 0; i < hjs.options.dayNames.length; i++) {
			calDayNameCell = new Element('th');
			calDayNameCell.appendText(hjs.options.dayNames[(hjs.options.startDay+i)%7].substr(0, hjs.options.dayChars)); 
			calDayNameCell.injectInside(calDayNameRow);
		}
		calDayNameRow.injectInside(calTableTbody);
		
		/* create the day cells */
		while (firstDay <= hjs.options.daysInMonth[hjs.month]){
			calDayRow = new Element('tr');
			for (i = 0; i < 7; i++){
				if ((firstDay <= hjs.options.daysInMonth[hjs.month]) && (firstDay > 0)){
					calDayCell = new Element('td', {'class':hjs.id + '_calDay', 'axis':hjs.year + '|' + (parseInt(hjs.month) + 1) + '|' + firstDay}).appendText(firstDay).injectInside(calDayRow);
				} else {
					calDayCell = new Element('td', {'class':'hjs_empty'}).appendText(' ').injectInside(calDayRow);
				}
				// Show the previous day
				if ( (firstDay == hjs.oldDay) && (hjs.month == hjs.oldMonth ) && (hjs.year == hjs.oldYear) ) {
					calDayCell.addClass('hjs_selected');
				}
				// Show today
				if ( (firstDay == hjs.nowDay) && (hjs.month == hjs.nowMonth ) && (hjs.year == hjs.nowYear) ) {
					calDayCell.addClass('hjs_today');
				}
				firstDay++;
			}
			calDayRow.injectInside(calTableTbody);
		}
		
		/* table into the calendar div */
		calTableThead.injectInside(calTable);
		calTableTbody.injectInside(calTable);
		calTable.injectInside(hjs.calendar);
		
		/* set the onmouseover events for all calendar days */
		$$('td.' + hjs.id + '_calDay').each(function(el){
			el.onmouseover = function(){
				el.addClass('hjs_roll');
			}.bind(this);
		}.bind(this));
		
		/* set the onmouseout events for all calendar days */
		$$('td.' + hjs.id + '_calDay').each(function(el){
			el.onmouseout = function(){
				el.removeClass('hjs_roll');
			}.bind(this);
		}.bind(this));
		
		/* set the onclick events for all calendar days */
		$$('td.' + hjs.id + '_calDay').each(function(el){
			el.onclick = function(){
				ds = el.axis.split('|');
				hjs.value = this.formatValue(hjs, ds[0], ds[1], ds[2]);
				this.remove(hjs);
			}.bind(this);
		}.bind(this));
		
		/* set the onchange event for the month & year select boxes */
		monthSel.onfocus = function(){ hjs.active = true; };
		monthSel.onchange = function(){
			hjs.month = monthSel.value;
			hjs.year = yearSel.value;
			this.remove(hjs);
			this.create(hjs);
		}.bind(this);
		
		yearSel.onfocus = function(){ hjs.active = true; };
		yearSel.onchange = function(){
			hjs.month = monthSel.value;
			hjs.year = yearSel.value;
			this.remove(hjs);
			this.create(hjs);
		}.bind(this);
	},
	
	/* Format the returning ctl00_ContentPlaceHolder1_date value according to the selected formation */
	formatValue: function(hjs, year, month, day){
		/* setup the ctl00_ContentPlaceHolder1_date string variable */
		var ctl00_ContentPlaceHolder1_dateStr = '';
		
		/* check the length of day */
		if (day < 10) day = '0' + day;
		if (month < 10) month = '0' + month;
		
		/* check the format & replace parts // thanks O'Rey */
		ctl00_ContentPlaceHolder1_dateStr = hjs.options.format.replace( /dd/i, day ).replace( /mm/i, month ).replace( /yyyy/i, year );
		hjs.month = hjs.oldMonth = '' + (month - 1) + '';
		hjs.year = hjs.oldYear = year;
		hjs.oldDay = day;
		
		/* return the ctl00_ContentPlaceHolder1_date string value */
		return ctl00_ContentPlaceHolder1_dateStr;
	},
	
	/* Remove the calendar from the page */
	remove: function(hjs){
		$clear(hjs.interval);
		hjs.active = false;
		if (window.opera) hjs.container.empty();
		else if (hjs.container) hjs.container.remove();
		hjs.calendar = false;
		hjs.container = false;
		$$('select.hjs_hide').removeClass('hjs_hide');
	}
});
