
var ShoppingCartItem = Class.create(
{
	id: null,
	
	element: null,
	
	cart: null,
	
	quantity: 1,
	
	featuresList: null,	
	
	featureListUpdater: null,
	
	initialize: function( cart, element )
	{
		this.cart = cart;
		this.element = element;
		
		this.initDOM();
		this.initOther();
		this.initEvents();
	},
	
	initDOM: function()
	{
		this.dom 			= {};
		this.dom.expand		= this.element.getElementsByClassName( "expand" )[0];
		this.dom.remove		= this.element.getElementsByClassName( "remove" )[0];
		this.dom.update		= this.element.getElementsByClassName( "update" )[0];
		this.dom.quantity 	= this.element.getElementsByClassName( "quantity" )[0];
		this.dom.product	= this.element.getElementsByClassName( "product-title" )[0].down( 'a' );
		this.dom.each		= this.element.getElementsByClassName( "each" )[0];
		this.dom.total		= this.element.getElementsByClassName( "total" )[0];
	},
	
	initOther: function()
	{
		this.quantity = parseInt( this.dom.quantity.getValue() );
		this.id = this.element.getAttribute( "id" ).replace( ShoppingCartItem.ROW_ID_MASK, "" );
		if( !this.dom.expand.hasClassName( "disabled" ) )
		{
			var nextTr = this.element.next( "tr" );
			
			if( nextTr.hasClassName( "item-features" ) )
			{
				this.featuresList = new ShoppingCartItemFeatures( this, nextTr );
				var featureForm = nextTr.down( "form" );
				if( featureForm.hasClassName( "feature-list-updater" ) )
					this.featureListUpdater = new FeatureListUpdater( featureForm, this );
			}
		}
	},
	
	initEvents: function()
	{
		if( !this.dom.expand.hasClassName( "disabled" ) )
			this.dom.expand.observe( "click", this.handleClickExpand.bind( this ) );
			
		this.dom.remove.observe( "click", this.handleClickRemove.bind( this ) );
		this.dom.update.observe( "click", this.handleClickUpdate.bind( this ) );
		this.dom.quantity.observe( "keydown", this.handleQuantityKeyDown.bind( this ) );
		this.dom.quantity.observe( "keyup", this.handleQuantityChange.bind( this ) );
	},
	
	getId: function()
	{
		return this.id;
	},
	
	getCart: function()
	{
		return this.cart;
	},
	
	getElement: function()
	{
		return this.element;
	},
	
	getFeaturesList: function()
	{
		return this.featuresList;
	},
	
	getFeatureListUpdater: function()
	{
		return this.featureListUpdater;
	},
	
	getQuantity: function()
	{
		return this.quantity;
	},
	
	setQuantity: function( quantity )
	{
		if( quantity === false )
			return this.dom.quantity.setValue( this.quantity );
		
		this.quantity = quantity;
		
		this.dom.quantity.setValue( quantity > -1 ? quantity : 0 );
		return this;
	},
	
	setEach: function( each )
	{
		this.dom.each.update( "$" + each );
		return this;
	},
	
	setTotal: function( total )
	{
		this.dom.total.update( "$" + total );
	},
	
	updateQuantity: function()
	{
		var uri = ShoppingCartItem.UPDATE_URI + this.getId();
		
		if( this.quantity == 0 )
			if( !confirm( "Remove " + this.dom.product.innerHTML + "?" ) )
				return;
		
		new Ajax.Request( uri,
		{
			method: "get",
			parameters: { quantity: this.quantity },
			onSuccess: this.updateDisplay.bind( this ),
			onFailure: function(){ alert( "ERROR\n\nCannot update item quantity [HTTP]" ) }
		});
	},
	
	updateDisplay: function( transport )
	{
		var data = transport.headerJSON;
		
		this.dom.quantity.blur();
		
		if( data.success == false )
			return alert( "ERROR\n\nCannot update or remove item [APP]" );
			
		if( data.remove_item == true )
		{
			this.destroy();
			
		} else {

			new Effect.Opacity( this.dom.total,
			{
				duration: 0.2,
				from: 1.0,
				to: 0.0,
				afterFinish: function()
				{
					this.setEach( data.item_each ).setTotal( data.item_total );
					new Effect.Opacity( this.dom.total,
					{
						duration: 0.5,
						from: 0.0,
						to: 1.0
					});
				}.bind( this )
			});
				
		}
		
		this.getCart().setTotal( data.cart_total );
		
		if( data.item_count == 0 )
			this.setEmpty();
		
		Event.fire( document, "cart:change" );
	},
	
	remove: function()
	{
		this.getCart().removeItem( this );
	},
	
	destroy: function()
	{
		if( this.featuresList instanceof ShoppingCartItemFeatures && this.featuresList.isExpanded() )
		{
			this.featuresList.collapse( this.destroy, 0.5 );
			
		} else {
			
			this.getElement().absolutize();
			Effect.Puff( this.getElement(),
			{
				duration: 0.5,
				afterFinish: function()
				{
					this.getCart().dom.cartContents.removeChild( this.getElement() );
					Event.fire( document, "dynamic-table:change" );
				}.bind( this )
			});
		}
	},
	
	expandFeatures: function()
	{
		this.featuresList.expand();
		this.dom.expand.addClassName( "expanded" );
	},
	
	collapseFeatures: function()
	{
		this.featuresList.collapse();
		this.dom.expand.removeClassName( "expanded" );
	},
	
	// Event Handlers
	
	handleClickExpand: function( e )
	{
		Event.stop( e );
		
		this.dom.expand.blur();
		
		if( !this.featuresList instanceof ShoppingCartItemFeatures )
			return;
			
		if( this.featuresList.isAnimating() )
			return;
		
		if( this.featuresList.isExpanded() )
			this.collapseFeatures();
		else
			this.expandFeatures();
	},
	
	handleClickRemove: function( e )
	{
		Event.stop( e );
		
		if( !confirm( "Remove " + this.dom.product.innerHTML + "?" ) )
			return;
		
		var uri = ShoppingCartItem.REMOVE_URI + this.getId();
		
		new Ajax.Request( uri,
		{
			method: "get",
			onSuccess: this.updateDisplay.bind( this ),
			onFailure: function(){ alert( "ERROR\nCould not remove item [HTTP]" ) }
		});		
	},
	
	handleClickUpdate: function( e )
	{
		Event.stop( e );		
		this.updateQuantity();
	},
	
	handleQuantityKeyDown: function( e )
	{
		// Check to see if they pressed ENTER
		
		var code = e.keyCode || e.which;		
		if( code === Event.KEY_RETURN )
		{
			Event.stop( e );
			this.updateQuantity();
		}
	},
	
	handleQuantityChange: function( e )
	{
		Event.stop( e );
		
		var value = this.dom.quantity.getValue();
		if( value == "" || value == "-" ) return;
		
		this.setQuantity( isNaN( value = parseInt( value ) ) ? false : value );
	},
	
	setEmpty: function()
	{
		this.getCart().dom.cartContents.insert( { top: '<tr class="dynamic-ignore"><td colspan="6"><h2 class="orb info">Your cart is empty.</h2></td></tr>' } );
	}
});

ShoppingCartItem.ROW_ID_MASK = "row_";
ShoppingCartItem.REMOVE_URI = "/cart/remove/";
ShoppingCartItem.UPDATE_URI = "/cart/update-quantity/";