Array.implement({
	
	invoke: function(fn, args){
		var result = [];
		
		for (var i = 0, l = this.length; i < l; i++){
			if(this[i] && this[i][fn])
				result.push(args ? this[i][fn].pass(args, this[i])() : this[i][fn]());
		}
		return result;
	}
	
});

var GMapHandler = new Class({
	map: false,
	
	initialize: function(el, lat, long) {
		window.addEvent('unload', function() {
			GUnload();
		});
		
		if (GBrowserIsCompatible()) {		
			this.map = new GMap2($(el));
			this.map.addControl(new GSmallMapControl());
				
			this.setCenter(lat, long);
		}
	},
	
	setCenter: function(lat, long) {
		var point = new GLatLng(parseFloat(lat), parseFloat(long));
		this.map.setCenter(point, 12);
		this.map.addOverlay(new GMarker(point));
	}
});

var Shared = new Class({

	initialize: function() {
		var basket = $('basket');
		if (basket) {
			$('basket').addEvent('click', function() {
				document.location.href = '/shop/basket';
			});
		}
		
		var basketAdded = null;
		if ((basketAdded = $('basket_added')) != null) {
			var fx = new Fx.Tween(basketAdded, {property: 'opacity', duration: 1000});
			(function() { fx.start([1,0]) }).delay(2000);
		}
		
		var buttons = $$('.btn_delete');
		if (buttons.length) {
			buttons.each(function(btn) {
				btn.addEvent('click', function(e) {
					this.confirmDelete(e);
				}.bind(this));
			}.bind(this));
		}
		
		if ($('basket_contents')) {
			var btnDeletes = $('basket_contents').getElements('a.btn_delete');
			if (btnDeletes.length) {
				btnDeletes.each(function(btn) {
					btn.removeEvents('click');
					btn.addEvent('click', function(e) {
						if (this.confirmDelete(e)) {
							var row = $(e.target).getParent().getParent().getParent();
							var tbl = row.getParent().getParent();
							if (tbl.rows.length == 3) document.location.reload();
							else $('shipping_category').fireEvent('change');
						}
					}.bind(this));
				}.bind(this));
			}
			
			if ($('shipping_destination')) {
				var objDestination = $('shipping_destination');
				var objCategory = $('shipping_category');
				var objShippingPrice = $('shipping_price');
				var objTotalPrice = $('basket_total');
				
				objDestination.addEvent('change', function() {
					objCategory.empty();
					objShippingPrice.empty();
					new Element('div', {'class': 'spinner', 'html': '&nbsp;'}).inject(objShippingPrice);
					
					new Request.JSON({
						url: '/shop/update-basket',
						onSuccess: function(json) {
							json.categories.each(function(category)  {
								new Element('option', {'value': category.id, 'text': category.name}).inject(objCategory);
							});
							objCategory.fireEvent('change');
						}
					}).get({'action': 'shipping', 'destination_id': objDestination.get('value')});
				});
				
				objCategory.addEvent('change', function() {
					objShippingPrice.empty();
					new Element('div', {'class': 'spinner', 'html': '&nbsp;'}).inject(objShippingPrice);
					objTotalPrice.empty();
					new Element('div', {'class': 'spinner', 'html': '&nbsp;'}).inject(objTotalPrice);
	
					var date = new Date();
					new Request.JSON({
						url: '/shop/update-basket',
						onSuccess: function(json) {
							$('basket_items').set('html',json.basket_items);
							$('basket_items_price').set('html',json.basket_items_price);
							objShippingPrice.empty().set('html',json.shipping_price);
							objTotalPrice.empty().set('html',json.total_price);
						}
					}).get({'action': 'shipping', 'category_id': this.get('value'), 'time': date.getTime()});
				});
			}
			
			if ($('purchased_yes')) {
				var yesSlide = new Fx.Slide('purchased_yes');
				var noSlide = new Fx.Slide('purchased_no');
				var yesQuestion = $('already_purchased_yes');
				var noQuestion = $('already_purchased_no');
				if (yesQuestion.get('checked')) {
					noSlide.hide();
				}
				if (noQuestion.get('checked')) {
					yesSlide.hide();
				}
				yesQuestion.addEvent('click', function() {
					yesSlide.toggle();
					noSlide.toggle();
				});
				noQuestion.addEvent('click', function() {
					yesSlide.toggle();
					noSlide.toggle();
				});
			
				var registerForm = ($('purchased_no')) ? $('purchased_no') : $('confirm_details');
				var inputs = registerForm.getElements('input[type="text"]');
				inputs.each(function(input) {
					if (!input.get('name').contains('delivery_')) {
						input.addEvent('blur', function() {
							var sibling = $('delivery_'+input.get('name'));
							if (sibling && (sibling.get('value') == '')) sibling.set('value',input.get('value'));
						});
					}
				});
			}
		}
		
		if ($('gmap')) new GMapHandler('gmap', $('lat').get('value'), $('lon').get('value'));
		
		if ($('categories')) {			
			$$('li.expander, li.expanded').each(function(li) {
				var subcat = li.getElement('ul');
				if (subcat) {
					subcat.setStyle('display','block');
					var subcatSlide = new Fx.Slide(subcat, {'duration': 'short'});
					if (li.hasClass('expander')) subcatSlide.hide();
					li.addEvent('click', function(e) {
						if (e) e.stopPropagation();
						subcatSlide.toggle();

						if (li.hasClass('expander')) li.removeClass('expander').addClass('expanded');
						else li.removeClass('expanded').addClass('expander');
					});
					li.getElement('a').addEvent('click', function(e) {
						var event = new Event(e).stop();
						if (!subcatSlide.open) {
							$(event.target).getParent().fireEvent('click');
						} else {
							document.location.href = this.get('href');
						}
					});
				}
			});
			
			$('categories').getElements('a').each(function(link) {
				link.addEvent('click', function(e) {
					e.stopPropagation();
				});
			});
		}
		
		new ZebraTable({'elements': 'div.product_left table', 'mouseEvents': false});
		
		$('search_go').addEvent('click', function(e) {
			$(e.target).getParent().submit();
		});
		
		$$('.print-window').addEvent('click', function(e) {
			new Event(e).stop();
			window.print();
		});
		
		var stockists = $$('a.stockist');
		if (stockists) {
			SqueezeBox.initialize({ size: {x: 600, y: 400} });
			stockists.addEvent('click', function(e) {
				e.stop();
				var uri = new URI(e.target);
				SqueezeBox.open($('stockist_'+uri.getData('stockist','fragment')), {handler: 'clone'});
				SqueezeBox.addEvent('open', function() {
					$('sbox-content').getElement('div').setStyle('display','block');
				});
			});
		}
		
		var stockists = $$('a.stockist_map');
		if (stockists) {
			SqueezeBox.initialize({ size: {x: 600, y: 400} });
			stockists.addEvent('click', function(e) {
				e.stop();
				var uri = new URI(e.target);
			    SqueezeBox.open($('stockist_map'), {handler: 'clone'});
			    SqueezeBox.addEvent('open', function() {
					new GMapHandler('sbox-content', uri.getData('lat','fragment'), uri.getData('lon','fragment'));
				});
			});
		}
		
		if ($('purchase_date')) this.addDateUtil($('purchase_date'));
		
		this.addTooltips();
	},
	
	addDateUtil: function(dateFields) {
		if ($type(dateFields) != 'array') dateFields = [dateFields];
	
		dateFields.each(function(el) {
			new vlaDatePicker(el, {separator: '-', prefillDate: false});
		});
	},
	
	addTooltips: function() {
		$$('.tooltip').each(function(element,index) {
			var content = element.get('title').split('::');
			element.store('tip:title', content[0]);
			element.store('tip:text', content[1]);
		});
		
		//create the tooltips
		var tipz = new Tips('.tooltip',{
			className: 'tipz',
			fixed: true,
			hideDelay: 50,
			showDelay: 50,
			offset: {'x': 0, 'y': 16}
		});	
	},
	
	confirmDelete: function(e) {
		var btn = $(e.target).getParent();

		var parts = btn.get('title').split(' | ');
		switch (parts.length) {
			case 1: var msg = 'Are you sure you want to delete?'; break;
			case 2: var msg = 'Are you sure you want to delete this '+parts[1]+'?'; break;
			case 3: var msg = 'Are you sure you want to delete this '+parts[1]+'?\n- '+parts[2]; break;
		}
		
		if (!confirm(msg)) e.stop();
		else {
			if (btn.href.indexOf('xhr') > -1) {
				e.stop();
				var link = btn.href.split('&xhr');
				var parts = link[0].split('?');
				var date = new Date();
				parts[1] += '&rowIndex='+(btn.getParent().getParent().rowIndex-1)+'&time='+date.getTime();
				return new Request.JSON({
					method: 'get',
					url: parts[0],
					onSuccess: function(json) {
						if (json.status == 'deleted') {
							var row = btn.getParent().getParent();
							return this.removeTableRow(row);
						} else if (json.status == 'error') {
							alert('It was not possible to remove the item from your basket!');
							return false;
						}
					}.bind(this)
				}).send(parts[1]);
			}
		}
	},
	
	removeTableRow: function(row) {
		var children = row.getChildren();
		
		var cellHeight = 0;
		children.each(function(child) {
			if (parseInt(child.getStyle('height')) > cellHeight) cellHeight = parseInt(child.getStyle('height'));
		});
		children.invoke('setStyle', ['height',cellHeight]);

		var fx = new Fx.Tween(row);
		fx.start('opacity','0.2').chain(function() {
			var childFx = [];
			children.each(function(child) {
				childFx.push(new Fx.Tween(child));
			});
			children.invoke('set', ['html','']);
			childFx.invoke('start', ['height','0px']);
			
			this.start('border','0').chain(function() {
				row.dispose();
				return true;
			});
		});
	}

});

