/**
 * datePicker.js
 * version: 1.0
 * author: Jeffrey Kacmarcik <jrkacmar@wisc.edu>
 * Copyright 2008 The Board of Regents of the University of Wisconsin System
 *
 * requires: http:/law.wisc.edu/js/helpers.js
 * instructions: 
 *  1. include this script in the header of a page.  e.g., <script type="text/javascript" src="/js/datePicker.js"></script>
 *  2. add 'datePicker' to input text items that you want this to apply to. e.g., <input type="text" rel="datePicker" name="blah" value="2008-03-20" />
 *  3. either: include /js/datePicker.css as a stylesheet, or make a custom one.  if creating from scratch: at minimum the containing div needs to be 'absolute'
 *
 * caveats:
 *  1. this will only work with input items of type "text" (doesn't make sense any where else)
 *  2. always use addWindowOnload (defined in helpers.js) to add a window.onload function to a page... otherwise multiple onloads _WILL_ overwrite one another
 *  3. as of 2008/3/20 tested & working on OSX FF2, PC FF2/FF3b4, Linux FF2, IE7
 */


// some constant-ish things
var Months = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ];
var Days = [ "S", "M", "T", "W", "T", "F", "S" ];

var DATE_ICON = "/icons/famfamfam/calendar.png";
var DATE_ICON_ALT = "Choose Date";

/**
 * datePicker class
 * 
 * @param string $element_id the id of the a element which will trigger the date picker
 * @access public
 * @return void
 */
