/**
 * Configurator.js - Product configurator
 * 
 * @author Webstores <info at webstores dot nl>
 *         Copyright (c) Webstores internet totaalbureau <http://www.webstores.nl/>
 */
function Configurator(form, options) {
	this.form = $(form);
	this.options = options;
	this.construct();
};

Configurator.prototype = {
	/**
	 * @constructor
	 */
	construct: function() {
		if(this.form.length) {
			this.options = $.extend({
				priceUrl: '/webshop/price',
				selectedClass: 'selected'
			}, this.options || {});
			
			this.form.addClass('js');
			
			this.addFormElementsEventHandler();
			this.createQuantityFields();
			this.colorClickHandler();
			this.clothClickHandler();
		}
	},
	
	/**
	 * Create the width/height quantity fields
	 */
	createQuantityFields: function() {
		var self = this;
		
		$('.quantity-input', this.form).each(function() {
			new QuantityField(this, {
				min: parseInt($(this).attr('data-min'), 10) || 0,
				max: parseInt($(this).attr('data-max'), 10) || 0,
				step: 0.5,
				updateDelay: 250,
				onUpdate: function() {
					self.sendRequest();
				}
			});
		});
	},
	
	/**
	 * When a color label fires onclick
	 */
	colorClickHandler: function() {
		var self = this;
		
		$('.product-colors .color', this.form).click(function() {
			$('.product-colors .' + self.options.selectedClass).removeClass(self.options.selectedClass);
			self.setColor(this);
			$(this).parents('li').addClass(self.options.selectedClass);
		});
	},
	
	/**
	 * When a cloth label fires onclick
	 */
	clothClickHandler: function() {
		var self = this;
		
		$('.cloth-list .cloth', this.form).click(function() {
			$('.cloth-list .' + self.options.selectedClass).removeClass(self.options.selectedClass);
			self.setCloth(this);
			$(this).parents('li').addClass(self.options.selectedClass);
		});
	},
	
	/**
	 * Sets the current color
	 * 
	 * @param {Object} el The HTMLLabelElement
	 */
	setColor: function(el) {
		$('#current-color .color', this.form).css('backgroundColor', $(el).css('backgroundColor'));
		$('#current-color .definition', this.form).text(el.title);
	},
	
	/**
	 * Sets the cloth's preview image and title
	 * 
	 * @param {Object} el The HTMLLabelElement
	 */
	setCloth: function(el) {
		$('#current-cloth .thumb img').attr('src', $(el).attr('data-preview'));
		$('#current-cloth .sub', this.form).text(el.title);
	},
	
	/**
	 * Adds an event handler to all form elements
	 * 
	 * @param {Function} handler The handler to call when the event type fires
	 */
	addFormElementsEventHandler: function(handler) {
		var eventType;
		var self = this;
		
		$(':input', this.form).not('.quantity-input').each(function() {
			var eventType = '';
			
			if(this.name) {
				switch(this.nodeName) {
					case 'INPUT':
						switch(this.type) {
							case 'text':
								eventType = 'keyup';
								break;
							case 'radio':
							case 'checkbox':
								eventType = 'click';
								break;
						}
						break;
					case 'TEXTAREA':
						eventType = 'keyup';
						break;
					case 'SELECT':
						eventType = 'change';
						break;
				}
			}
			
			if(eventType) {
				$(this).bind(eventType, function() {
					self.sendRequest();
				});
			}
		});
	},
	
	/**
	 * Sends an HTTP request to get updated totals
	 */
	sendRequest: function() {
		var self = this;
		
		$.ajax({
			url: self.options.priceUrl,
			cache: false,
			dataType: 'json',
			type: 'POST',
			data: self.form.serialize(),
			success: function(data) {
				self.updatePrices(data);
			}
		});
	},
	
	/**
	 * Update prices
	 * 
	 * JSON:
	 * - type:  The type of price, e.g.:
	 *          "size": for the size price
	 *          "cart": for cart items
	 * - title: The title of a cart item
	 * - price: The price as string, with a Euro sign
	 *          as HTML entity
	 * 
	 * @param {Object} data The JSON response
	 */
	updatePrices: function(data) {
		/*
		 * JSON
		 * 
			{
				"success": 1,
				"prices": [
					{
						"type": "size",
						"price": "&euro; 2520,00"
					},
					{
						"type": "cart",
						"title": "Meerprijs formaat",
						"price": "&euro; 320,00"
					},
					{
						"type": "cart",
						"title": "Volant",
						"price": "&euro 10,00"
					},
					{
						"type": "cart",
						"title": "Slingerstand bediening buiten",
						"price": "&euro 89,00"
					}
				],
				"grandTotal": "&euro; 2629,00"
			}
			
			or, on error:
			
			{
				"success": 0,
				"message": "Ongeldige combinatie"
			}
		 */
		
		if(data.success) {
			this.resetCart();
			
			for(var i = 0; i < data.prices.length; i++) {
				switch(data.prices[i].type) {
					case 'size':
						$('.size-price').html(data.prices[i].price);
						break;
					case 'cart':
						this.addCartItem(data.prices[i].title, data.prices[i].price);
						break;
				}
			}
			
			$('#cart-small-total').html(data.grandTotal);
		}
		else {
			$('#step-toolbar button[type="submit"], #cart-small button[type="submit"]').attr('disabled', true);
			$('#cart-small .size-price, #cart-small-total ').text('-');
			$('#product-compile .step .size-price').html(data.message);
		}
	},
	
	/**
	 * Adds an item to the cart
	 * 
	 * @param {String} title The title of the cart item
	 * @param {String} price The cart item's price
	 */
	addCartItem: function(title, price) {
		$('#cart-small .cart-products').append('<li class="dynamic"><span class="description">' + title + '</span><span class="price">' + price + '</span></li>');
	},
	
	/**
	 * Reset the cart (enable submit button and remove dynamic cart items)
	 */
	resetCart: function() {
		$('#step-toolbar button[type="submit"], #cart-small button[type="submit"]').attr('disabled', false);
		$('#cart-small .dynamic').remove();
	}
};

