var Cart = Class.create();

Cart.prototype = {
	initialize: function()
	{
		this.cart_items = new Hash();
		
		this.personal_information = null;
		this.delivery = null;
		this.registered_cart_displays = [];
		
		this.ajax = new AjaxController();
		
		this.event_listeners = {'pushed':[], 'pulled':[]};
		
	},
	_restructureCartItems: function(server_cart_items)
	{
		var cart_items = new Hash();
		Object.keys(server_cart_items).each( function(product_record_id, product_record_id_index)
		{
			if ( product_record_id != 'length' )
			{
				var cart_item = new CartItem(this, server_cart_items[product_record_id].product_record);
					cart_item.qty = parseInt(server_cart_items[product_record_id].qty);
					cart_item.price = parseFloat(server_cart_items[product_record_id].product_record.Product.selling_price);
				
				cart_items.set(product_record_id, cart_item);	
			}
			
		}.bind(this));
		
		return cart_items;
		
	},
	pushToServer: function()
	{
		// Mini function pack cart items
		var cart_item_pairs = function()
		{
			var cart_item_pairs = {};
			this.cart_items.each( function(cart_item_hash, cart_item_hash_index)
			{
				cart_item_pairs[cart_item_hash.key] = {
					qty: cart_item_hash.value.qty
				}
			}.bind(this));
			return cart_item_pairs;
			
		}.bind(this);
		
		var data = "data[cart_item_pairs]="+escape(YAHOO.lang.JSON.stringify(cart_item_pairs()));
		
		var callback = {
			success: function(o)
			{
				var ajax_response = YAHOO.lang.JSON.parse(o.responseText);
				this.cart_items = this._restructureCartItems(ajax_response.cart.server_cart_items);
				this.personal_information = ajax_response.cart.personal_information;
				this.delivery = ajax_response.cart.delivery;
				
				// Redraw all cart_displays
				this.registered_cart_displays.each( function(cart_display, cart_display_index)
				{
					cart_display.render();
					
				}.bind(this));
				
				this.event_listeners.pushed.each( function(func, func_index){
					func();
				});
				
			}.bind(this)
		}
		
		this.ajax.request('POST', '/jx/sync_cart/push', callback, data);
	},
	pullFromServer: function()
	{
		var data = "data[empty]="+escape('');
		
		var callback = {
			success: function(o)
			{
				var ajax_response = YAHOO.lang.JSON.parse(o.responseText);
				this.cart_items = this._restructureCartItems(ajax_response.cart.server_cart_items);
				this.personal_information = ajax_response.cart.personal_information;
				this.delivery = ajax_response.cart.delivery;
				
				// Redraw all cart_displays
				this.registered_cart_displays.each( function(cart_display, cart_display_index)
				{
					cart_display.render();
					
				}.bind(this));
				
				this.event_listeners.pulled.each( function(func, func_index){
					func();
				});
				
			}.bind(this)
		}
		
		this.ajax.request('POST', '/jx/sync_cart/pull', callback, data);
	},
	addProduct: function(product_record, optional_qty)
	{
		var cart_item = this.getProduct(product_record.Product.id);
		if ( Object.isUndefined(cart_item) )
		{
			var new_cart_item = new CartItem(this, product_record);
			if ( !Object.isUndefined(optional_qty) )
			{
				new_cart_item.qty = optional_qty;
			}
			
			this.cart_items.set(product_record.Product.id, new_cart_item);
			cart_item = new_cart_item;
			
			this.pushToServer();
		}
		
		return cart_item;
	},
	removeProduct: function(product_record_id)
	{
		var cart_item = this.getProduct(product_record_id);
		if ( !Object.isUndefined(cart_item) ) 
		{
			this.cart_items.unset(product_record_id);
			
			this.pushToServer();
		}
		
		return cart_item;
	},
	getProduct: function(product_record_id)
	{
		return this.cart_items.get(product_record_id);
	},
	getGrandTotalValue: function()
	{
		var grand_total_value = 0.00;
		
		this.cart_items.each( function(cart_item_hash, cart_item_hash_index)
		{
			grand_total_value += cart_item_hash.value.getTotalValue();
			
		}.bind(this));
		
		if ( this.delivery != null )
		{
			//grand_total_value += this.delivery.amount;
		}
		
		return grand_total_value;
	},
	observe: function(event_string, func)
	{
		switch (event_string)
		{
			case 'pushed':
				this.event_listeners.pushed.push(func);
				break;
				
			case 'pulled':
				this.event_listeners.pulled.push(func);
				break;
		}
	}
}

