//
// DEFINITION
//


/**
 * Mainly a collection class
 * Manages all of the elements that can be used to modify dates
 */
var DateController = new Class({
	// Outlets -- elements that might need updating by this class
	outletDate: null,
	outletMonth: null,
	outletYear: null,
	outletDay: null,
	outletCalendar: null,
			
	initialize: function ( date, month, year, day, calendar ) {
		this.outletDate = date;
		this.outletMonth = month;
		this.outletYear = year;
		this.outletDay = day;
		this.outletCalendar = calendar;
	},
	
	/**
	 * Make sure the day of the month exists and that the user is not trying to reserve a date in the past
	 * Update the form to correct these issues if need be
	 */
	fixDay: function () {
		// Get the number of days in the month with a JS hack
		var arrival = new Date( this.outletYear.get('value'), this.outletMonth.get('value'), 0);
		var daysInMonth = arrival.getDate();
		
		if ( this.outletDate.get('value') > daysInMonth ) {
			this.outletDate.value = daysInMonth;
		}
		
		arrival = this.getDate();
		var now = new Date();
		
		if ( arrival < now ) {
			this.setDate( now );
		}
	},
	
	getDate: function () {
		var date = this.outletDate.get('value');
		var month = this.outletMonth.get('value');
		var year = this.outletYear.get('value');
		return new Date( year, month - 1, date )
	},
	
	setDate: function ( date ) {
		this.outletDate.value = date.getDate();
		this.outletMonth.value = date.getMonth() + 1;
		this.outletYear.value = date.getFullYear();
		if ( this.outletDay ) {
			this.outletDay.value = dayOfWeek[ date.getDay() ]
		}
	}
});


/**
 * Manages the entire reservation form
 */
var ResFormController = new Class({
	// Outlets -- elements that might need updating by this class
	outletArrive: null,
	outletDepart: null,
	outletNights: null,
	
	initialize: function ( arrive, depart, nights ) {
		this.outletArrive = arrive;
		this.outletDepart = depart;
		this.outletNights = nights;
	},
	
	// Actions -- aka event handlers
	actionChangeArrival: function ( event ) {
		this.outletArrive.fixDay();
		var arrivalDate = this.outletArrive.getDate();
		if ( this.outletDepart ) {
			var departureDate = this.outletDepart.getDate();
		
			if ( arrivalDate >= departureDate ) {
				// Set departure date to one day after arrival date
				departureDate = new Date( arrivalDate );
				departureDate.setDate( departureDate.getDate() + 1 );
				this.outletDepart.setDate( departureDate );
			}
			this.updateDay( arrivalDate, departureDate );
			var days = Math.round( (departureDate - arrivalDate) / 86400000 ); // Milliseconds
			this.outletNights.value = days;
		}
	},
	actionChangeDeparture: function ( event ) {
		this.outletDepart.fixDay();
		var arrivalDate = this.outletArrive.getDate();
		var departureDate = this.outletDepart.getDate();
		
		if ( arrivalDate >= departureDate ) {
			// Set arrival date to one day before departure date
			arrivalDate = new Date( departureDate );
			arrivalDate.setDate( arrivalDate.getDate() - 1 );
			this.outletArrive.setDate( arrivalDate );
		}
		this.updateDay( arrivalDate, departureDate );
		var days = Math.round( (departureDate - arrivalDate) / 86400000 );
		this.outletNights.value = days;
	},
	actionChangeNights: function ( event ) {
		if ( this.outletNights ) {
			var arrivalDate = this.outletArrive.getDate();
			var days = Number( this.outletNights.get('value') );
			if ( days > 0 ) {
				var departureDate = new Date( arrivalDate );
				departureDate.setDate( departureDate.getDate() + days );
				this.outletDepart.setDate( departureDate );
				this.actionChangeDeparture();
			}
		}
	},
	
	updateDay: function ( arrival, departure ) {
		if ( this.outletArrive.outletDay ) {
			this.outletArrive.outletDay.value = dayOfWeek[ arrival.getDay() ];
		}
		if ( this.outletDepart && this.outletDepart.outletDay ) {
			this.outletDepart.outletDay.value = dayOfWeek[ departure.getDay() ];
		}
	}
});


//
// IMPLEMENTATION
//

window.addEvent( 'domready', function() {
	var nodeResForm = $( 'resform' );
	if ( nodeResForm ) {
		// Grab all of the nodes that we'll be working with
		// This is kind of resource intensive, so we should only do this once
		var nodeArriveDate = nodeResForm.getElement( 'select[name=arriveDate]' );
		var nodeArriveMonth = nodeResForm.getElement( 'select[name=arriveMonth]' );
		var nodeArriveYear = nodeResForm.getElement( 'select[name=arriveYear]' );
		var nodeArriveCalendar = new Calendar({ checkinLabel: {arriveDate: 'j', arriveMonth: 'n', arriveYear: 'Y' }}, 
											{ direction: 0.5 }); // uses calendar.*.js
		// Instantiate the form controllers and set the outlets
		var arriveDateController = new DateController( nodeArriveDate, 
											nodeArriveMonth,
											nodeArriveYear,
											null,
											nodeArriveCalendar );
											
		var resFormController = new ResFormController( arriveDateController, 
													null, 
													null );												
		// Set the Arrival fields to today and the Departure fields to tomorrow
		var now = new Date();
		arriveDateController.setDate( now );
	
		resFormController.outletArrive.outletCalendar.options.onchange = resFormController.actionChangeArrival.bind( resFormController );
				
		// Set the actions so the form updates itself when a user changes something
		nodeArriveDate.addEvent( 'change', resFormController.actionChangeArrival.bindWithEvent( resFormController ) );
		nodeArriveMonth.addEvent( 'change', resFormController.actionChangeArrival.bindWithEvent( resFormController ));
		nodeArriveYear.addEvent( 'change', resFormController.actionChangeArrival.bindWithEvent( resFormController ) );
	}
});