(function() {
    var window = this, undefined, widget = window.jsx.widget;

    jsx.widget.ProductPanel = function(element, galleryInstance) {
		var self = this, jquery_width_func;
		element = $(element);
		this.galleryInstance = galleryInstance;
		this.visible = false;
		this.element = element;
		this.isCollapsibleNoDisplay = true;
		this.thumbnailListPanel = element.find("div.thumbnail-list-panel").addClass('no-display');
		this.thumbnailList = this.thumbnailListPanel.find("*.thumbnail");
		this.photoListPanel = element.find("div.photo-list");
		this.initialWidth = this.photoListPanel.width();
		this.photoList = this.photoListPanel.find("*.photo");
		this.photoDisplay = this.photoListPanel.find("*.photo-label");
		this.photoDisplayOver = this.photoListPanel.find("*.photo-label-inactive");
		this.photoLoadIcon = this.photoListPanel.find("*.load-icon");
		this.textPanel = element.find("div.text").addClass('no-display');
		this.descriptionPanel = this.textPanel.find("div.description").addClass('no-display');
		this.asidePanel = this.textPanel.find("div.aside");
		this.descriptionList = [];
		element.find("ul.description-list li.description").each(
			function() {
				self.descriptionList.push($(this).html());
			}
		);
		this.listenerArray = [];
		this.lastPhoto = null;
		this.currentPhoto = null;
		this.maxPhotoWidth = 0;
		this.minPhotoWidth = 190;
		this.rightPanelWidth = 214;
		this.leftPanelWidth = 190;
		this.index = 0;
		this.width = 0;
		this.left = 0;
		this.minWidth = this.element.width();
		this.width = this.minWidth;
		this.left = this.element.position().left;
		this.futurWidth = null;
		
		this.element.jquery_width = this.element.width;
		this.element.width = function (size) {
			if (size === undefined && self.futurWidth) {
				return self.futurWidth;
			} else {
				return this.jquery_width(size);
			}
		};
		this.element.jquery_position = this.element.position;
		this.element.position = function() {
			var position = this.jquery_position();
			if (self.galleryInstance.futurWidth && self.index > self.galleryInstance.animatingIndex) {
				position.left = position.left + self.galleryInstance.futurWidth - self.galleryInstance.oldWidth;
			}
			return position;
		};
		
		this.textPanel.find("*.nav a.button-close").click(
			function(event) {
				self.collapse();
				self.photoDisplay.animate({opacity:0}, 500);
				self.photoDisplayOver.animate({opacity:1}, 500);
			}
		);
		
		this.thumbnailListView = new jsx.widget.ListView(element.find("*.list-view").get(0));
		this.thumbnailListView.addListener(
			{
				productPanel :      this,
				thumbnailListView : this.thumbnailListView,
				onClick :           function(event) {
					this.thumbnailListView.selectItem(event.index);
					this.productPanel.showPhoto(event.index);
					this.productPanel.showDescription(event.index);
				}
			}
		);
		this.thumbnailListView.element.find("*.nav.top a").click(
			function(event) {
				var index = self.thumbnailListView.index;
				if (index > 0) {
					self.thumbnailListView.selectItem(index - 1);
					self.showPhoto(index - 1);
					self.showDescription(index - 1);
				}
			}
		);
		this.thumbnailListView.element.find("*.nav.bottom a").click(
			function(event) {
				var index = self.thumbnailListView.index;
				if (index < self.thumbnailListView.size() - 1) {
					self.thumbnailListView.selectItem(index + 1);
					self.showPhoto(index + 1);
					self.showDescription(index + 1);
				}
			}
		);
		
		this.centerLoadIcon();
    };
	jsx.widget.ProductPanel.prototype.resizeThumbnailListContentPanel = function() {
		var height = this.thumbnailListPanel.height();
		this.thumbnailListPanel.find("*.nav").each(
			function() {
				height -= $(this).height();
			}
		);
		this.thumbnailListPanel.find("div.thumbnail-list-content-panel").height(height);
	};
	jsx.widget.ProductPanel.prototype.attachListeners = function() {
		var self = this;
		
		this.photoListPanel.hover(
			function() {
				if (!self.element.hasClass("expanded")) {
					self.photoDisplay.addClass('hover');
					self.photoDisplay.stop();
					self.photoDisplay.animate({opacity:1}, 1000);
					self.photoDisplayOver.stop();
					self.photoDisplayOver.animate({opacity:0}, 1000);
				}
			} ,
			function() {
				if (!self.element.hasClass("expanded")) {
					self.photoDisplay.removeClass('hover');
					self.photoDisplay.stop();
					self.photoDisplay.animate({opacity:0}, 500);
					self.photoDisplayOver.stop();
					self.photoDisplayOver.animate({opacity:1}, 500);
				}
			}
		);
		
		this.photoListPanel.click(
			function() {
				if (self.element.hasClass("expanded")) {
					self.collapse(true);
				} else {
					self.expand();
				}
			}
		);
	};
	jsx.widget.ProductPanel.prototype.loadThumbnails = function() {
		var count, ctr, images, self = this;
		images = this.thumbnailList.add(this.photoList.eq(0));
		count = images.size();
		ctr = 0;
		
		images.each(
			function() {
				$(new Image()).load(
					function() {
						if (++ctr >= count) {
							self.fireThumbnailsLoaded();
						}
					}
				).attr("src", this.src);
			}
		);
	};
	jsx.widget.ProductPanel.prototype.loadPhotos = function() {
		var count, ctr, images, self = this;
		images = this.photoList;
		count = images.size();
		ctr = 0;
		
		images.each(
			function() {
				$(new Image()).load(
					function() {
						if (++ctr >= count) {
							self.firePhotosLoaded();
						}
					}
				).attr("src", this.src);
			}
		);
	};
	jsx.widget.ProductPanel.prototype.fireThumbnailsLoaded = function() {
		this.show();
	};
	jsx.widget.ProductPanel.prototype.firePhotosLoaded = function() {
	};
	jsx.widget.ProductPanel.prototype.show = function() {
		var self = this;
		
		if (!this.visible) {
			this.photoList.each(
				function(i) {
					self.maxPhotoWidth = Math.max(self.maxPhotoWidth, $(this).width());
				}
			);
			
			this.photoDisplay.css("opacity", 0);
			this.photoDisplay.removeClass("preload");
			this.photoDisplayOver.css("opacity", 0);
			this.photoDisplayOver.removeClass("preload");
			this.photoList.each(
				function() {
					$(this).css("opacity", 0);
					$(this).removeClass("preload");
					$(this).animate({opacity:1}, 
						{
							complete:function() {
								self.textPanel.removeClass('no-display');
								self.thumbnailListPanel.removeClass('no-display');
								self.resizeThumbnailListContentPanel();
								self.thumbnailListView.selectItem(0);
								self.showPhoto(0);
								self.showDescription(0);
							},
							duration:500
						}
					);
				}
			);
			this.photoDisplayOver.animate({opacity:1});
			setTimeout(function(){
				if (!self.photoDisplay.hasClass('hover')) {
					self.photoDisplay.stop();
					self.photoDisplay.animate({opacity:0}, 1000);
				}
			}, this.index*500 + 3000);
			this.photoDisplay.animate({opacity:1});
			this.attachListeners();
			this.photoLoadIcon.animate({opacity:0}, 
				{
					complete:function() {
						$(this).addClass('hidden').css('opacity', 1);
					},
					duration:500
				}
			);
			this.resizeDescription();
			this.visible = true;
		}
	};
	jsx.widget.ProductPanel.prototype.expand = function() {
		var self = this, index, dwidth;
		
		dwidth = this.maxPhotoWidth + this.rightPanelWidth + this.leftPanelWidth - this.minPhotoWidth + 2;
		this.futurWidth = this.minPhotoWidth + dwidth;
		this.galleryInstance.oldWidth = this.galleryInstance.contentPanel.width();
		this.galleryInstance.futurWidth = this.galleryInstance.oldWidth + dwidth;
		this.galleryInstance.animatingIndex = this.index;
		
		this.element.addClass("expanded");
		
		this.galleryInstance.gotoPanel(this.index);
		
		if (this.lastPhoto) {
			index = this.photoList.index(this.lastPhoto);
			this.showPhoto(index, {transition:'dissolve'});
		}
		
		this.width = this.maxPhotoWidth + this.rightPanelWidth + this.leftPanelWidth;
		this.photoListPanel.animate(
			{
				width:this.maxPhotoWidth,
				marginRight:this.rightPanelWidth,
				marginLeft:this.leftPanelWidth
			},
			{
				complete:function() { 
					self.galleryInstance.animatingIndex = null;
					self.futurWidth = null; 
					self.galleryInstance.futurWidth = null; 
					self.galleryInstance.oldWidth = 0;
					self.fireResizeEvent(this); 
				}
			}
		);	
		this.photoDisplay.stop();
		this.photoDisplay.animate({opacity:0}, 500);
	};
	jsx.widget.ProductPanel.prototype.collapse = function(showLabel) {
		var self = this, photo, panel;
		
		
		this.fireCollapseEvent(this);
		
		panel = this.galleryInstance.productPanelList[this.galleryInstance.currentPanelIndex];
		
		dwidth = this.minPhotoWidth - this.maxPhotoWidth - this.rightPanelWidth - this.leftPanelWidth;
		this.futurWidth = this.element.width() + dwidth;
		this.galleryInstance.oldWidth = this.galleryInstance.contentPanel.width();
		this.galleryInstance.futurWidth = this.galleryInstance.oldWidth + dwidth;
		this.galleryInstance.animatingIndex = this.index;
		
		if (this.galleryInstance.currentPanelIndex != this.index) {
			this.galleryInstance.gotoPanel(this.galleryInstance.currentPanelIndex);
		} else  {
			this.galleryInstance.gotoPanel(this.index);
		}
		this.element.removeClass("expanded");
		
		this.lastPhoto = this.currentPhoto;
		this.showPhoto(0, {transition:'dissolve'});
		
		this.photoListPanel.animate(
			{
				width:this.minPhotoWidth,
				marginRight:0,
				marginLeft:0
			},
			{
				complete:function() { 
					self.galleryInstance.animatingIndex = null;
					self.futurWidth = null; 
					self.galleryInstance.futurWidth = null; 
					self.galleryInstance.oldWidth = 0;
					self.fireResizeEvent(this);
				}
			}
		);
			
		if (showLabel) {
			this.photoDisplay.stop();
			this.photoDisplay.animate({opacity:1}, 1000);
		}
	};
	jsx.widget.ProductPanel.prototype.fireResizeEvent = function(source) {
		var i, listener;
		i = 0;
		while (listener = this.listenerArray[i++]) {
			if (typeof listener.onResize == "function") {
				listener.onResize({source:source});
			}
		}
	};
	jsx.widget.ProductPanel.prototype.fireExpandEvent = function(source) {
		var i, listener;
		i = 0;
		while (listener = this.listenerArray[i++]) {
			if (typeof listener.onExpand == "function") {
				listener.onExpand({source:source});
			}
		}
	};
	jsx.widget.ProductPanel.prototype.fireCollapseEvent = function(source) {
		var i, listener;
		i = 0;
		while (listener = this.listenerArray[i++]) {
			if (typeof listener.onCollapse == "function") {
				listener.onCollapse({source:source});
			}
		}
	};
	jsx.widget.ProductPanel.prototype.centerLoadIcon = function() {
		var width, height, icon, left, top;
		width = this.photoListPanel.width();
		height = this.photoListPanel.height();
		icon = this.photoListPanel.find("img.load-icon");
		left = (width - icon.width()) / 2;
		top = (height - icon.height()) / 2;
		icon.css("left", left);
		icon.css("top", top);
	};
	jsx.widget.ProductPanel.prototype.centerPhotoDisplay = function() {
		var width, height, icon, left, top;
		height = this.photoListPanel.height();
		icon = this.photoDisplay;
		top = (height - icon.height()) / 2;
		/*icon.css("left", left);*/
		icon.css("top", top);
	};
	jsx.widget.ProductPanel.prototype.showPhoto = function(index, options) {
		var bgPhoto, fgPhoto, firstTime = false;
		
		fgPhoto = this.photoList.eq(index);
		if (!this.currentPhoto || fgPhoto.get(0) != this.currentPhoto.get(0)) {
			if (!this.currentPhoto) {
				this.photoList.addClass('background').removeClass('foreground').addClass('hidden');
				this.currentPhoto = this.photoList.eq(0).removeClass('hidden');
				bgPhoto = this.currentPhoto;
				firstTime = true;
			} else {
				this.currentPhoto.addClass('background').removeClass('foreground');
				bgPhoto = this.currentPhoto;
			}
			function hideBgPhoto() {
				if (bgPhoto) {
					bgPhoto.addClass('hidden');
				}
			};
			if ((firstTime && index != 0) || !firstTime) {
				this.currentPhoto = fgPhoto;
				if (!options || !options.transition) {
					this.wipe(fgPhoto, hideBgPhoto);
				} else {
					switch (options.transition) {
						case 'wipe':
							this.wipe(fgPhoto, hideBgPhoto);
							break;
						case 'dissolve':
							this.dissolve(fgPhoto, hideBgPhoto);
							break;
					}
				}
			}
		}
	};
	jsx.widget.ProductPanel.prototype.showDescription = function(index) {
		this.descriptionPanel.html('');
		this.descriptionPanel.html(this.descriptionList[index]);
	};
	jsx.widget.ProductPanel.prototype.resizeDescription = function(index) {
	};
	jsx.widget.ProductPanel.prototype.wipe = function(elem, callback) {
		elem.addClass('foreground');
		elem.css('left', -this.currentPhoto.width());
		elem.removeClass('hidden');
		
		elem.animate({left:0}, 
			{
				complete:function() {
					if (typeof callback == "function") {
						callback();
					}
				}
			},
			500
		);
	};
	jsx.widget.ProductPanel.prototype.dissolve = function(elem, callback) {
		elem.addClass('foreground');
		elem.css('opacity', 0);
		elem.removeClass('hidden');
		
		elem.animate({opacity:1}, 
			{
				complete:function() {
					if (typeof callback == "function") {
						callback();
					}
				}
			},
			500
		);
	};
})();