/**
 * Regexes
 * 
 */
var parentNameToIDRE = /\d*$/;
/**
 * Selectors
 */
var s_cartTotalID = '#cart_total';
/**
 * Data
 */
var selectedExtras = [];
var originalTotal = 0;

/**
 * Deals with booking/confirm 
 */
function Cart() {
	
	// selectors
	this.s_cartID = '#cart';
	this.s_bookingClass = '.booking';
	this.s_cartTotal = '#cart_total';
	
	// data
	this.bookings = [];
	this.total    = [];
	this.actions;
	this.values;
	
	this.initCart = function(actions,values) {
		
		this.actions = actions;
		this.values = values;
		
		var cart = this;
		// store all bookings
		$(this.s_cartID).find(this.s_bookingClass).each(function(){
			var booking = new Booking($(this),cart);
			cart.bookings.push(booking);
			booking.total();
		});
		
		this.setValue(this.totalUpBookings());
		
	}
	this.totalUpBookings = function() {
		var total = 0;
		for (i = 0; i < this.bookings.length; i++) {
			total += Number(this.bookings[i].total());
		};
		this.setValue(total);
		return total;
	}
	this.cartTotal = function() {
		
	}
	this.setValue = function(value) {
		$(this.s_cartTotal).html(this.format(value));
	}
	/**
	 * Formats all money data for cart
	 */
	this.format = function(value) {
		return Number(value).toFixed(2);
	}
}

function Booking(bookingElement,cart) {
	
	// elements
	this.ele = bookingElement;
	
	// selectors
	this.s_mealTotal = '.meal_total_value';
	this.s_nights    = '.cart_nights li';
	this.s_extras = '.extras';
	this.s_checkboxes = '.booking_extra_checkbox';
	this.s_dropdowns = '.booking_extra_dropdown';
	this.s_total = '.booking_total_value';
	this.s_totalDiscount = '.offer_value_total';
	
	// data
	this.mealsTotal = 0;
	this.extrasTotal = 0;
	this.nightsTotal = 0;
	this.bookingTotal = 0;
	
	
	// cart
	this.cart = cart;
	
	/**
	 * Generates total for booking
	 */
	this.total = function() {
		this.bookingTotal = (this.totalNights() + this.totalExtras() + this.totalMeals()) - this.totalDiscount();
		this.updateView();
		return this.bookingTotal;
	}
	/**
	 * Returns total nights; doesn't change after initial
	 */
	this.totalNights = function() {
		if(this.nightsTotal) return this.nightsTotal;
		var total =0;
		this.ele.find(this.s_nights).each(function(){
			total += Number($(this).attr('cartvalue'));
		})
		this.nightsTotal = total;
		
		return Number(total);
	}
	/**
	 * Returns total nights; doesn't change after initial
	 */
	this.totalMeals = function(){
		if (this.mealsTotal) {
				return this.mealsTotal;
		}
		
		
		if (this.ele.find(this.s_mealTotal).length == 0) {
			return 0;
		} 
		
		var val = this.ele.find(this.s_mealTotal).eq(0).html();
		
		this.mealsTotal = Number(val);
		
		if(val) {
			val = val.replace(/,/,'');
			return Number(val);
		} else {
			return 0;
		}
		
	}
	/**
	 * Returns total extras
	 */
	this.totalExtras = function() {
		// total checkboxes
		var total = 0;
		
		var booking = this;
		
		this.ele.find(this.s_extras + ' ' + this.s_checkboxes + ':checked').each(function(){
			var id = $(this).val();
			total += booking.getExtraValue(id);
		});
		
		this.ele.find(this.s_extras + ' ' + this.s_dropdowns + ' option:selected').each(function(){
			var id = $(this).val();
			if(id ==0 ) {
				
			} else {
				total += booking.getExtraValue(id);
			}
		});
		return Number(total);
	}
	this.totalDiscount = function() {
		if(this.discountTotal) {
			return this.discountTotal;
		}
		var val = this.ele.find(this.s_totalDiscount).eq(0).html();
		if(val) {
			val = val.replace(/,/,'');
			return Number(val);
		} else {
			return 0;
		}
	}
	this.updateView = function() {
		this.ele.find(this.s_total).html(this.cart.format(this.bookingTotal));
	}
	/**
	 * Calculates the value of an extra for a booking
	 */
	this.getExtraValue = function(extraID) {
		var bookingNightsTotal = this.totalNights();
		var val = 0;

		switch(this.cart.actions[extraID]) {
			case 'fixed':
				val = Number(this.cart.values[extraID]);
			break;
			case 'free':
				val = 0;
			break;
			case 'percent':
				val = (Number(this.cart.values[extraID]) / 100) * bookingNightsTotal;
			break;
		}
		return val;
		//alert('extra id ' + extraID + ' total ' + val + ' action ' + this.cart.actions[Number(extraID)]);
	}
}