function datePicker( el )
{
	var self = this;
	self.el = false;
	self.button = false;
	self.cal = false;

	self.today = new Date();
	self.selectedMonth = self.today.getMonth()+1;
	self.selectedDate = self.today.getDate();
	self.selectedYear = self.today.getFullYear();

	/**
	 *  class constructor
	 */
	self.init = function( el )
	{
		self.el = $(el);
	
		// create the icon
		self.button = create("a").set("href", "javascript:void(0)");
		self.button.onclick = function()
		{
			if( self.cal === false )
			{
				self.redrawCalendar();
			}
			else
			{
				self.closeCal();
			}
		};
		self.button.append( create("img").set("src", DATE_ICON).set("alt", DATE_ICON_ALT).set("title", DATE_ICON_ALT) );
		insertAfter( self.el.parentNode, self.button, self.el );

/*
		self.el.onfocus = self.el.onclick = function()
		{
			if( self.cal === false )
				{ self.redrawCalendar(); }
		};
*/
		// set the initial date.
		if( self.el.value.length != 0 )
		{
			var originalDate = self.el.value.match( /^([0-9]*)-([0-9]*)-([0-9]*)$/ );
			self.selectedYear = ( originalDate[1] != '0000' ) ? parseInt(originalDate[1],10) : self.selectedYear;
			self.selectedMonth = ( originalDate[2] != '00' ) ? parseInt(originalDate[2],10) : self.selectedMonth;
			self.selectedDate = ( originalDate[3] != '00' ) ? parseInt(originalDate[3],10) : self.selectedDate;
		}

	};

	self.closeCal = function()
	{
		delById( self.cal );
		self.cal = false;
	};

	/**
	 * redraw the calendar for the currently selected date
	 */
	self.redrawCalendar = function()
	{
		if( self.cal !== false )
		{
			self.closeCal();
		}
		
		var pos = getElementPosition( self.el );
		self.cal = self.generateCalendar( self.selectedMonth, self.selectedYear );
		
		self.cal.style.top = (pos.y+22) + "px";
		self.cal.style.left = pos.x + "px";

		document.body.appendChild( self.cal );
	};

	/**
	 *  generate the calendar table for the specified month and year 
	 */
	self.generateCalendar = function( month, year )
	{
		var cal = create('div');
		cal.className = "lawCal";

		var table = create('table');
		var tbody = create('tbody');
		
		// month heading
		var decr_link = create('a').set('href', 'javascript:void(0)').set('onclick', function() { self.decrMonth(); }).set('innerHTML', '&laquo;');
		var decr = create('td').set('className', 'heading').append( decr_link );
		var hmonth = create('td').set('className', 'heading').set('colSpan', 5).append( Months[month-1]+' '+year );
		var incr_link = create('a').set('href', 'javascript:void(0)').set('onclick', function() { self.incrMonth(); }).set('innerHTML', '&raquo;');
		var incr = create('td').set('className', 'heading').append( incr_link );

		var row = create('tr').append(decr).append(hmonth).append(incr);
		tbody.append( row );

		// weekday headings
		var row = create('tr');
		for( var d=0; d<7; d++ )
			{ row.append( create('th').append( Days[d] ) ); }
		tbody.appendChild( row );

		// dates
		var temp_date = new Date();
		temp_date.setDate(1);
		temp_date.setMonth( month-1 );
		temp_date.setFullYear( year );
		do // for as many weeks as needed
		{
			var row = create('tr');
			for( var d=1; d<=7; d++ )
			{
				// for each day in the week

				if( temp_date.getDay() != d-1 || month != temp_date.getMonth()+1 )
				{ 
					// skip days not in this month
					row.append( create('td') ); 
				}
				else
				{
					// the day link
					var date_link = create('a').set('href', 'javascript:void(0)');
					date_link.set('year', temp_date.getFullYear()).set('month', temp_date.getMonth()+1).set('ddate', temp_date.getDate());
					date_link.set('onclick', function() { self.pickDate( this.year, this.month, this.ddate ); } );
					date_link.append( temp_date.getDate() );
			
					var cell = create('td').append( date_link );

					// highlight the current date in use
					if( 	temp_date.getFullYear() == self.selectedYear && 
						temp_date.getMonth()+1 == self.selectedMonth && 
						temp_date.getDate() == self.selectedDate )
					{
						cell.className = "active";
					}

					// highlight todays date
					if( 	temp_date.getFullYear() == self.today.getFullYear() && 
						temp_date.getMonth() == self.today.getMonth() && 
						temp_date.getDate() == self.today.getDate() )
					{
						cell.className += " today";
					}
					

					row.append( cell ); 
				
					temp_date.setDate( temp_date.getDate()+1 );	

				}
			}
			tbody.appendChild( row );
			
			// break once the month is over
			if( month != temp_date.getMonth()+1 )
				{ break; }
		} while( true );

		// put it all together
		table.appendChild( tbody );
		cal.appendChild( table );

		// return the table we created
		return cal;
	};

	/**
	 * move to the next month 
	 */
	self.incrMonth = function()
	{
		self.selectedMonth++;
		if( self.selectedMonth > 12 )
		{
			self.selectedMonth = 1;
			self.selectedYear++;
		}

		// redraw
		self.redrawCalendar();
	};

	/**
	 * move to the previous month
	 */
	self.decrMonth = function()
	{
		self.selectedMonth--;
		if( self.selectedMonth < 1 )
		{
			self.selectedMonth = 12;
			self.selectedYear--;
		}

		// redraw
		self.redrawCalendar();
	};

	/**
	 * a date was picked-- send it back to the input item
	 */
	self.pickDate = function( year, month, day )
	{
		self.selectedYear = year;
		self.selectedMonth = month;
		self.selectedDate = day;

		// datestamp = 'YYYY-MM-DD'
		var datestamp = 
			year + '-' +
			((month<10) ? '0'+month : month) + '-' +
			((day<10) ? '0'+day : day);

		self.el.value = datestamp;

		// fire any onchange event that might exist
		if( self.el.onchange )
			{ self.el.onchange(); }

		self.redrawCalendar(); // redraw for good measure
		self.closeCal(); // close the calendar
	};

	// call the constructor
	self.init( el );
}


/**
 * findDatePickerItems
 *   loop through all input items and find any ones that need the calendar system added
 * 
 * @access public
 * @return void
 */
function findDatePickerItems()
{
	var inputs = document.getElementsByTagName('input');
	var dps = new Array();

	for (var i=0; i < inputs.length; i++) 
	{
		var attr = inputs[i].getAttribute('rel');
		if ( !attr || attr != 'datePicker' )
			{ continue; }

		if( inputs[i].getAttribute('type') != 'text' )
			{ continue; }

		// create a new datePicker and push it onto the array.  it may not be needed to keep track of these
		dps.push( new datePicker( inputs[i] ) );
	}
}

// window.onload
addWindowOnload( function() { findDatePickerItems(); } );

/**
 *  
 */