var CartItem = Class.create();

CartItem.prototype = {
	initialize: function(cart, product_record)
	{
		this.cart = cart;
		this.product_record = product_record;
		this.qty = 1;
	},
	setQty: function(qty)
	{
		if ( qty >= 1 )
		{
			this.qty = parseInt(qty);
			( this.cart != false ? this.cart.pushToServer() : false );
		}
	},
	addQty: function(qty)
	{
		if ( qty >= 1 )
		{
			this.qty += parseInt(qty);
			( this.cart != false ? this.cart.pushToServer() : false );
		}
	},
	getTotalValue: function()
	{
		return this.product_record.Price[0][root.current_use_price] * this.qty;
	}
}



var CartDisplay = Class.create();
CartDisplay.prototype = {
	initialize: function(cart, el)
	{
		this.cart = cart;
		this.el = el.update('');
		
		// Flag
		this.allow_item_remove = true;
		this.allow_qty_edit = true;
		
		// Checkout button
		this.checkout_button_el = new Element('input', {type:'button', value: 'Checkout'}).addClassName('input_button');
		this.checkout_url = '#';
		this.checkout_button_el.observe('click', function(event)
		{
			window.location.href = this.checkout_url;
			
		}.bindAsEventListener(this));
		
		this.header_el = new Element('div').update('<h1><img src="/img/techexcel/cart_title.gif" /> Shopping Cart</h1><div class="text_smaller">Thank You! Please review your shopping cart items below, and click "CEHCKOUT" button when ready to checkout.</div><br />');
		this.body_el = new Element('div');
		this.grand_total_el = new Element('div').addClassName('text_align_right text_larger text_bold').update('Total '+( root.display_gst ? 'InGST' : 'ExGST' )+'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$'+( root.display_gst ? number_format(this.cart.getGrandTotalValue() * 1.1, 2) : number_format(this.cart.getGrandTotalValue(), 2)) );
		this.checkout_el = new Element('div').update(this.checkout_button_el);
		
		this.el.insert(this.header_el).insert(this.body_el).insert(this.grand_total_el).insert(this.checkout_el);
		
		// Register itself
		this.cart.registered_cart_displays.push(this);

	},
	observe: function(event_string, func)
	{
		switch (event_string)
		{
			case 'rendered':
				this.el.observe('CartDisplay:render', func);
				break;
		}
	},
	render: function()
	{
		var layout_table_el = new TableElement({num_rows: ( this.cart.cart_items.keys().length != 0 ? this.cart.cart_items.keys().length : 1 ), num_cols: 6}).addClassName('table cart_display_table');
		
		this.cart.cart_items.each( function(cart_item_hash, cart_item_hash_index)
		{
			var cart_item = cart_item_hash.value;
			
			var product_link_el = new Element('a',{href: "#"}).update(cart_item.product_record.Product.description);
			
			var qty_input_el = new Element('div').update(cart_item.qty);
			if ( this.allow_qty_edit )
			{
				qty_input_el = new Element('input', {value: cart_item.qty, maxLength: 4}).addClassName('input_text qty_input');
			}
			
			var remove_link_el = new Element('div').update('&nbsp;');
			if ( this.allow_item_remove )
			{
				remove_link_el = new Element('a', {href: "#"}).update('<img src="/img/techexcel/cross_icon.gif" title="Remove this product" alt="Remove this product" />');
			}
			
			layout_table_el.getCell(cart_item_hash_index, 0).insert(remove_link_el).addClassName('table_field width_5');
			layout_table_el.getCell(cart_item_hash_index, 1).insert(product_link_el).insert(new Element('span').addClassName('text_smaller').update(' - [$'+( root.display_gst ? number_format(cart_item.product_record.Price[0][root.current_use_price] * 1.1, 2) : number_format(cart_item.product_record.Price[0][root.current_use_price], 2) )+']</span>')).addClassName('table_field width_55');
			layout_table_el.getCell(cart_item_hash_index, 2).update('&nbsp;&nbsp;&nbsp;x&nbsp;&nbsp;&nbsp;').addClassName('table_field width_5 text_align_right');
			layout_table_el.getCell(cart_item_hash_index, 3).insert(qty_input_el).addClassName('table_field width_10 text_align_right');
			layout_table_el.getCell(cart_item_hash_index, 4).update('&nbsp;&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;').addClassName('table_field width_5 text_align_right');
			layout_table_el.getCell(cart_item_hash_index, 5).update('$'+( root.display_gst ? number_format(cart_item.getTotalValue() * 1.1, 2) : number_format( cart_item.getTotalValue(), 2 )) ).addClassName('table_field width_20 text_align_right');
			
			// Event on qty_input_el
			qty_input_el.observe('change', function(event)
			{
				var value = parseInt(qty_input_el.value);
				if ( isNaN(value) || value < 0 || value > 99 ) 
				{
					alert('Please enter value between 0 - 99');
					qty_input_el.value = '1';
					value = 1;
				}
				
				// Set new qty
				var target_cart_item = this.cart.cart_items.get(cart_item.product_record.Product.id);
				target_cart_item.setQty(value);
				
				// Redraw
				this.render();
				
			}.bindAsEventListener(this));
			
			// Event on remove_link_el
			remove_link_el.observe('click', function(event)
			{
				if ( this.allow_item_remove && confirm('Remove this item?') ) 
				{
					this.cart.removeProduct(cart_item.product_record.Product.id);
					
					// Redraw
					this.render();
				}
				
			}.bindAsEventListener(this));
			
			// Event on product_link_el
			product_link_el.observe('click', function(event)
			{
				if ( root.product_viewer != false )
				{
					root.product_viewer.display(cart_item.product_record);
				}
				
			}.bindAsEventListener(this));
			
		}.bind(this));
		
		// Empty Cart?
		if ( this.cart.cart_items.keys().length == 0 )
		{
			layout_table_el.getCell(0, 1).update('Your shopping cart is empty.');
			this.checkout_button_el.hide();
		}
		else
		{
			// Show Delivery
			/*
			if ( this.cart.delivery != null )
			{
				var delivery_row_index = layout_table_el.rows.length;
				layout_table_el.setNumRows(delivery_row_index + 1);
				layout_table_el.getCell(delivery_row_index, 0).addClassName('table_field width_5').update('&nbsp;');
				layout_table_el.getCell(delivery_row_index, 1).update('<a href="#">'+this.cart.delivery.name+'</a>').addClassName('table_field width_55');
				layout_table_el.getCell(delivery_row_index, 2).update('&nbsp;&nbsp;&nbsp;x&nbsp;&nbsp;&nbsp;').addClassName('table_field width_5 text_align_right');
				layout_table_el.getCell(delivery_row_index, 3).update('1').addClassName('table_field width_10 text_align_right');
				layout_table_el.getCell(delivery_row_index, 4).update('&nbsp;&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;').addClassName('table_field width_5 text_align_right');
				layout_table_el.getCell(delivery_row_index, 5).update('$'+number_format( this.cart.delivery.amount )).addClassName('table_field width_20 text_align_right');
			}
			*/
			this.checkout_button_el.show();
		}
		
		this.body_el.update('');
		this.body_el.insert(layout_table_el);
		
		this.grand_total_el.update('Total '+( root.display_gst ? 'InGST' : 'ExGST' )+'&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$'+( root.display_gst ? number_format(this.cart.getGrandTotalValue() * 1.1, 2) : number_format(this.cart.getGrandTotalValue(), 2) ) );
		
		this.el.fire('CartDisplay:render');
	}
}