var Catalog = {
	getOption: function(el) {
		return new Catalog.Option(el)
	},
	
	getProduct: function(el) {
		return new Catalog.Product(el)
	},
	
	getBasket: function() {
		return new Catalog.Basket();
	},
	
	getOrder: function() {
		return new Catalog.Order();
	},
	
	getBasketProduct: function(el) {
		return new Catalog.BasketProduct(el)
	},
	
	blendBasket: function() {
		new Effect.Opacity('basket_container', { from: 1.0, to: 0.1, duration: 0.1 });
	},
	
	showBasket: function() {
		Effect.Appear('basket_container');
	}
}

Catalog.Element = Class.create({}, {
	initialize: function(el) {
		var tmp = $(el)
		this.el = tmp.hasClassName(this.className) ? tmp : tmp.up('.' + this.className);
	}
});


Catalog.Basket = Class.create({}, {
	initialize: function() {
		this.el = $('cart');
	},
	
	update: function() {
		Catalog.blendBasket();

		new Ajax.Updater('basket_container', _INDEX + '/' + _SUBSITE + '/ajax/basket', {
			parameters: 'ajax=1&' + this.el.serialize(),
			onComplete: function(r) { Catalog.showBasket() }
		});		
	},
	
	getOptions: function() {
		return this.el.select('.product_option').collect(function(el) {
			return new Catalog.Option(el);
		});
	}
});

Catalog.Order = Class.create({}, {
	initialize: function() {
		this.el = $('shcart');
	},
	
	update: function() {
		Catalog.blendBasket();

		new Ajax.Updater('basket_container', _INDEX + '/' + _SUBSITE + '/ajax/order', {
			parameters: 'ajax=1&' + this.el.serialize(),
			onComplete: function(r) { Catalog.showBasket() }
		});		
	},
	
	removeFromBasket: function() {
		Catalog.blendBasket();
		
		new Ajax.Updater('basket_container', _INDEX + '/' + _SUBSITE + '/ajax/order', {
			parameters: 'act=catalogue/basket_remove&product_id=' + escape(this.getProductId()),
			onComplete: function(r) { Catalog.showBasket(); }
		});
	},
	
	getProductId: function() {
		return this.el.down('span.product_id').innerHTML;		
	}
});


Catalog.Product = Class.create(Catalog.Element, {
	className: 'product',
	
	addToBasket: function() {
		if (!this.getPickedOptions().length)
			return alert(_MESSAGES.CHOOSE_AMOUNT);
			
		this.showNote(_MESSAGES.PRODUCT_ADDED_TO_BASKET);
		
		Catalog.blendBasket();
					 
		new Ajax.Updater('basket_container', _INDEX + '/' + _SUBSITE + '/ajax/basket', {
			parameters: 'act=catalogue/basket_add&' + this.el.serialize(),
			onComplete: function(r) { Catalog.showBasket() }
		});
		
		this.resetAmounts();
	},
	
	removeFromBasket: function() {
		Catalog.blendBasket();
		
		new Ajax.Updater('basket_container', _INDEX + '/' + _SUBSITE + '/ajax/basket', {
			parameters: 'act=catalogue/basket_remove&product_id=' + escape(this.getProductId()),
			onComplete: function(r) { Catalog.showBasket(); }
		});
	},
	
	getProductId: function() {
		return this.el.down('span.product_id').innerHTML;		
	},
	
	showNote: function(note) {
		var el = this.el.down('.note');
		el.down('div').update(note);

		var queue = Effect.Queues.get('notescope');
		queue.each(function(effect) { effect.cancel(); });
		
		new Effect.SlideDown(el, { duration: 0.4, queue: { position: 'end', scope: 'notescope', limit: 2 }});
		new Effect.SlideUp(el, { duration: 0.4, delay: 0.8, queue: { position: 'end', scope: 'notescope', limit: 2 }});
	},
	
	getPickedOptions: function() {
		return this.getOptions().select(function(o) {
			return o.getAmount() > 0;
		})
	},

	getOptions: function() {
		return this.el.select('.product_option').collect(function(el) {
			return new Catalog.Option(el);
		});
	},
	
	resetAmounts: function() {
		this.getOptions().each(function(o) { o.reset(); }); 
	}
});

Catalog.BasketProduct = Class.create(Catalog.Product, {
	className: 'cart_product'
});

Catalog.Option = Class.create(Catalog.Element, {
	className: 'product_option',
	
	changeAmount: function(n) {
		this.setAmount(this.getAmount() + n);			
	},
	
	getCode: function() {
		return this.el.down('span.option_code').innerHTML;		
	},
	
	getAmount: function() {
		return parseInt($F(this.getAmountEl())); 
	},
	
	getAmountEl: function() {
		return this.el.down('.amount input');
	},
	
	setAmount: function(n) {
		if (n < 0) return;
		this.getAmountEl().value = n;
		this.el.down('.amount span').update(n);
	},
	
	reset: function() {
		this.setAmount(0);
	}
});

