Cart = {
	/* whether Cart.init() has already been called */
	initialized: false,
	/* articles in the cart */
	list: [],
	/**
	 * Open a "modal" window with Cart UI
	 */
	openEditor: function() {
		var w = Util.window("cart-ui", 800, 600);
		w.show();
		new Ext.Updater('cart-ui-table').update({url: Rx.WWWDIR+"cart-table.php"});
	},
	/**
	 * add item 
	 * @param DOMNode trigger the trigger that has been clicked to invoke action
	 * @param int id
	 */
	add: function(trigger, id, price, relocate) {
		if (false === Cart.contains(id))
		{
			if (! Cart.list.length)
			{
				Cart.chooseDefaultShippingMethod();
			}
			Cart.list.push({"id": id, "order_quantity": 1});
			Cart.loadPackPrice(id);
			Cart.store();
			trigger.innerHTML = "Ok";
			trigger.onclick = function(){return false;};
			Cart.updateStatus(price, 1);
		}
		
		if ((arguments.length > 3) && relocate) {
			location.href = trigger.getAttribute('href');
		}
		
		return true;
	},
	/**
	 * remove item
	 * @param int id
	 */
	remove: function(id, price, quantity) {
		
		var index = Cart.contains(id);
		
		if (false !== index)
		{
			var newList = [];
			for (var i = 0; i < Cart.list.length; ++i)
			{
				if (i != index)
				{
					newList.push(Cart.list[i]);
				}
			}
			
			Cart.updateQuantityMarker(id, 0);
			
			// remove table row
			var tr = document.getElementById('row-' + id);
			tr.parentNode.removeChild(tr);
			
			Cart.updateStatus(price, -Cart.list[index].order_quantity);
			
			Cart.list = newList;
			Cart.store();
			
			return true;
		}
		
		return false;
	},
	updateStatus: function(price, quantityDiff) {
		price *= quantityDiff;
		var priceEl = document.getElementById('total-price');
		if (priceEl)
		{
			var currPrice = parseFloat(priceEl.innerHTML);
			var priceText = Cart.round(currPrice + price);
			priceEl.innerHTML = priceText;
		}
		var countEl = document.getElementById('total-count');
		if (countEl) {
			var currCount = parseInt(countEl.innerHTML);
			countEl.innerHTML = currCount + quantityDiff;
		}
		
		var modalWinPriceEl = document.getElementById('total-price-modal');
		if (modalWinPriceEl) modalWinPriceEl.innerHTML = priceText;
		
		var totalPriceWithShippingEl = document.getElementById('total-price-with-shipping');
		if (totalPriceWithShippingEl)
		{
			var totalPriceWithShipping = parseFloat(totalPriceWithShippingEl.innerHTML);
			totalPriceWithShipping += price;
			totalPriceWithShippingEl.innerHTML = Cart.round(totalPriceWithShipping);
		}
	},
	updateQuantityMarker: function(id, quantity)
	{
		var marker = document.getElementById('quantity-marker' + id);
		if (marker)
		{
			marker.innerHTML = quantity;
		}
	},
	updateShipping: function(id, price)
	{
		Util.setCookie('shipping', id, 90);
		Cart.updateShippingStatus(price);
		if (document.getElementById('checkout-shipping'))
		{
			location.reload();
		}
	},
	updateShippingStatus: function(price)
	{
		var shippingPriceEl = document.getElementById('shipping-price');
		var currShippingPrice = parseFloat(shippingPriceEl.innerHTML);
		
		shippingPriceEl.innerHTML = Cart.round(price);
		
		var totalPriceWithShippingEl = document.getElementById('total-price-with-shipping');
		if (totalPriceWithShippingEl)
		{// @todo: this code duplicates in updateStatus
			var totalPriceWithShipping = parseFloat(totalPriceWithShippingEl.innerHTML);
			totalPriceWithShipping -= currShippingPrice;
			totalPriceWithShipping += price;
			totalPriceWithShippingEl.innerHTML = Cart.round(totalPriceWithShipping);
		}
	},
	/**
	 * Clear cart
	 */
	clear: function(confirm) {
		confirm = arguments.length ? confirm : true;
		if (confirm && window.confirm("Please confirm order removal"))
		{
			Cart.list = [];
			Cart.store();
		}
	},
	/**
	 * Set order-quantity for a given product
	 */
	setQuantity: function(id) {
		var index = Cart.contains(id);
		if (false === index)
		{
			return false;
		}
		
		var input = document.getElementById('quantity' + id);
		var q = parseFloat(input.value);
		if (isNaN(q) || (q <= 0))
		{
			q = 1;
		}
		q = Math.round(q);
		input.value = q;
		
		Cart.updateQuantityMarker(id, q);
		
		var subtotal = Cart.round(q * Cart.list[index].price_per_pack);
		document.getElementById('subtotal' + id).innerHTML = Cart.round(q * Cart.list[index].price_per_pack);
		
		var quantityDiff = q - Cart.list[index].order_quantity;
		
		Cart.list[index].order_quantity = q;
		Cart.list[index].subtotal = subtotal;
		Cart.store();
		Cart.updateStatus(Cart.list[index].price_per_pack, quantityDiff);
	},
	/**
	 * Initialize.
	 */
	init: function(list) {
		Cart.list = list;
	},
	/**
	 * Whether the cart contains article id
	 * @param int id
	 * @return int found element index or bool FALSE if not found
	 */
	contains: function(id) {
		
		for (var i = 0; i < Cart.list.length; ++i)
		{
			if (id == Cart.list[i].id)
			{
				return i;
			}
		}
		
		return false;
	},
	/**
	 * Store current cart state
	 */
	store: function()
	{
		if (0 == Cart.list.length) 
		{
			Util.delCookie('cart');
			Cart.updateShipping(0, 0);
			return ;
		}
		var pairs = [];
		for (var i = 0; i < Cart.list.length; ++i)
		{
			pairs.push(Cart.list[i].id + ":" + Cart.list[i].order_quantity);
		}
		Util.setCookie('cart', pairs.join(","), 90);
	},
	loadPackPrice: function(id) {
		new Ext.data.Connection().request({
			url: Rx.WWWDIR + "get-pack-price.php?id=" + id,
			success: function(r){
				var index = Cart.contains(id);
				if (index) {
					var ppp = parseFloat(r.responseText);
					if ((! isNaN(ppp)) && ppp > 0)
					{
						Cart.list[index].price_per_pack = Cart.round(ppp);
					}
				}
			},
			failure: function(r){
				o=[]
				for (i in r){o.push(i);}
				alert(o.join(', '))
				alert("response1: \n"+r.status+"\n"+r.responseText+"\n"+'An error has occured. The page will be reloaded.');
				location.reload();
			}
		});
	},
	chooseDefaultShippingMethod: function() {
		new Ext.data.Connection().request({
			url: Rx.WWWDIR + "get-default-shipping.php",
			success: function(r){
				try {
					eval('var json = (' + r.responseText + ')');
					Cart.updateShipping(json.id, json.price);
				} catch (e) {
					alert("response2: \n"+r.responseText+"\n"+'An error has occured. The page will be reloaded.');
					location.reload();
				}
			},
			failure: function(r){
				alert("response3: \n"+r.responseText+"\n"+'An error has occured. The page will be reloaded.');
				location.reload();
			}
		});
	},
	onOrderSubmit: function(data)
	{
		jdom("success-message-text").innerHTML = data;
		jdom.show("success-message");
	},
	preventEditorOpening: function()
	{
		Cart.openEditor = function(){};
	},
	/**
	 * A utility function
	 */
	round: function(floatval)
	{
		return Math.round(floatval * 100) / 100;
	}
}
