var Shoppingcart = Class.create({
	
	initialize: function(element) {
		this.element = $(element);
		
		// geen items in de cart, STOPPEN!
		if (!this.element.down('#items')) return;
		
		this.options = Object.extend({
			urls: {
				remove: Katoenenzo.options.webroot + 'shoppingcart/ajax/remove',
				update: Katoenenzo.options.webroot + 'shoppingcart/ajax/update',
				placeorder: Katoenenzo.options.webroot + 'shoppingcart/ajax/placeorder'
			}
		}, arguments[1] || {});
		
		this.items = this.options.items || [];
		this.transports = this.options.transports || [];
		this.selectedTransport = this.options.selectedTransport;
		
		this.startCalculating();
		this.calculate();
		
		this.cart = $('items');
		
		this.startObserving();
		
		if (this.options.userid) {
			this.createSubmitSystem();
		}
	},
	
	
	/*
	 * Create Submit System
	 */
	createSubmitSystem: function() {
		$w('#items .deliverAt .checkout').each(function(i) {
			var item = this.element.down(i);
			
			item.show = function() {
				this.setStyle('position:relative;visibility:visible;top:auto;left:auto;');
				return this;
			};
			item.hide = function() {
				this.setStyle('position:absolute;visibility:hidden;top:-9999px;left:-9999px;');
				return this;
			};
			item.visible = function() {
				return parseInt(this.getStyle('top')) != -9999;
			};
			item.toggle = function() {
				this[this.visible() ? 'hide' : 'show']();
			};
		}.bind(this));
		
		
		this.deliverAt = this.element.down('.deliverAt');
		this.checkout = this.element.down('.checkout');
		
		// OBSERVE
		this.element.down('.placeOrder .next').observe("click", function(event) {
			event.stop();
			this.cart.hide();
			this.deliverAt.show();
		}.bindAsEventListener(this));
		
		this.deliverAt.down('.buttons').observe('click', this.delegateDeliverButtons.bindAsEventListener(this));
		this.checkout.observe('click', this.delegateCheckout.bindAsEventListener(this));
		
	},
	
	/*
	 * Event Delegation
	 * Deliver
	 */
	delegateDeliverButtons: function(event) {
		var element = event.findElement('a');
		if (element) {
			event.stop();
			var prevnext = element.className;
			
			if (prevnext != 'next') {
				this.deliverAt.hide();
				this.cart.show();
			}
			else {
				// controleer form
				this.checkDeliverForm();
			}
		}
	},
	
	/*
	 * Event delegation
	 * Checkout
	 */
	delegateCheckout: function(event) {
		var element = event.findElement('a.previous');
		if (element) {
			event.stop();
			this.checkout.hide();
			this.deliverAt.show();
		}
		
		var element = event.findElement('a.next');
		if (element) {
			event.stop();
			// check algemene voorwaarden
			if (this.generalConditionsAgreed()) {
				this.submitOrder();
			}
		}
		
		var element = event.findElement('#generalConditions');
		if (element) {
			this.setGeneralConditionStatus(element.checked);
		}
	},
	
	/*
	 * General conditions
	 */
	// observe
	
	
	generalConditionsAgreed: function() {
		var checked = $('generalConditions').checked;
		
		// mark bad
		this.setGeneralConditionStatus(checked);
		
		return checked;
	},
	
	setGeneralConditionStatus: function(checked) {
		this.checkout.down('.generalConditions')[(checked ? 'remove' : 'add') + 'ClassName']('bad');
	},
	
	/*
	 * Bezorgadres check
	 * Na deze check word of checkout getoond of een aantal velden rood
	 */
	checkDeliverForm: function() {
		var requiredLabels = this.deliverAt.select("label.required");
		
		
		var errors = 0;
		requiredLabels.each(function(element) {
			var input = element.up('dt').next('dd').down('input');
			if (input) {
				input.removeClassName("bad");
				
				var value = input.value.strip();
				if (!value ||
					(input.getAttribute('name') == 'email' && !(/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/).test(input.value))) {
					input.addClassName("bad");
					errors++;
				}
			}
		});

		if (!errors) {
			requiredLabels.each(function(element) {
				var input = element.up('dt').next('dd').down('input');
				if (input) {
					this.element.down('.'+ input.id + ' .content').update(input.value);
				}
			}.bind(this));
			
			// country
			this.checkout.down('.country .content').update($('country').options[$('country').selectedIndex].label);
			
			// telephone
			var tel = $F('telephone'),
				telephoneCheck = this.checkout.down('.telephone');
			if (tel) {
				telephoneCheck.show().down('.content').update(tel);
			}
			else {
				telephoneCheck.hide();
			}
			
			// opmerkingen
			var tel = $F('notes'),
			notesCheck = this.checkout.down('.notes');
			if (tel) {
				notesCheck.show().down('.content').update(tel);
			}
			else {
				notesCheck.hide();
			}
			
			this.deliverAt.hide();
			this.checkout.show();
		}
	},
	
	
	
	/*
	 * Disable alle submit buttons zodat we maar 1x submitten
	 */
	disableSubmits: function() {
		// stop observing both submit buttons and the back button
		this.checkout.select('a.next, a.previous')
			.invoke('stopObserving')
			.invoke('writeAttribute', { href: 'javascript:;' });
	},
	

	/*
	 * Submi bestelling
	 */
	submitOrder: function() {
		// AJAX Bestelling
		this.ajaxSubmit('none', function(orderID) {
			window.location.href = Katoenenzo.options.webroot + 'orders/order/' + orderID 
		}.bind(this));
	},
	
	
	/*
	 * Ajax submit
	 */
	ajaxSubmit: function(paymentMethod, callback) {
		// disable submits
		this.disableSubmits();
		
		new Ajax.Request(this.options.urls.placeorder, {
			parameters: Object.extend($('deliverForm').serialize(true), {
				userid: this.options.userid,
				sessionid: this.options.sessionid,	
				transportid: this.selectedTransport,
				paymentmethod: paymentMethod
			}),
			
			onComplete: function(response) {
				callback(response.responseText);
			}
		});
		
	},
	
	/*
	 * Observe
	 */
	startObserving: function() {
		this.element.observe('click', this.delegateClick.bindAsEventListener(this));
		
		this.element.down('select[name=transport]').observe('change', this.changeTransport.bindAsEventListener(this));
		
		//this.element.select('li.amount').invoke('observe', 'keyup', this.updateItemAmount.bindAsEventListener(this));
	},
	
	delegateClick: function(event) {
		var element = event.findElement('a.deleteButton');

		if (element) {
			event.stop();
			var item = element.up('.item'),
				number = ((/_([0-9]+)*$/.exec(item.id) || [null, null])[1]);
			this.remove(number, element);			
		}
		
		var element = event.findElement('li.amount input[type=button]');
		if (element) {
			this.updateItemAmount(event);
			element.blur();
		}
	},
	
	changeTransport: function(event) {
		var element = event.findElement('select');
		this.selectedTransport = element.options[element.selectedIndex].value;
	},
	
	getSelectedTransportPrice: function() {
		return this.transports.find(function(i) { return i.id == this.selectedTransport }).price;
	},
	
	updateItemAmount: function(event) {
		var element = event.findElement('input'),
			plusminus = element.className,
			id = ((/_([0-9]+)*$/.exec(element.up('.item').id) || [null, null])[1]);
		var item = this.items.find(function(i) { return i.id == id });
		
		// NOOIT 0
		if (item.amount == 1 && plusminus == 'minus') return;
		
		// disable inputs
		element.up('.amount').select('input').invoke('disable');
		
		// set loading image
		var amountValue = element.up('.amount').down('span.value');
		amountValue.addClassName('loading');
		
		// update array
		var singleItemPrice = item.price / item.amount;
		item.amount += (plusminus == 'plus') ? 1 : -1;
		item.price = (item.amount * singleItemPrice);
		
		new Ajax.Request(this.options.urls.update, {
			parameters: {
				id: id,
				price: item.price,
				amount: item.amount
			},
			onComplete: function() {
				// update amount/loading
				amountValue.removeClassName('loading').update(parseInt(item.amount));
				
				// NIEUWE PRIJS IN SPAN IS DE EXCL PRIJS
				var priceExclBTW = ((item.price / (100 + this.options.VAT)) * 100).toFixed(2);
				element.up('.item').down('.price .value').update(priceExclBTW);
				
				// enable inputs
				element.up('.amount').select('input').invoke('enable');
			}.bind(this)
		});
	},
	
	getCalculateObject: function() {
		var subTotal = 0;
		this.items.each(function(item) {
			subTotal += ((item.price / (100 + this.options.VAT)) * 100);
		}.bind(this));
		
		var transport = this.transports.find(function(t) { return t.id == this.selectedTransport}.bind(this)).price;
		
		var totalExclVAT = subTotal + transport;
		var totalVAT = (totalExclVAT / 100) * this.options.VAT;
		var totalInclVAT = totalExclVAT + totalVAT;
		
		return {
			subTotal: (subTotal).toFixed(2),
			transport: (transport).toFixed(2),
			totalExclVAT: (totalExclVAT).toFixed(2),
			totalVAT: (totalVAT).toFixed(2),
			totalInclVAT: (totalInclVAT).toFixed(2)
		};
	},
	
	/*
	 * Prijs berekening
	 */
	
	startCalculating: function() {
		$w('updateItemAmount changeTransport remove').each(function(fn) {
			this[fn] = this[fn].wrap(function(proceed, event, element) {
				proceed(event, element);
				this.calculate();
			}.bind(this));
		}.bind(this));
	},
	
	calculate: function() {
		var calc = this.getCalculateObject();
		
		this.element.down('li.subTotal .value').update(calc.subTotal);
		this.element.down('li.totalExclVAT .value').update(calc.totalExclVAT );
		this.element.down('li.totalVAT .value').update(calc.totalVAT );
		this.element.down('li.totalInclVAT .value').update(calc.totalInclVAT);
	},
	
	remove: function(id, element) {
		var item = element.up('.item');
		element.remove();
		
		// disable inputs (-+)
		item.select('.amount input').invoke('disable');
		
		new Ajax.Request(this.options.urls.remove, {
			parameters: {
				id: id
			},
			onComplete: function() {
				item.remove();
				var removeItem = this.items.find(function(i) { return i.id == id });
				
				this.items = this.items.without(removeItem);
				if (!this.items.length) {
					$('items').hide();
					$('noItems').show();
				}
			}.bind(this)
		});
	}
	
	
});