var ZebraTable = new Class({
	Implements: [Options,Events],
	
	options: {
		elements: 'table.list-table',
		cssEven: 'zebra_even',
		cssOdd: 'zebra_odd',
		cssHighlight: 'zebra_highlight',
		cssMouseEnter: 'zebra_mo',
		mouseEvents: true
	},
	
	initialize: function(options) {
		this.setOptions(options);

		$$(this.options.elements).each(function(table) {
			this.zebraize(table);
		},this);
	},
	
	zebraize: function(table) {
		table.getElements('tbody tr').each(function(tr,i) {
			var options = this.options, klass = i % 2 ? options.cssEven : options.cssOdd;
			tr.addClass(klass);
			if (this.options.mouseEvents) {
				tr.addEvents({
					mouseenter: function () {
						if(!tr.hasClass(options.cssHighlight)) tr.addClass(options.cssMouseEnter).removeClass(klass);
					},
					mouseleave: function () {
						if(!tr.hasClass(options.cssHighlight)) tr.removeClass(options.cssMouseEnter).addClass(klass);
					},
					click: function() {
						if(!tr.hasClass(options.cssHighlight))
							tr.removeClass(options.cssMouseEnter).addClass(options.cssHighlight);
						else
							tr.addClass(options.cssMouseEnter).removeClass(options.cssHighlight);
					}
				});
			}
		}, this);
	}
});


var shared;
window.addEvent('domready', function() {
	shared = new Shared();
});