
var hpCalendar = new Class({
	
	Implements: Options,

	options: {
        reference: '',
        popup: 0,
        inlineRef: '',
        endDate: '',
        propRef: '',
        currency: 'GBP'
    },

	initialize: function(options){
		
		this.setOptions(options);
		this.options.reference = this.options.reference+'-';
		this.arrival = null;
		//this.departure = null;
		this.clicks = 0;
		this.hpCalModel = new DHTMLSuite.calendarModel({ });
		this.invalidDatesLoaded = 0;
		
		//console.log(this.options.endDate)
		
		//Set which fields are present
		this.arrivalField = 0;
		//this.departureField = 0;
		//this.durationField = 0;
		if($(this.options.reference+'arrival-d') && $(this.options.reference+'arrival-y-m')) this.arrivalField = 1;
		//if($(this.options.reference+'departure-d') && $(this.options.reference+'departure-y-m')) this.departureField = 1;
		//if($(this.options.reference+'days-offset')) this.durationField = 1;
		
		var today = new Date();
		
		//Set invalid dates - first is all dates before today	
		this.hpCalModel.addInvalidDateRange(false,{year: today.getFullYear(),month: today.getMonth()+1,day: today.getDate()-1});
		
		//Set invalid end date
		if(this.options.endDate) this.hpCalModel.addInvalidDateRange(this.options.endDate, false);
		
		//Request holder
		this.request = null; 
		
		//Set the calendar language ref
		this.hpCalModel.setLanguageCode('en');
		
		//Setup default calendar options
		var defaultCalOptions = { 
			id: this.options.reference+'availabilityCal',
			callbackFunctionOnDayClick: 'getDateFromCalendar',
			scrollInYearDropDownActive: false,
			dropdownStartYear: today.getFullYear(),
			dropdownEndYear: this.options.year,			
			combineNaviation: true,
			displayCloseButton: false
		}
		
		if(this.options.popup){
			defaultCalOptions.closeButtonPosition = 'bottom';
			defaultCalOptions.displayCloseButton = true;
		}
		
		var calOptions = $merge(defaultCalOptions, options)
		
		//Create calendar
		this.hpCal = new DHTMLSuite.calendar(calOptions);
		
		//Set a reference to this for use in the getDateFromCalendar method
		this.hpCal.self = this;
		
		this.hpCal.dropdownStartYear = today.getFullYear();
		this.hpCal.dropdownEndYear = this.options.endDate.year ? this.options.endDate.year : today.getFullYear() + 2;
		
		//Set the calendar reference
		this.hpCal.setCalendarModelReference(this.hpCalModel);	
		
		this.hpCal.resetViewDisplayedMonth();
					
		if(!this.options.popup){
			this.hpCal.setTargetReference(this.options.inlineRef);
			this.hpCal.display();
		}else{
			//We have to initialise the calendar so we can set the selected dates
			this.hpCal.display();
			this.hpCal.hide();
		}
				
		if(!this.options.popup){
			if($('calendar_pane')){
				$('calendar_pane').addEvent('click',this.getInvalidDates.bind(this));
			}else{
				this.getInvalidDates();
			}
		}
				
		//Set the arrival / departure dates
		var arrival = this.getDate('arrival');
		//var departure = this.getDate('departure');
		if(arrival){
			this.setDate('arrival',arrival)
		}
		//if(departure){this.setDate('departure',departure)	}
		
		var initialDate = this.getDate('arrival');	
		if(initialDate){
			//Set the initial date
			this.hpCalModel.initialDay = initialDate.day;
			this.hpCalModel.initialMonth = initialDate.month;
			this.hpCalModel.initialYear = initialDate.year;
			this.hpCalModel.__setDisplayedDateToInitialData();
		}
		
					
		//Set the on change events for arrive/depart
		if(this.arrivalField) $(this.options.reference+'arrival-d').addEvent('change',function(e){return this.updateDate('arrival',e)}.bind(this));
		if(this.arrivalField) $(this.options.reference+'arrival-y-m').addEvent('change',function(e){return this.updateDate('arrival',e)}.bind(this));		
		//if(this.departureField) $(this.options.reference+'departure-d').addEvent('change',function(e){return this.updateDate('departure',e)}.bind(this));
		//if(this.departureField) $(this.options.reference+'departure-y-m').addEvent('change',function(e){return this.updateDate('departure',e)}.bind(this));		
		//if(this.durationField) $(this.options.reference+'days-offset').addEvent('change',function(e){return this.updateDepart('',e)}.bind(this));
		if($(this.options.reference+'clear_button')) $(this.options.reference+'clear_button').addEvent('click',this.clearForm.bind(this));
		
		if($(this.options.reference+'arrival_icon')) $(this.options.reference+'arrival_icon').setStyle('display','').addEvent('click',this.showPopup.bind(this));
		//if($(this.options.reference+'departure_icon')) $(this.options.reference+'departure_icon').setStyle('display','').addEvent('click',this.showPopup.bind(this));
			
		//Set the duration
		this.updateDuration();
	}, 
	
	showPopup: function(e){
		
		var buttonObj = e.target;

		this.hpCal.setCalendarPositionByHTMLElement(buttonObj,0,buttonObj.offsetHeight+2);	// Position the calendar right below the form input
	
		//Set the target
		this.source = buttonObj.get('class');
		
		//Detect which input has been clicked and set the initial date accordingly	
		var arrival = this.getDate('arrival');
		//var departure = this.getDate('departure');
		
		var initialDate = this.getDate(this.source);				
		if(this.source == 'departure' && arrival && !departure){
			initialDate = arrival;
		}
		
		if(initialDate){
			//Set the initial date
			this.hpCalModel.initialDay = initialDate.day;
			this.hpCalModel.initialMonth = initialDate.month;
			this.hpCalModel.initialYear = initialDate.year;
			this.hpCalModel.__setDisplayedDateToInitialData();
		}
		
		//Set the selected dates if previously set
		if(this.arrival){
			this.hpCalModel.FromDate = arrival.year+''+arrival.month+''+arrival.day;
		}
//		if(this.departure){	this.hpCalModel.ToDate = departure.year+''+departure.month+''+departure.day;		}
		
		
	
		if(this.hpCal.isVisible()){
			this.hpCal.hide();
		}else{		
			this.hpCal.resetViewDisplayedMonth();	// This line resets the view back to the inital display, i.e. it displays the inital month and not the month it displayed the last time it was open.		
			this.hpCal.display();
			this.hpCal.__populateMonthView();		
		}		
	},
	
	getDateFromCalendar: function(inputArray){
		
		if(!validateDate(inputArray, this.options.endDate)){
			return false;
		}

		if(!this.options.popup){
			if(this.clicks == 0){
				this.source = 'arrival';
			}else{
				this.source = 'departure';
			}
		}
		
		if(this.source == 'arrival'){
			if(this.departure){
				if(!validateDateRange(this.hpCalModel,inputArray,this.departure)){					
					return false;
				}
			}
			this.arrival = inputArray;
			this.setDate(this.source,inputArray);	
			this.updateDuration();
		}
		else{
			//Check if arrival is set, if so, validate
			if(this.arrival){
				if(!validateDateRange(this.hpCalModel,this.arrival,inputArray)){					
					return false;
				}
			}			
			this.setDate(this.source,inputArray);	
			this.updateDuration();		
		}
		
		if(this.arrival && this.departure){
			if(!validateDateRange(this.hpCalModel,this.arrival,this.departure)){					
				return false;
			}
		}
		
		if(this.options.popup){	
			this.hpCal.hide();
		}
		
		this.clicks = !this.clicks;
		return true;	
	},
	
	
	/**
	 * Gets the date for a particular field
	 **/
	getDate: function(obj){
			
		if(obj == 'arrival' && !this.arrivalField) return false;
		//if(obj == 'departure' && !this.departureField) return false;
		
		if(!obj) return false;		
		var month = $(this.options.reference+obj+'-y-m').value.split('-');	
		var day = $(this.options.reference+obj+'-d').value;
		
		if(day && month[0] && month[1])	return {day: day, month: month[1], year: month[0]};
		else return false;
	},
	
	
	/**
	 * Sets the dates for a particulare field
	 **/
	setDate: function (obj, value){
		
		//Set the day field
		this.setDay(obj, value);
		
		if(value && !validateDate(value, this.options.endDate)) return false;		
		
		//Set arrival or departure date
		if(obj == 'arrival'){			
			this.arrival = value;	
		}else{
			this.departure = value;	
		}
			
		//Validate
		if(this.arrival && this.departure){
			if(!validateDateRange(this.hpCalModel,this.arrival,this.departure)){	
				if(obj == 'arrival') this.arrival = null;
				else this.departure = null;				
				return false;
			}
		}
		
		//Block out dates on cal
		if(obj == 'arrival'){			
			this.hpCalModel.FromDate = value ? value.year+''+value.month+''+value.day : '';	
		}//else{this.hpCalModel.ToDate = value ? value.year+''+value.month+''+value.day : '';	}
		
		if(!value) value = {year: '', month: '', day: ''}		
		
		//Set drop down values
		$(this.options.reference + obj+'-d').value = value.day;
		$(this.options.reference + obj+'-y-m').value = (value.year && value.month) ? value.year+'-'+value.month : '';
		
		//Update calendar
		this.hpCal.__populateMonthView();
		 
		//If not popup & both dates, get price
		if(!this.options.popup && this.arrival && this.departure){
			this.getPrice();
		}
		return true;
	},
	
	/**
	 * Sets the day of the week field
	 **/	
	setDay: function(target, date){
		
		var days = new Array('Sun','Mon','Tues','Wed','Thurs','Fri','Sat')
		if(!date) date = this.getDate(target);
				
		if(!date || !(date.year && date.month && date.day)) return false;
					
		if(date){
			var myDate=new Date(date.year,date.month-1,date.day);
			var day = myDate.getDay();
			$(this.options.reference+target+'-day').set('html',days[day]);
		}
		return true;			
	},
	
	
	updateDate: function(target,e){
		var date = this.getDate(target);		
		if(date){
			if(!this.setDate(target,date)){
				new Event(e).stop();
				return false;
			}
			return this.updateDuration();		
		}		
	},
	
	updateDuration: function(){
		
		var from = this.getDate('arrival');
		//var to = this.getDate('departure');
		var one_day=1000*60*60*24
		
		/*if(from  && this.durationField){//&& to
			
			var fromDate = new Date(from.year,from.month-1,from.day);
			//var toDate = new Date(to.year,to.month-1,to.day);			
			//var offsetValue = Math.ceil((toDate.getTime()-fromDate.getTime())/(one_day));	
			
			//Calculate difference btw the two dates, and convert to days
			//$(this.options.reference+'days-offset').value = offsetValue;		
		
		}else if(from){
			return this.updateDepart();
		}else if(this.durationField){
			$(this.options.reference+'days-offset').value = '';
		}
		*/
		return true;
	},
	
	updateDepart: function(){
		
		var from = this.getDate('arrival');
		var offset = this.durationField ? $(this.options.reference+'days-offset').value : '';
				
		if(from && offset){
			var one_day=1000*60*60*24
			var fromDate = new Date(from.year,from.month-1,from.day);	
							
			var toDate = fromDate;
			toDate.setDate(toDate.getDate() + parseInt(offset));
			
			var day = toDate.getDate();
			day = day < 10 ? '0'+day : day;
			
			var month = toDate.getMonth()+1;
			month = month < 10 ? '0'+month : month;	
								
			var to = {day: day, month: month, year: toDate.getFullYear()}

			if(!validateDateRange(this.hpCalModel, from, to)) return false;
			
			this.setDate('departure',to)	
					
			if(!this.options.popup && this.arrival && this.departure){
				this.getPrice();
			}
		}		
		return true;
	},
	
	validateForm: function(validateDates){
		
		var from = this.getDate('arrival');
		var to = this.getDate('departure');
		validateDates = validateDates ? 1 : 0;

			
		if(from || validateDates){
			if(!validateDate(from, this.options.endDate)){
				return false;
			}
		}
		if(to || validateDates){
			if(!validateDate(to, this.options.endDate)){
				return false;
			}	
		}
		if(from || to){
			if(!validateDateRange(this.hpCalModel, from, to)){
				return false;
			}
		}
		return true;
	},
	
	
	getInvalidDates: function(){

		if(!this.invalidDatesLoaded){
			var self = this;
			new Request.JSON({
				url: "/components/com_hotproperty/includes/calendar/invalidDates.php?propid="+this.options.propRef,
				onComplete: function(data){
					if($chk(data)){
						data.dates.each(function(d){
							self.hpCalModel.addInvalidDateRange({year: d.yearFrom,month: d.monthFrom, day: d.dayFrom},{year: d.yearTo, month: d.monthTo, day: d.dayTo});
						});
						self.hpCal.__populateMonthView();
						self.invalidDatesLoaded = 1;
					}
				}
			}).get();				
		}	
	},
	
	//Ajax function to get the price
	getPrice: function(){
		
		this.arrival = this.getDate('arrival');
		this.departure = this.getDate('departure');
		var arrival = this.arrival.day+'/'+this.arrival.month+'/'+this.arrival.year;
		var departure = this.departure.day+'/'+this.departure.month+'/'+this.departure.year;
		
		if(this.request) this.request.cancel();
		
		var queryString = 'task=totalPrice&startDate='+ arrival +'&endDate='+ departure +'&propRef='+this.options.propRef+'&currency='+this.options.currency;
		
		this.request = 
		new Request({
			url: '/components/com_hotproperty/ajax.php',
			onSuccess: function(responseText, responseXML){				
				
				var xml = responseXML.getElementsByTagName('price');
				var xml2 = responseXML.getElementsByTagName('price_display');
				
				if(xml.length == 0) return this.onFailure({status: 'Empty XML'});
				
				//Get the price and set it for all elements with class .hp_price
				var price = xml2[0].firstChild.data;					
				$('hp_main').getElements('.hp_price').each(function(el){
					el.set('html',price);
				})				
			},
			onFailure: function(xhr){
				unavailable(xhr);
				return false;
			}
		}).send(queryString)
	},
	
	//Resets the form
	clearForm: function(e){	
		new Event(e).stop();
		if(this.request) this.request.cancel();
		this.hpCalModel.initialDay=-1;	
		this.setDate('arrival',null)
		this.setDate('departure',null)
		this.updateDuration();
		this.arrival = null;
		this.departure = null;
		this.clicks = 0;
		this.hpCalModel.FromDate = null;
		this.hpCalModel.ToDate = null;		
		this.hpCal.resetViewDisplayedMonth();
		$('hp_main').getElements('.hp_price').each(function(el){
			el.set('html','');
		})
	}
	
})

//This funciton has to be outside the main class as otherwise the calendar
//tries to call a method within itself if you use "this.getDateFromCalendar" as the call back method
function getDateFromCalendar(inputArray){
	
	var self = inputArray.calendarRef.self;
	self.getDateFromCalendar(inputArray);
}