var tdCollection;
(function($) {
	tdCollection = {
		init : function() {
			// Display the spinner
			$("#body, #filmstrip").css({opacity: 0});
			$("#page").addClass('spinner');
			
			// Set up thumbnails
			$("#body .piece").each(function() {
				var t = $(this);
				var id = t.attr('id');
				
				$('#filmstrip a[href$="' + id + '"]')
				.click(function() {
					if (tdFilmstrip.pieceCarousel.locked || tdFilmstrip.pieceCarousel.animating)
		                return false;
					// Push state
					$.bbq.pushState({image: id}, 2);
					return false;
				})
				.hover(
					function() {
						$(this).stop().animate({
							borderTopColor: '#58585A',
							borderRightColor: '#58585A',
							borderBottomColor: '#58585A',
							borderLeftColor: '#58585A'
						}, 100);
					},
					function() {
						if ( !$(this).hasClass('active') ) {
							$(this).stop().animate({
								borderTopColor: '#D1D1D3',
								borderRightColor: '#D1D1D3',
								borderBottomColor: '#D1D1D3',
								borderLeftColor: '#D1D1D3'
							}, 250);	
						}
					}
				);
			});
			
			// Set up jewellery views
			$("#body .view").each(function() {
				var t = $(this);
				var p = t.closest(".piece");
				var src = t.find(".hidden .src").html();
				var width = parseInt( t.find(".hidden .width").html() );
				t.css({
					backgroundImage: "url('" + src + "')",
					width: width
				})
				.closest('li').css({
					width: width
				});
			});
			
			// Create jewellery piece carousel
			$("#body .pieces").jcarousel({
				scroll: 1,
				animation: 750,
				easing: 'easeOutQuart',
				buttonNextHTML: '<div class="iepngfix"></div>',
				buttonPrevHTML: '<div class="iepngfix"></div>',
				initCallback: function(carousel, state) {
					tdFilmstrip.pieceCarousel = carousel;
					// Split the middle
					var half = Math.floor(carousel.options.size / 2);
					$("#body .pieces li:gt(" + (half - 1) + ")").prependTo("#body .pieces");
				},
				wrap: 'both'
			});
			
			// Extend jewellery piece carousel
			tdFilmstrip.pieceCarousel.extend({
				scroll: function(i, a) {
					if (this.locked || this.animating)
						return;
					
					// If transition is not animated, trigger it immediately
					if ( a == false ) {
						this.animate(this.pos(i), false);
						return;
					}
					
					// Get position, set this.speed
					var pos = this.pos(i);
					
					// Get distance to new position
					var diff = Math.abs(this.first - $.jcarousel.intval(i));
					
					// Set new animation speed
					var speed = this.options.animation * Math.sqrt(Math.sqrt(this.dist/500));
					
					// Animate the scroll
					this.animate(pos, a, speed);
				},
				animate: function(p, a, speed) {
					if (this.locked || this.animating)
						return;
		
					this.animating = true;
					
					// Added this line; if a speed is specified, use it
					var speed = speed ? speed : this.options.animation;
		
					var self = this;
					var scrolled = function() {
						self.animating = false;
		
						if (p == 0)
							self.list.css(self.lt,	0);
		
						if (self.options.wrap == 'both' || self.options.wrap == 'last' || self.options.size == null || self.last < self.options.size)
							self.startAuto();
		
						self.buttons();
						self.notify('onAfterAnimation');
					};
		
					this.notify('onBeforeAnimation');
		
					// Animate
					if (!speed || a == false) {
						this.list.css(this.lt, p + 'px');
						scrolled();
					} else {
						var o = !this.options.vertical ? {'left': p} : {'top': p};
						this.list.animate(o, speed, this.options.easing, scrolled);
					}
				},
				pos: function(i) {
					if (this.locked || this.animating)
		                return;

		            i = $.jcarousel.intval(i);
					
		            var t = $(".pieces .jcarousel-item-" + i);
					
					if ( !t.length )
						return false;
					
					var diff = i - this.focus;
					
					// Adjust diff so that we move the fewest necessary list items
					if ( Math.abs(diff) > Math.floor(this.options.size / 2) ) {
						diff = diff > 0 ? diff - this.options.size : diff + this.options.size;
					}
					
					// Move the list items from the left side to the right...
					if ( diff > 0 ) {
						var aw = 0;
						var items = $("#body .pieces li:lt(" + diff + ")").each(function() {
							aw += $(this).width();
						});
						items.appendTo("#body .pieces");
						// Adjust left offset to compensate for removed items
						if ( aw ) {
							var l = parseInt(this.list.css(this.lt));
							var n = l + aw;
							this.list.css(this.lt, n + 'px');
							aw = 0;
						}
					}
					// ...or from the right side to the left
					else if ( diff < 0 ) {
						var aw = 0;
						var items = $("#body .pieces li:gt(" + (this.options.size + diff - 1) + ")").each(function() {
							aw += $(this).width();
						});
						items.prependTo("#body .pieces");
						// Adjust left offset to compensate for added items
						if ( aw ) {
							var l = parseInt(this.list.css(this.lt));
							var n = l - aw;
							this.list.css(this.lt, n + 'px');
							aw = 0;
						}
					}
						
					// Calculate the scroll
					this.focus = i;
					var il = t.position().left;
					var iw = t.width();
					var pw = $("#body .jcarousel-container").width();
					var pos = 0 - parseInt( il + ( iw / 2 ) - ( pw / 2 ) );
					
					this.dist = Math.abs(n - pos);
					
		            return pos;
				},
				next: function() {
					if (this.locked || this.animating)
		                return;
					$.bbq.pushState({
						image: $("#body li.jcarousel-item-" + this.focus).next('li').attr('id')
					}, 2);
					// Original code:
					// this.scroll( this.focus < this.options.size ? this.focus + 1 : 1 );
		        },
 				prev: function() {
					if (this.locked || this.animating)
		                return;
					$.bbq.pushState({
						image: $("#body li.jcarousel-item-" + this.focus).prev('li').attr('id')
					}, 2);
					// Original code:
					// this.scroll( this.focus > 1 ? this.focus - 1 : this.options.size );
		        },
				focus: 0,
				dist: 0
			});

			// Bind an event to window.onhashchange
			$(window).bind('hashchange', function(e, a) {
				var hash = e.getState();
				var link = hash.image ? $('a[href$="' + hash.image + '"]') : false;
				
				// Default target if we have no hash
				var target = $(".pieces li.title");
				
				// Unset active link
				$("#filmstrip a.active").removeClass('active').css({borderColor: '#D1D1D3'});
				
				if ( link.length ) {
					// Set active link
					link.addClass('active').css({borderColor: '#58585A'});
					
					// Set scroll target
					target = $('#' + hash.image);
				}
				
				// Display target element
				tdFilmstrip.pieceCarousel.scroll( target.attr('jcarouselindex'), a );
			});
			
			// Do the rest after everything else has loaded
			$(window).load(tdCollection.onLoad);
		},
		onLoad : function() {
			// Vertically centre copy
			$("#body .copy").wrapInner('<div />').children("div").vCenter();
			
			// Trigger the correct piece on load, without animation
			$(window).trigger('hashchange', false);
			
			// Remove the spinner
			$("#page").removeClass('spinner');
			$("#body, #filmstrip").animate({opacity: 1}, 200);
		}
	}
	$(document).ready(tdCollection.init);
})(jQuery);
