/**
 * Checkout.js - Checkout functionality
 * 
 * @param {Mixed} form Selector or reference of the checkout form
 * @param {Object} options Optional parameters
 */
function CheckoutForm(form) {
	this.form = $(form);
	this.updateTimeout = null;
	this.init();
};

CheckoutForm.prototype = {
	/**
	 * Initialize
	 */
	init: function() {
		if(this.form.length) {
			switch(this.form.attr('name')) {
				case 'checkoutCart':
					this.initCart();
					break;
				case 'checkoutPersonalDetails':
					this.initPersonalDetails();
					break;
				case 'checkoutShippingPayment':
					this.initShippingPayment();
					break;
			}
		}
	},
	
	/**
	 * Initialize cart
	 */
	initCart: function() {
		var self = this;
		
		$('.validation-icon, #recalculate').hide();
		
		this.form.find('.spinner-input').each(function() {
			new Spinner(this, {
				min: 1,
				updateDelay: 250,
				onUpdate: function() {
					self.sendUpdateRequest();
				}
			});
		});
		
		this.form.find('#checkout-gift-wrap').click(function() {
			self.sendUpdateRequest();
		});
		
		this.form.find('#checkout-coupon-code').keyup(function() {
			self.clearTimeout(self.updateTimeout);
			
			if(this.value.length > 3) {
				self.updateTimeout = setTimeout(function() {
					self.sendUpdateRequest();
				}, 1000);
			}
		});
	},
	
	/**
	 * Initialize personal details
	 */
	initPersonalDetails: function() {
		var self = this;
		
		if(!this.form.find('input[name="altShippingAddress"]').is(':checked')) {
			this.collapse($('#alt-shipping-address'));
		}
		
		this.form.find('input[name="altShippingAddress"]').click(function() {
			self.altShippingAddressClickHandler(this);
		});
	},
	
	/**
	 * Initialize shipment
	 */
	initShippingPayment: function() {
		var self = this;
		
		this.form.find(':checked').parents('.option').each(function() {
			self.optionClickHandler(this);
		});
		
		this.form.find('.option').click(function() {
			self.optionClickHandler(this);
		});
	},
	
	/**
	 * When the alt shipping address checkbox fires onclick
	 * 
	 * @param {Object} el The HTMLInputElement
	 */
	altShippingAddressClickHandler: function(el) {
		$(el).is(':checked') ? this.expand('#alt-shipping-address') : this.collapse('#alt-shipping-address');
	},
	
	/**
	 * When a shipping- or payment method option fires onclick
	 * 
	 * @param {Object} el The option HTMLElement
	 */
	optionClickHandler: function(el) {
		var el = $(el);
		el.siblings('.option').removeClass('selected');
		el.addClass('selected').find('input[type="radio"]').attr('checked', true);
		el.parents('.options').removeClass('error');
	},
	
	/**
	 * Collapse element
	 * 
	 * @param {Object} el The element to collapse
	 */
	collapse: function(el) {
		$(el).removeClass('expanded').addClass('collapsed');
		this.toggleFormElementsByParent(el, true);
	},
	
	/**
	 * Expand element
	 * 
	 * @param {Object} el The element to expand
	 */
	expand: function(el) {
		$(el).removeClass('collapsed').addClass('expanded');
		this.toggleFormElementsByParent(el, false);
	},
	
	/**
	 * Toggle a form element
	 * 
	 * @param {Object} el The HTMLElement
	 * @param {Boolean} toggle True to enable the form element, false to disable
	 */
	toggleFormElement: function(el, toggle) {
		if(typeof toggle === "boolean") {
			el.disabled = toggle;
		}
		else {
			el.disabled = el.disabled ? false : true;
		}
	},
	
	/**
	 * Toggle form elements inside a parent element
	 * 
	 * @param {Object} parent The HTMLElement
	 * @param {Boolean} toggle True to enable the form element, false to disable
	 */
	toggleFormElementsByParent: function(parent, toggle) {
		var self = this;
		
		$(parent).find(':input').each(function() {
			self.toggleFormElement(this, toggle);
		});
	},
	
	/**
	 * Request updated data
	 */
	sendUpdateRequest: function() {
		var self = this;
		
		$.ajax({
			url: self.form.action,
			cache: false,
			dataType: 'json',
			type: 'POST',
			data: self.form.serialize(),
			success: function(data) {
				self.updateCart(data);
			}
		});
	},
	
	/**
	 * Update the cart
	 * 
	 * @param {Object} data The updated data in JSON format
	 */
	updateCart: function(data) {
		/*
		 * JSON:
		 * 
			{
				"itemSubtotals": [
					{
						"itemId": 0,
						"subtotal": "&euro; 118,00"
					},
					{
						"itemId": 1,
						"subtotal": "&euro; 25,90"
					},
					{
						"itemId": 2,
						"subtotal": "&euro; 73,50"
					}
				],
				"cartOptions": [
					{
						"optionId": 0,
						"subtotal": "&euro; 2,50"
					},
					{
						"optionId": 1,
						"valid": true,
						"subtotal": "&euro; -40,00"
					}
				],
				"subtotal": "&euro; 217,40",
				"vat": "&euro; 51,00",
				"grandTotal" : "&euro; 268,40"
			}
		 */
		
		for(var i = 0; i < data.itemSubtotals.length; i++) {
			$('#cart-item-' + data.itemSubtotals[i].itemId + ' .total').html(data.itemSubtotals[i].subtotal);
		}
		
		if(data.cartOptions) {
			for(var i = 0, cartOption = null; i < data.cartOptions.length; i++) {
				cartOption = $('#cart-option-' + data.cartOptions[i].optionId);
				cartOption.find('.total').html(data.cartOptions[i].subtotal);
				cartOption.toggleClass('valid', !!data.cartOptions[i].valid);
			}
		}
		
		$('#checkout-subtotal .total').html(data.subtotal);
		$('#checkout-vat .total').html(data.vat);
		$('#checkout-grand-total .total').html(data.grandTotal);
	},
	
	/**
	 * Clear a timeout
	 * 
	 * @param {Number} timeout The ID of the timeout to clear
	 */
	clearTimeout: function(timeout) {
		if(timeout != null) {
			clearTimeout(timeout);
			timeout = null;
		}
	}
};
