
/*author: chj*/
(function ($) {
	$.fn.flash = function (options) {
		var defaults = {
			loader_image:"/images/huandeng/loader.gif", 
			start_at_index:0, 
			clickElement:"a", 
			selectElement:"li", 
			animate_first_image:false, 
			animation_speed:400, 
			slideshow:{autostart:true, speed:5000}, 
			effect:"fade", // or 'slide-vert', 'fade', or 'resize', 'none'
			cycle:true
		};
		var settings = $.extend(false, defaults, options);
		if (options && options.slideshow) {
			settings.slideshow = $.extend(false, defaults.slideshow, options.slideshow);
		}
		var galleries = [];
		$(this).each(function () {
			var gallery = new Gallery(this, settings);
			galleries[galleries.length] = gallery;
		});
	    // Sorry, breaking the jQuery chain because the gallery instances
	    // are returned so you can fiddle with them
		return galleries;
	};
	function VerticalSlideAnimation(img_container, direction, desc) {
		var current_top = parseInt(img_container.css("top"), 10);
		if (direction == "left") {
			var old_image_top = "-" + this.image_wrapper_height + "px";
			img_container.css("top", this.image_wrapper_height + "px");
		} else {
			var old_image_top = this.image_wrapper_height + "px";
			img_container.css("top", "-" + this.image_wrapper_height + "px");
		}
		if (desc) {
			desc.css("bottom", "-" + desc[0].offsetHeight + "px");
			desc.animate({bottom:0}, this.settings.animation_speed * 2);
		}
		return {old_image:{top:old_image_top}, new_image:{top:current_top}};
	}
	function HorizontalSlideAnimation(img_container, direction, desc) {
		var current_left = parseInt(img_container.css("left"), 10);
		if (direction == "left") {
			var old_image_left = "-" + this.image_wrapper_width + "px";
			img_container.css("left", this.image_wrapper_width + "px");
		} else {
			var old_image_left = this.image_wrapper_width + "px";
			img_container.css("left", "-" + this.image_wrapper_width + "px");
		}
		if (desc) {
			desc.css("bottom", "-" + desc[0].offsetHeight + "px");
			desc.animate({bottom:0}, this.settings.animation_speed * 2);
		}
		return {old_image:{left:old_image_left}, new_image:{left:current_left}};
	}
	function ResizeAnimation(img_container, direction, desc) {
		var image_width = img_container.width();
		var image_height = img_container.height();
		var current_left = parseInt(img_container.css("left"), 10);
		var current_top = parseInt(img_container.css("top"), 10);
		img_container.css({width:0, height:0, top:this.image_wrapper_height / 2, left:this.image_wrapper_width / 2});
		return {old_image:{width:0, height:0, top:this.image_wrapper_height / 2, left:this.image_wrapper_width / 2}, new_image:{width:image_width, height:image_height, top:current_top, left:current_left}};
	}
	function FadeAnimation(img_container, direction, desc) {
		img_container.css("opacity", 0);
		return {old_image:{opacity:0}, new_image:{opacity:1}};
	}
	
	  // Sort of a hack, will clean this up... eventually
	function NoneAnimation(img_container, direction, desc) {
		img_container.css("opacity", 0);
		return {old_image:{opacity:0}, new_image:{opacity:1}, speed:0};
	}
	function Gallery(wrapper, settings) {
		this.init(wrapper, settings);
	}
	Gallery.prototype = {wrapper:false, settings:false, flash_wrapper:false, image_wrapper:false, title_wrapper:false, flash_nav:false, loader:false, preloads:false, slideshow:false, current_index:0, current_image:false, settings:false, images:false, in_transition:false, animations:false, init:function (wrapper, settings) {
		var context = this;
		this.wrapper = $(wrapper);
		this.settings = settings;
		this.setupElements();
		this.setupAnimations();
		this.image_wrapper_width = this.image_wrapper.width();
		this.image_wrapper_height = this.image_wrapper.height();
		this.current_index = 0;
		this.current_image = false;
		this.in_transition = false;
		this.findImages();
		var nextimage_callback = function (callback) {
			return context.nextImage(callback);
		};
		this.slideshow = new Slideshow(nextimage_callback, this.settings.slideshow);
		var start_at = this.settings.start_at_index;
		this.loading(true);
		this.showImage(start_at, function () {
	          // We don't want to start the slideshow before the image has been
	          // displayed
			if (context.settings.slideshow.autostart) {
				context.preloadImage(start_at + 1);
				context.slideshow.start();
			}
		});
	}, setupElements:function () {
		this.flash_wrapper = this.wrapper;
		this.image_wrapper = this.flash_wrapper.find(".image_wrapper");
		this.title_wrapper = this.flash_wrapper.find(".title_wrapper");
		this.flash_nav = this.wrapper.find(".flash_nav");
		this.preloads = $("<div class=\"flash_preloads\"></div>");
		this.loader = $("<img src=\"" + this.settings.loader_image + "\">");
		this.image_wrapper.append(this.loader);
		this.loader.hide();
		$(document.body).append(this.preloads);
	}, setupAnimations:function () {
		this.animations = {"slide-vert":VerticalSlideAnimation, "slide-hori":HorizontalSlideAnimation, "resize":ResizeAnimation, "fade":FadeAnimation, "none":NoneAnimation};
	}, loading:function (bool) {
		if (bool) {
			this.loader.show();
		} else {
			this.loader.hide();
		}
	}, addAnimation:function (name, fn) {
		if ($.isFunction(fn)) {
			this.animations[name] = fn;
		}
	}, findImages:function () {
		var context = this;
		this.images = [];
		var clicks = this.flash_nav.find(this.settings.clickElement);
		clicks.each(function (i) {
			var clickelement = $(this);
			clickelement.click(function () {
				context.showImage(i);
				return false;
			});
			var imgsrc = clickelement.data("flash_imgsrc");
			var linktarget = clickelement.data("flash_linktarget");
			var title = clickelement.data("flash_title");
			context.images[i] = {image:imgsrc, link:linktarget, title:title, preloaded:false, error:false, size:false};
		});
	}, _getContainedImageSize:function (image_width, image_height) {		
		if (image_width > this.image_wrapper_width) {
			var ratio = image_height / image_width;
			image_width = this.image_wrapper_width;
			image_height = this.image_wrapper_width * ratio;
		}
		return {width:image_width, height:image_height};
	}, _centerImage:function (img_container, image_width, image_height) {
		img_container.css("top", "0px");
		if (image_height < this.image_wrapper_height) {
			var dif = this.image_wrapper_height - image_height;
			img_container.css("top", (dif / 2) + "px");
		}
		img_container.css("left", "0px");
		if (image_width < this.image_wrapper_width) {
			var dif = this.image_wrapper_width - image_width;
			img_container.css("left", (dif / 2) + "px");
		}
	}, nextIndex:function () {
		if (this.current_index == (this.images.length - 1)) {
			if (!this.settings.cycle) {
				return false;
			}
			var next = 0;
		} else {
			var next = this.current_index + 1;
		}
		return next;
	}, nextImage:function (callback) {
		var next = this.nextIndex();
		if (next === false) {
			return false;
		}
		this.preloadImage(next + 1);
		this.showImage(next, callback);
		return true;
	}, prevIndex:function () {
		if (this.current_index == 0) {
			if (!this.settings.cycle) {
				return false;
			}
			var prev = this.images.length - 1;
		} else {
			var prev = this.current_index - 1;
		}
		return prev;
	}, prevImage:function (callback) {
		var prev = this.prevIndex();
		if (prev === false) {
			return false;
		}
		this.preloadImage(prev - 1);
		this.showImage(prev, callback);
		return true;
	}, preloadAll:function () {
		var context = this;
		var i = 0;
		function preloadNext() {
			if (i < context.images.length) {
				i++;
				context.preloadImage(i, preloadNext);
			}
		}
		context.preloadImage(i, preloadNext);
	}, showImage:function (index, callback) {
		if (this.images[index] && !this.in_transition) {
			var context = this;
			var image = this.images[index];
			this.in_transition = true;
			if (!image.preloaded) {
				this.loading(true);
				this.preloadImage(index, function () {
					context.loading(false);
					context._showWhenLoaded(index, callback);
				});
			} else {
				this._showWhenLoaded(index, callback);
			}
		}
	}, _showWhenLoaded:function (index, callback) {
		if (this.images[index]) {
			var context = this;
			var image = this.images[index];
			var img_container = $(document.createElement("div"));
			var img = $(new Image()).attr("src", image.image);
			if (image.link) {
				img_container.append($("<a target='_blank' href='"+image.link+"'></a>").html(img));
			} else {
				img_container.append(img);
			}
			this.image_wrapper.prepend(img_container);
	        var size = this._getContainedImageSize(image.size.width, image.size.height);
			//var size = {width:context.image_wrapper_width, height:context.image_wrapper_height};
			img.attr("width", size.width);
			img.attr("height", size.height);
			img_container.css({width:size.width + "px", height:size.height + "px"});
			this._centerImage(img_container, size.width, size.height);
			if (this.title_wrapper && image.title) {
				this.title_wrapper.text(image.title);
			}
			this.selectElementSelect(this.flash_nav.find(this.settings.selectElement).filter(this.settings.clickElement + ".nav" + index + ",:has(>" + this.settings.clickElement + ".nav" + index + ")"));
			var direction = "right";
			if (this.current_index < index) {
				direction = "left";
			}
			if (this.current_image || this.settings.animate_first_image) {
				var animation_speed = this.settings.animation_speed;
				var easing = "swing";
				var animation = this.animations[this.settings.effect].call(this, img_container, direction);
				if (typeof animation.speed != "undefined") {
					animation_speed = animation.speed;
				}
				if (typeof animation.easing != "undefined") {
					easing = animation.easing;
				}
				if (this.current_image) {
					var old_image = this.current_image;
					old_image.animate(animation.old_image, animation_speed, easing, function () {
						old_image.remove();
					});
				}
				img_container.animate(animation.new_image, animation_speed, easing, function () {
					context.current_index = index;
					context.current_image = img_container;
					context.in_transition = false;
					context.fireCallback(callback);
				});
			} else {
				this.current_index = index;
				this.current_image = img_container;
				this.in_transition = false;
				this.fireCallback(callback);
			}
		}
	}, preloadImage:function (index, callback) {
		if (this.images[index]) {
			var image = this.images[index];
			if (!this.images[index].preloaded) {
				var img = $(new Image());
				img.attr("src", image.image);
				if (!this.isImageLoaded(img[0])) {
					this.preloads.append(img);
					var context = this;
					img.load(function () {
						image.preloaded = true;
						image.size = {width:this.width, height:this.height};
						context.fireCallback(callback);
					}).error(function () {
						image.error = true;
						image.preloaded = false;
						image.size = false;
					});
				} else {
					image.preloaded = true;
					image.size = {width:img[0].width, height:img[0].height};
					this.fireCallback(callback);
				}
			} else {
				this.fireCallback(callback);
			}
		}
	}, isImageLoaded:function (img) {
		if (typeof img.complete != "undefined" && !img.complete) {
			return false;
		}
		if (typeof img.naturalWidth != "undefined" && img.naturalWidth == 0) {
			return false;
		}
		return true;
	}, selectElementSelect:function (sel) {
		sel.siblings(".select").removeClass("select");
		sel.addClass("select");
	}, fireCallback:function (fn) {
		if ($.isFunction(fn)) {
			fn.call(this);
		}
	}};
	function Slideshow(nextimage_callback, settings) {
		this.init(nextimage_callback, settings);
	}
	Slideshow.prototype = {settings:false, running:false, nextimage_callback:false, countdown_interval:false, init:function (nextimage_callback, settings) {
		var context = this;
		this.nextimage_callback = nextimage_callback;
		this.settings = settings;
	}, start:function () {
		if (this.running) {
			return false;
		}
		var context = this;
		this.running = true;
		this._next();
		return true;
	}, stop:function () {
		if (!this.running) {
			return false;
		}
		this.running = false;
		clearInterval(this.countdown_interval);
		return true;
	}, _next:function () {
		var context = this;
		clearInterval(context.countdown_interval);
		var slide_timer = 0;
		this.countdown_interval = setInterval(function () {
			slide_timer += 1000;
			if (slide_timer >= context.settings.speed) {
				var whenNextIsShown = function () {
	              // A check so the user hasn't stoped the slideshow during the
	              // animation
					if (context.running) {
						context._next();
					}
					slide_timer = 0;
				};
				if (!context.nextimage_callback(whenNextIsShown)) {
					context.stop();
				}
				slide_timer = 0;
			}
		}, 1000);
	}};
})(jQuery);