/**
 * Listeners etc
 */
var cart;
$(document).ready(function() {
	/** 
	 * Date picker functions
	 */
	$.datepicker.setDefaults({ dateFormat: 'dd MM yy', minDate: new Date() });
	/**
	 * Default - if there is another datepicker after this one in the form
	 * with the name '_from$', set up the default and set the from date
	 * as the minimum
	 * @param {Object} dateText
	 * @param {Object} inst
	 */
	$('.datePick').datepicker({
		onSelect: function(dateText, inst){
			if(/_from$/.test($(this).attr('name'))) {
				// get parent form
				// and find next datepicker until
				var until = $(this).nextAll('.datePick[name$=until]:first').eq(0);
				if (until) {
					// set up defaults - two day stay, with
					// min allowed the from date
					var newFromDate = $(this).datepicker('getDate');
					var dayStaySecs = 86400 * 1000;
					
					var minUntil = newFromDate.getTime() + dayStaySecs;
					var defaultUntil = newFromDate.getTime() + (dayStaySecs * 2);
					
					var minUntilDate = new Date(minUntil);
					var defaultStayDate = new Date(defaultUntil);
					
					until.datepicker('setDate', defaultStayDate);
					until.datepicker('option', 'minDate', minUntilDate);
				}
			}
		}
	});
	
	$('.booking_extra_checkbox').change(function() {
		cart.totalUpBookings();
	});
	$('.booking_extra_dropdown').change(function() {
		cart.totalUpBookings();
	});
	$('.checkbox_all_toggle').change(function() {
		var selected = $(this).val();
		$(this).siblings('input').each(function(){
			$(this).attr('checked',selected);
		});
	});
	$('.checkbox_none_toggle').click(function() {
		$(this).siblings('input').each(function(){
			$(this).attr('checked',false);
		});
		return false;
	});
	
	/**
	 * Availability data
	 */
	// normal room row, change room type
	$('.availability_list_room .room_options input:radio').click(function(){
		var id = $(this).val();
		var group = $(this).parents('.availability_list_room');
		// update bydate pricing
		group.find('.room_price').html($('#roomPriceData #date_price_' + id).html());
		// update total row
		totalGroup(group);
	});
	// update offer values
	$('.availability_list_offer .room_options input:radio').click(function(){
		var id = $(this).val();
		var offerRow =  $(this).parents('.availability_list_offer');
		setDiscount(id,offerRow);
		totalGroup(offerRow);
	});
	// update row to reflect change room pricing
	$('.availability_list_room .meal_options input:radio').click(function(){
		var group = $(this).parents('.availability_list_room');
		totalGroup(group);
	});
	
	// initialise values (in case browser remembers a selection that PHP is ignorant of)
	$('.availability_list_room .room_options input:radio:checked').each(function() {
		var id = $(this).val();
		var group = $(this).parents('.availability_list_room');
		group.find('.room_price').html($('#roomPriceData #date_price_' + id).html());
	});	
	$('.availability_list_offer .room_options input:radio:checked').each(function() {
		var id = $(this).val();
		var offerRow =  $(this).parents('.availability_list_offer');
		setDiscount(id,offerRow);
	});
	
	$('.availability_list_room').each(function() {
		totalGroup($(this));
	})
	
	if(baseValuesByID && actionsByID) {
		cart = new Cart();
		cart.initCart(actionsByID,baseValuesByID);
	}
	
	
});
function setDiscount(roomID,offerRow) {
	var offerID = offerRow.find('.offer_id').eq(0).html();
	var offerDiscountEleID = '#offer_room_' + offerID + '_' + roomID;
	var discount = $(offerDiscountEleID).html();
	offerRow.find('.booking_offer_total .total_numeric').html(Number(discount).toFixed(2));
}
/**
 * Gets the total of an .availability_list_room; meals + room
 * @param {jQuery Object} group
 */
function totalGroup(group) {
	var total =0;
	var mealVarRE = /[\d\.]^/; 
	group.find('.room_price .price').each(function() {
		total += Number($(this).html());
	});
	group.find('.meal_options input:checked').each(function() {
		var label = $(this).prev().html();
		var val = /[\d\.]*$/.exec(label);
		total += Number(val);
	});
	var discountTotal = Number(group.find('.booking_offer_total .total_numeric').html());
	if(discountTotal) {
		total-= discountTotal;
	}
	group.find('.booking_total .total_numeric').html(Number(total).toFixed(2));
}

