/*

	DatePicker component
	Creates dropdowns for selecting a date. Automatically disables invalid options like 29th of February on non-leap-years

	Constructor requires one parameter:
		* Id			Unique identifier of the datepicker control (for support of multiple controls in one page)

	Constructor can optionally accept a second parameter, with any of the following options:
		* AgeLimit		Disables selection of dates more recent than the specified amount of years. Defaults to 0.
		* StartDate		Specifies the date (yyyy-mm-dd) that will be selected on page load.
		* Container		Sets the datepicker to be created within a container element. When not specified, container is rendered in page load using document.write()
		* Minimalize	Sets the datepicker values to the format of '25', '12', '2007', rather than '25th' of 'December', '2007'. Defaults to false.
		* Time			Adds options for specifying time as well as date. Defaults to false.
		* YearFrom		Sets the first selectable year, from oldest to most recent. Defaults to 1959
		* YearTo		Sets the last selectable year, from oldest to most recent. Overriden by AgeLimit. Defaults to current year.

	viz.
		<script type="text/javascript">
		new DatePicker('dp_1', { AgeLimit: 18, StartDate: '1980-12-24', Container: 'div_dp' });
		</script>
*/
DatePicker = Class.create();
DatePicker.prototype =
{
	initialize: function(id)
	{
		this.Options = arguments[1] ? arguments[1] : {};
		this.Id = id;

		this.Months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];

		if(!this.Options.Container)
		{
			document.write('<select name="' + id + '_day" id="' + id + '_day"></select> ');

			if(!this.Options.Minimalize)
				document.write('of ');

			document.write('<select name="' + id + '_month" id="' + id + '_month"></select> ');
			document.write('<select name="' + id + '_year" id="' + id + '_year"></select>');
		}
		else
		{
			var c = $(this.Options.Container);

			d = document.createElement('select');
			m = document.createElement('select');
			y = document.createElement('select');

			d.name = d.id = id + '_day';
			m.name = m.id = id + '_month';
			y.name = y.id = id + '_year';

			c.appendChild(d);
			c.innerHTML += this.Options.Minimalize ? ' ' : ' of ';
			c.appendChild(m);
			c.innerHTML += ' ';
			c.appendChild(y);

			if(this.Options.Time)
			{
				var h = document.createElement('select');
				var m = document.createElement('select');

				h.name = h.id = id + '_hour';
				m.name = m.id = id + '_minute';

				c.innerHTML += ' ';
				c.appendChild(h);
				c.innerHTML += ' ';
				c.appendChild(m);
			}
		}

		this.SetupDatePicker();
		this.SetupEvents();
	},

	SetupEvents: function()
	{
		Event.observe(this.Id + '_month', 'change', this.Update.bind(this));
		Event.observe(this.Id + '_year', 'change', this.Update.bind(this));
	},

	Update: function()
	{
		var year = $(this.Id + '_year');
		var month = $(this.Id + '_month');
		var day = $(this.Id + '_day');

		var daysInMonth = 31;
		var m = month.selectedIndex + 1;
		var y = year[year.selectedIndex].value;
		if(m == 2)
			daysInMonth = (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) ? 29 : 28;
		else
			daysInMonth = ((m < 8 && m % 2 == 0) || (m > 8 && m % 2 != 0)) ? 30 : 31;

		if(year.selectedIndex == 0) {
			for(i = 11; i >= new Date().getMonth(); i--) {

				if(!month[i])
					break;

				if(parseInt(month[i].value) == new Date().getMonth() +1)
					break;

				month.remove(i);
			}
			if(parseInt(month.value) == new Date().getMonth()+1) {
				for(i = 30; i >= new Date().getDate(); i--) {
					if(day[i])
					{
						if(parseInt(day[i].value) == new Date().getDate())
							break;

						day.remove(i);
					}
				}
			} else {
				for(i = parseInt(day.options[day.options.length-1].value)+1; i <= daysInMonth; i++) {
					var opt = document.createElement('option');
					opt.value = '0' + i;
					opt.value = opt.value.substring(opt.value.length-2, opt.value.length);
					opt.text = this.GetDayName(i);

					try {
						day.add(opt, null);
					} catch(ex) {
						day.add(opt); //ie
					}
				}
			}
		} else {
			for(i = parseInt(month.options[month.options.length-1].value)+1; i <= 12; i++) {
				var opt = document.createElement('option');
				opt.value = '0' + i;
				opt.value = opt.value.substring(opt.value.length-2, opt.value.length);
				opt.text = this.Months[i-1];

				try {
					month.add(opt, null);
				} catch(ex) {
					month.add(opt); //ie
				}
			}

			for(i = parseInt(day.options[day.options.length-1].value)+1; i <= daysInMonth; i++) {
				var opt = document.createElement('option');
				opt.value = '0' + i;
				opt.value = opt.value.substring(opt.value.length-2, opt.value.length);
				opt.text = this.GetDayName(i);

				try {
					day.add(opt, null);
				} catch(ex) {
					day.add(opt); //ie
				}
			}
		}

		for(i = day.options.length-1; i >= daysInMonth; i--)
		{
			day.remove(i);
		}
	},

	GetDayName: function(day)
	{
		if(this.Options.Minimalize)
			return day;

		switch(day % 10)
		{
			case 1:
				day = (day == 11) ? day + "th" : day + "st";
				break;
			case 2:
				day = (day == 12) ? day + "th" : day + "nd";
				break;
			case 3:
				day = (day == 13) ? day + "th" : day + "rd";
				break;
			default:
				day = day + "th";
				break;
		}

		return day;
	},

	SetupDatePicker: function()
	{
		id = this.Id;

		for(dpi = 1; dpi <= 31; dpi++)
		{
			sValue = dpi;
			if(sValue < 10)	sValue = "0" + dpi;

			sDay = this.GetDayName(dpi);

			$(id + '_day').options.add(new Option(sDay, sValue));
		}

		for(dpi = 0; dpi < this.Months.length; dpi++)
		{
			sValue = (dpi+1);
			if(sValue < 10)	sValue = "0" + sValue;

			var name = this.Months[dpi];
			if(this.Options.Minimalize)
				name = (dpi+1);

			$(id + '_month').options.add(new Option(name, sValue));
		}

		ageLimit = this.Options.AgeLimit ? this.Options.AgeLimit : 0;

		yearOffset = isIe ? 0 : 1900;

		if(ageLimit > 0)
			var year = yearOffset - ageLimit + new Date().getYear();
		else if(this.Options.YearTo)
			var year = this.Options.YearTo;
		else
			var year = yearOffset + new Date().getYear();

		yearFrom = 1959;
		if(this.Options.YearFrom)
			yearFrom = this.Options.YearFrom;

		for(dpi = year; dpi >= yearFrom; dpi--)
		{
			$(id + '_year').options.add(new Option(dpi, dpi));
		}

		if(this.Options.Time)
		{
			for(dpi = 0; dpi < 24; dpi++)
			{
				name = dpi;
				if(name < 10)
					name = '0' + dpi;

				$(id + '_hour').options.add(new Option(name, name));
			}

			for(dpi = 0; dpi < 60; dpi++)
			{
				name = dpi;
				if(name < 10)
					name = '0' + dpi;

				$(id + '_minute').options.add(new Option(name, name));
			}
		}

		if(ageLimit > 0)
			$(id + '_year').selectedIndex = 1;

		if(this.Options.StartDate)
		{
			year = this.Options.StartDate.substring(0, 4);
			month = this.Options.StartDate.substring(5, 7);
			day = this.Options.StartDate.substring(8, 10);

			$(id + '_year').value = year;
			$(id + '_month').value = month;
			$(id + '_day').value = day;

			if(this.Options.Time && this.Options.StartDate.length > 10)
			{
				hour = this.Options.StartDate.substring(11, 13);
				minute = this.Options.StartDate.substring(14, 16);

				$(id + '_hour').value = hour;
				$(id + '_minute').value = minute;
			}
		}
	}
}