/** * Copyright (c) 2010 Anders Ekdahl (http://coffeescripter.com/) * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. * * Version: 1.2.4 * * Demo and documentation: http://coffeescripter.com/code/ad-gallery/ */(function($) {	$.fn.adGallery = function(options) {		var defaults = { loader_image: 'resources/imageGallery/loader.png',			start_at_index: 0,			description_wrapper:$('#descriptions'),			descriptCont_wrapper:$('#descriptCont'),			adImageWrapper:$('.ad-image-wrapper'),			thumb_opacity: 0.5,			animate_first_image: false,			animation_speed: 400,			width: false,			height: false,			display_next_and_prev: true,			display_back_and_forward: true,			display_slideShowControls: true,			scroll_jump: 0, // If 0, it jumps the width of the container			slideshow: {				enable: true,				autostart: false,				speed: 5000,				start_label: 'Start',				stop_label: 'Stop',				stop_on_scroll: true,				countdown_prefix: '(',				countdown_sufix: ')',				onStart: false,				onStop: false			},			effect: 'fade', // 'slide-hori', 'slide-vert', 'fade', or 'resize', 'none'			enable_keyboard_move: true,			cycle: true,			callbacks: {				init: false,				afterImageVisible: false,				beforeImageVisible: false			}		};		var settings = $.extend(false, defaults, options);		if(options && options.slideshow) {			settings.slideshow = $.extend(false, defaults.slideshow, options.slideshow);		};		if(!settings.slideshow.enable) {			settings.slideshow.autostart = false;		};		var galleries = [];		$(this).each(function() {			var gallery = new AdGallery(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);    };    if(this.current_description) {      this.current_description.animate({bottom: '-'+ this.current_description[0].offsetHeight +'px'}, 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);    };    if(this.current_description) {      this.current_description.animate({bottom: '-'+ this.current_description[0].offsetHeight +'px'}, 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 AdGallery(wrapper, settings) {		this.init(wrapper, settings);	};	AdGallery.prototype = {		// Elements		wrapper: false,		image_wrapper: false,		gallery_info: false,		nav: false,		loader: false,		preloads: false,		thumbs_wrapper: false,		scroll_back: false,		scroll_forward: false,		next_link: false,		prev_link: false,		slideshow: false,		image_wrapper_width: 0,		image_wrapper_height: 0,		current_index: 0,		current_image: false,		current_description: false,		nav_display_width: 0,		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();			if(this.settings.width) {				this.image_wrapper_width = this.settings.width;				this.image_wrapper.width(this.settings.width);				this.wrapper.width(this.settings.width);			} else {				this.image_wrapper_width = this.image_wrapper.width();			};			if(this.settings.height) {				this.image_wrapper_height = this.settings.height;				this.image_wrapper.height(this.settings.height);			} else {				this.image_wrapper_height = this.image_wrapper.height();			};			this.nav_display_width = this.nav.width();			this.current_index = 0;			this.current_image = false;			this.current_description = false;			this.in_transition = false;			this.findImages();			if(this.settings.display_next_and_prev) {				this.initNextAndPrev();			};			if(this.settings.display_slideShowControls) {				this.initSlideShowButton();			};			// The slideshow needs a callback to trigger the next image to be shown			// but we don't want to give it access to the whole gallery instance			var nextimage_callback = function(callback) {				return context.nextImage(callback);			};			this.slideshow = new AdGallerySlideshow(nextimage_callback, this.settings.slideshow);			this.controls.append(this.slideshow.create());			if(this.settings.slideshow.enable) {				this.slideshow.enable();			} else {				this.slideshow.disable();			};			if(this.settings.display_back_and_forward) {				this.initBackAndForward();			};			if(this.settings.enable_keyboard_move) {				this.initKeyEvents();			};			var start_at = parseInt(this.settings.start_at_index, 10);			if(window.location.hash && window.location.hash.indexOf('#ad-image') === 0) {				start_at = window.location.hash.replace(/[^0-9]+/g, '');				// Check if it's a number				if((start_at * 1) != start_at) {					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();				};			}		);		this.fireCallback(this.settings.callbacks.init);	},    setupAnimations: function() {      this.animations = {        'slide-vert': VerticalSlideAnimation,        'slide-hori': HorizontalSlideAnimation,        'resize': ResizeAnimation,        'fade': FadeAnimation,        'none': NoneAnimation      };    },    setupElements: function() {      this.controls = this.wrapper.find('.ad-controls');      this.gallery_info = $('<p class="ad-info"></p>');	  this.galleryCounter = this.wrapper.find('.ad-counter');      this.galleryCounter.append(this.gallery_info);      this.image_wrapper = this.wrapper.find('.ad-image-wrapper');      this.image_wrapper.empty();      this.nav = this.wrapper.find('.ad-nav');      this.thumbs_wrapper = this.nav.find('.ad-thumbs');      this.preloads = $('<div class="ad-preloads"></div>');      this.loader = $('<img class="ad-loader" src="'+ this.settings.loader_image +'">');      this.image_wrapper.append(this.loader);      this.loader.hide();      $(document.body).append(this.preloads);    },    loading: function(bool) {		var loadingTimer;		if(bool) {			var angle = 0;			loadingTimer = setInterval(function(){				angle+=7;				$('.ad-loader').rotate(angle);			},50);			this.loader.show();      } else {	  	clearInterval(loadingTimer);        this.loader.hide();		$('.ad-loader').rotate(0);		this.loader.hide();      };    },    addAnimation: function(name, fn) {      if($.isFunction(fn)) {        this.animations[name] = fn;      };    },    findImages: function() {      var context = this;      this.images = [];      var thumb_wrapper_width = 0;      var thumbs_loaded = 0;      var thumbs = this.thumbs_wrapper.find('a');      var thumb_count = thumbs.length;      if(this.settings.thumb_opacity < 1) {        thumbs.find('img').css('opacity', this.settings.thumb_opacity);      };      thumbs.each(        function(i) {          var link = $(this);          var image_src = link.attr('href');          var thumb = link.find('img');          // Check if the thumb has already loaded          if(!context.isImageLoaded(thumb[0])) {            thumb.load(              function() {                thumb_wrapper_width += this.parentNode.parentNode.offsetWidth;                thumbs_loaded++;              }            );          } else{            thumb_wrapper_width += thumb[0].parentNode.parentNode.offsetWidth;            thumbs_loaded++;          };          link.addClass('ad-thumb'+ i);          link.click(            function() {              context.showImage(i);              context.slideshow.stop();              return false;            }          ).hover(            function() {              if(!$(this).is('.ad-active') && context.settings.thumb_opacity < 1) {                $(this).find('img').fadeTo(300, 1);              };              context.preloadImage(i);            },            function() {              if(!$(this).is('.ad-active') && context.settings.thumb_opacity < 1) {                $(this).find('img').fadeTo(300, context.settings.thumb_opacity);              };            }          );          var link = false;          if(thumb.data('ad-link')) {            link = thumb.data('ad-link');          } else if(thumb.attr('longdesc') && thumb.attr('longdesc').length) {            link = thumb.attr('longdesc');          };          var desc = false;          if(thumb.data('ad-desc')) {            desc = thumb.data('ad-desc');          } else if(thumb.attr('alt') && thumb.attr('alt').length) {            desc = thumb.attr('alt');          };          var title = false;          if(thumb.data('ad-title')) {            title = thumb.data('ad-title');          } else if(thumb.attr('title') && thumb.attr('title').length) {            title = thumb.attr('title');          };          context.images[i] = { thumb: thumb.attr('src'), image: image_src, error: false,                                preloaded: false, desc: desc, title: title, size: false,                                link: link };		  galleryImages = context.images;        }      );      // Wait until all thumbs are loaded, and then set the width of the ul      var inter = setInterval(        function() {          if(thumb_count == thumbs_loaded) {            thumb_wrapper_width -= 100;            var list = context.nav.find('.ad-thumb-list');            list.css('width', thumb_wrapper_width +'px');            var i = 1;            var last_height = list.height();            while(i < 201) {              list.css('width', (thumb_wrapper_width + i) +'px');              if(last_height != list.height()) {                break;              }              last_height = list.height();              i++;            }            clearInterval(inter);			//center .ad-thumb-list if smaller than .ad-thumbs wrapper			if(list.width() < context.thumbs_wrapper.width()){				var thumbDif = (context.thumbs_wrapper.width() - list.width())/2;				list.css("margin-left", thumbDif);							};          };        },        100      );    },    initKeyEvents: function() {      var context = this;      $(document).keydown(        function(e) {          if(e.keyCode == 39) {            // right arrow            context.nextImage();            context.slideshow.stop();          } else if(e.keyCode == 37) {            // left arrow            context.prevImage();            context.slideshow.stop();          };        }      );    },	initNextAndPrev: function() {		//top bottons		this.next_top_link = this.controls.find('#ad-controller-left');		this.prev_top_link = this.controls.find('#ad-controller-right');		//side buttons		//this.next_link = $('<div id="ad-next"><div class="ad-last-image"></div><div id="ad-next-image" class="nextImage"></div></div>');		//this.prev_link = $('<div id="ad-prev"><div class="ad-first-image"></div><div id="ad-prev-image" class="prevImage"></div></div>');		this.next_link = $('<div id="ad-next"><div id="ad-last-image" class="lastImage"></div><div id="ad-next-image" class="nextImage"><div id="ad-next-top" class="nextTop"></div><div id="ad-next-middle"><div id="ad-next-mid-button" class="nextMidButton"></div><div id="ad-next-mid-background" class="nextMidBack"></div></div><div id="ad-next-bottom" class="nextBottom"></div></div></div>');		this.prev_link = $('<div id="ad-prev"><div id="ad-first-image" class="firstImage"></div><div id="ad-prev-image" class="prevImage"><div id="ad-prev-top" class="prevTop"></div><div id="ad-prev-middle"><div id="ad-prev-mid-button" class="prevMidButton"></div><div id="ad-prev-mid-background" class="prevMidBack"></div></div><div id="ad-prev-bottom" class="prevBottom"></div></div></div>');		this.image_wrapper.append(this.next_link);		this.image_wrapper.append(this.prev_link);				var context = this;				//top bottons		this.prev_top_link.add(this.next_top_link).mouseover(			function(e) {				// IE 6 hides the wrapper div, so we have to set it's width				//$(this).css('height', context.image_wrapper_height);				if($(this).is('#ad-controller-right')) {					$('#ad-controller-right').attr('class', 'adControllerRightOver');				}else{					$('#ad-controller-left').attr('class', 'adControllerLeftOver');				}			}		).mouseout(			function(e) {				if($(this).is('#ad-controller-right')) {					$('#ad-controller-right').attr('class', 'adControllerRight');				}else{					$('#ad-controller-left').attr('class', 'adControllerLeft');				}			}		).click(			function() {				if ($(this).is('#ad-controller-right')) {					context.nextImage();					context.slideshow.stop();				}else{					context.prevImage();					context.slideshow.stop();				};			}      	);				//side buttons		this.prev_link.add(this.next_link).mouseover(			function(e) {				// IE 6 hides the wrapper div, so we have to set it's width				$(this).css('height', context.image_wrapper_height);				/* $(this).find('div').show();*/			   				if($(this).is('#ad-next')) {					$('#ad-last-image').attr('class', 'lastImageOver');					$('#ad-next-top').attr('class', 'nextTopOver');					$('#ad-next-mid-button').attr('class', 'nextMidButtonOver');					$('#ad-next-mid-background').attr('class', 'nextMidBackOver');					$('#ad-next-bottom').attr('class', 'nextBottomOver');				}else{					$('#ad-first-image').attr('class', 'firstImageOver');					$('#ad-prev-top').attr('class', 'prevTopOver');					$('#ad-prev-mid-button').attr('class', 'prevMidButtonOver');					$('#ad-prev-mid-background').attr('class', 'prevMidBackOver');					$('#ad-prev-bottom').attr('class', 'prevBottomOver');				}			}		).mouseout(			function(e) {				/*$(this).find('div').hide();*/				if($(this).is('#ad-next')) {					$('#ad-last-image').attr('class', 'lastImage');					$('#ad-next-top').attr('class', 'nextTop');					$('#ad-next-mid-button').attr('class', 'nextMidButton');					$('#ad-next-mid-background').attr('class', 'nextMidBack');					$('#ad-next-bottom').attr('class', 'nextBottom');				}else{					$('#ad-first-image').attr('class', 'firstImage');					$('#ad-prev-top').attr('class', 'prevTop');					$('#ad-prev-mid-button').attr('class', 'prevMidButton');					$('#ad-prev-mid-background').attr('class', 'prevMidBack');					$('#ad-prev-bottom').attr('class', 'prevBottom');				}			}		).click(			function(e) {				var $target = $(e.target);				if ( $target.is("#ad-last-image") ) {					context.lastImage();					context.slideshow.stop();				}else if ( $target.is("#ad-first-image") ) {					context.firstImage();					context.slideshow.stop();				}else if ($(this).is('#ad-next')) {					context.nextImage();					context.slideshow.stop();				}else{					context.prevImage();					context.slideshow.stop();				};			}      	);    },    initBackAndForward: function() {      var context = this;      this.scroll_forward = $('<div class="ad-forward"></div>');      this.scroll_back = $('<div class="ad-back"></div>');      this.nav.append(this.scroll_forward);      this.nav.prepend(this.scroll_back);      var has_scrolled = 0;      var thumbs_scroll_interval = false;      $(this.scroll_back).add(this.scroll_forward).click(        function() {          // We don't want to jump the whole width, since an image          // might be cut at the edge          var width = context.nav_display_width - 50;          if(context.settings.scroll_jump > 0) {            var width = context.settings.scroll_jump;          };          if($(this).is('.ad-forward')) {            var left = context.thumbs_wrapper.scrollLeft() + width;          } else {            var left = context.thumbs_wrapper.scrollLeft() - width;          };          if(context.settings.slideshow.stop_on_scroll) {            context.slideshow.stop();          };          context.thumbs_wrapper.animate({scrollLeft: left +'px'});          return false;        }      ).css('opacity', 0.6).hover(        function() {          var direction = 'left';          if($(this).is('.ad-forward')) {            direction = 'right';          };          thumbs_scroll_interval = setInterval(            function() {              has_scrolled++;              // Don't want to stop the slideshow just because we scrolled a pixel or two              if(has_scrolled > 30 && context.settings.slideshow.stop_on_scroll) {                context.slideshow.stop();              };              var left = context.thumbs_wrapper.scrollLeft() + 1;              if(direction == 'left') {                left = context.thumbs_wrapper.scrollLeft() - 1;              };              context.thumbs_wrapper.scrollLeft(left);            },            10          );          $(this).css('opacity', 1);        },        function() {          has_scrolled = 0;          clearInterval(thumbs_scroll_interval);          $(this).css('opacity', 0.6);        }      );    },	initSlideShowButton: function(){		this.slideShowControl = this.wrapper.find('#ad-controller-mid');		var context = this;				this.slideShowControl.mouseover(function(){			// IE 6 hides the wrapper div, so we have to set it's width			//$(this).css('height', context.image_wrapper_height);			if(context.slideshow.running) {				$('#ad-controller-mid').attr('class', 'adControllerPauseOver');			}else{				$('#ad-controller-mid').attr('class', 'adControllerPlayOver');			}		}).mouseout(function(){			if(context.slideshow.running) {				$('#ad-controller-mid').attr('class', 'adControllerPause');			}else{				$('#ad-controller-mid').attr('class', 'adControllerPlay');			}		}).click(function(){			if(context.slideshow.running) {				context.slideshow.stop();				$('#ad-controller-mid').attr('class', 'adControllerPlay');			}else{				context.nextImage();				context.slideshow.start();				$('#ad-controller-mid').attr('class', 'adControllerPause');			};		});	},    _afterShow: function() {      this.gallery_info.html((this.current_index + 1) +' / '+ this.images.length);      if(!this.settings.cycle) {        // Needed for IE        this.prev_link.show().css('height', this.image_wrapper_height);        this.next_link.show().css('height', this.image_wrapper_height);        if(this.current_index == (this.images.length - 1)) {          this.next_link.hide();        };        if(this.current_index == 0) {          this.prev_link.hide();        };      };      this.fireCallback(this.settings.callbacks.afterImageVisible);    },    /**     * Checks if the image is small enough to fit inside the container     * If it's not, shrink it proportionally     */    _getContainedImageSize: function(image_width, image_height) {	  var navWidth = this.wrapper.find('#ad-prev-image').width();	  var sizeMinusNav = this.image_wrapper_width - (2*navWidth);      if(image_height > this.image_wrapper_height) {        var ratio = image_width / image_height;        image_height = this.image_wrapper_height;        image_width = this.image_wrapper_height * ratio;      };      if(image_width > this.image_wrapper_width) {  	    var ratio = image_height / image_width;  	    image_width = sizeMinusNav;  	    image_height = sizeMinusNav * ratio;  	  };      return {width: image_width, height: image_height};    },    /**     * If the image dimensions are smaller than the wrapper, we position     * it in the middle anyway     */    _centerImage: function(img_container, image_width, image_height, image_side) {      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');	  var navWidth = this.wrapper.find('#ad-prev-image').width();	  var sizeMinusNav = this.image_wrapper_width - navWidth;      if(image_width < this.image_wrapper_width) {        var dif = this.image_wrapper_width - image_width;		if(image_side == "right"){			img_container.css('left', dif - navWidth + 'px');		}else if(image_side == "left"){			img_container.css('left', navWidth +'px');		}else{       		img_container.css('left', (dif / 2) +'px');		}      };    },    _getDescription: function(image) {      var desc = false;      if(image.desc.length || image.title.length) {        var title = '';        if(image.title.length) {          title = '<strong class="ad-description-title">'+ image.title +'</strong>';        };        var desc = '';        if(image.desc.length) {          desc = '<span>'+ image.desc +'</span>';        };        desc = $('<p class="ad-image-description">'+ title + '<br />' + desc +'</p>');      };      return desc;    },    /**     * @param function callback Gets fired when the image has loaded, is displaying     *                          and it's animation has finished     */    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);        };      };    },    /**     * @param function callback Gets fired when the image has loaded, is displaying     *                          and it's animation has finished     */    _showWhenLoaded: function(index, callback) {      if(this.images[index]) {        var context = this;        var image = this.images[index];        var img_container = $(document.createElement('div')).addClass('ad-image');        var img = $(new Image()).attr('src', image.image);        if(image.link) {          var link = $('<a href="'+ image.link +'" target="_blank"></a>');          link.append(img);		  link.lightBox();          img_container.append(link);        } else {          img_container.append(img);        };        this.image_wrapper.prepend(img_container);        var size = this._getContainedImageSize(image.size.width, image.size.height);        img.attr('width', size.width);        img.attr('height', size.height);        img_container.css({width: size.width +'px', height: size.height +'px'});		//first image to right		if(index == 0){			this._centerImage(img_container, size.width, size.height, "right");		}else if(index == (this.images.length - 1)){ //last image to left			this._centerImage(img_container, size.width, size.height, "left");		}else{ //all else centered			this._centerImage(img_container, size.width, size.height);		}		//resize side navigation if needed		var navHeight = this.wrapper.find('#ad-next').height();		if(navHeight != size.height){			//wrapper			this.wrapper.find('#ad-next').css('height', size.height + 'px');			this.wrapper.find('#ad-prev').css('height', size.height + 'px');			//middle			var navEndHeights = (this.wrapper.find('#ad-next-top').height())*2;			var midHeight = size.height - navEndHeights;			this.wrapper.find('#ad-next-middle').css('height', midHeight + 'px');			this.wrapper.find('#ad-prev-middle').css('height', midHeight + 'px');			//bottom			this.wrapper.find('#ad-next-bottom').css('top', (midHeight + navEndHeights/2) + 'px');			this.wrapper.find('#ad-prev-bottom').css('top', (midHeight + navEndHeights/2) + 'px');			//center middle arrow			var buttonHeight = this.wrapper.find('#ad-next-mid-button').height();			this.wrapper.find('#ad-next-mid-button').css('top', (midHeight - buttonHeight)/2 + 'px');			this.wrapper.find('#ad-prev-mid-button').css('top', (midHeight - buttonHeight)/2 + 'px');			//center entire nav bar			var navDif = this.image_wrapper_height - size.height;			this.wrapper.find('#ad-next').css('top', (navDif / 2) + 'px');			this.wrapper.find('#ad-prev').css('top', (navDif / 2) + 'px');		}		        var desc = this._getDescription(image, img_container);        if(desc) {		  var adImageWrapperTop = parseInt(this.settings.adImageWrapper.css('top'), 10);          if(!this.settings.description_wrapper) {            img_container.append(desc);            /*var width = size.width - parseInt(desc.css('padding-left'), 10) - parseInt(desc.css('padding-right'), 10);            desc.css('width', width +'px');*/          } else {            this.settings.description_wrapper.append(desc);          }		  this.settings.descriptCont_wrapper.css({height: size.height +'px', top: adImageWrapperTop + 'px'});		  if(size.height < this.image_wrapper_height) {        		var dDif = this.image_wrapper_height - size.height;        		this.settings.descriptCont_wrapper.css({top: (adImageWrapperTop + (dDif / 2)) +'px'});      	  }        };        this.highLightThumb(this.nav.find('.ad-thumb'+ index));        var direction = 'right';        if(this.current_index < index) {          direction = 'left';        };        this.fireCallback(this.settings.callbacks.beforeImageVisible);        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, desc);          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;            var old_description = this.current_description;			if(old_description) old_description.remove();            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.current_description = desc;              context.in_transition = false;              context._afterShow();              context.fireCallback(callback);            }          );        } else {          this.current_index = index;          this.current_image = img_container;          context.current_description = desc;          this.in_transition = false;          context._afterShow();          this.fireCallback(callback);        };      };    },    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;    },	firstImage: function(callback) {		if(this.current_index != 0) {			this.preloadImage(0);			this.showImage(0, 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;    },	 lastImage: function(callback) {	 	if(this.current_index != this.images.length - 1) {	 		this.preloadImage(this.images.length - 1);	 		this.showImage(this.images.length - 1, 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);    },    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;    },    highLightThumb: function(thumb) {      this.thumbs_wrapper.find('.ad-active').removeClass('ad-active');      thumb.addClass('ad-active');      if(this.settings.thumb_opacity < 1) {        this.thumbs_wrapper.find('a:not(.ad-active) img').fadeTo(300, this.settings.thumb_opacity);        thumb.find('img').fadeTo(300, 1);      };      var left = thumb[0].parentNode.offsetLeft;      left -= (this.nav_display_width / 2) - (thumb[0].offsetWidth / 2);      this.thumbs_wrapper.animate({scrollLeft: left +'px'});    },    fireCallback: function(fn) {      if($.isFunction(fn)) {        fn.call(this);      };    }  };  function AdGallerySlideshow(nextimage_callback, settings) {    this.init(nextimage_callback, settings);  };  AdGallerySlideshow.prototype = {    start_link: false,    stop_link: false,    countdown: false,    controls: false,    settings: false,    nextimage_callback: false,    enabled: false,    running: false,    countdown_interval: false,    init: function(nextimage_callback, settings) {      var context = this;      this.nextimage_callback = nextimage_callback;      this.settings = settings;    },	create: function() {		/*this.start_link = $('<span class="ad-slideshow-start">'+ this.settings.start_label +'</span>');		this.stop_link = $('<span class="ad-slideshow-stop">'+ this.settings.stop_label +'</span>');*/		//this.countdown = $('<span class="ad-slideshow-countdown"></span>');		this.controls = $('<div class="ad-slideshow-controls"></div>');		//this.controls.append(this.start_link).append(this.stop_link).append(this.countdown);		//this.countdown.hide();		var context = this;	        /*this.start_link.click(        function() {          context.start();        }      );      this.stop_link.click(        function() {          context.stop();        }      );*/      $(document).keydown(        function(e) {          if(e.keyCode == 83) {            // 's'            if(context.running) {              context.stop();            } else {              context.start();            };          };        }      );      return this.controls;    },    disable: function() {      this.enabled = false;      this.stop();      this.controls.hide();    },    enable: function() {      this.enabled = true;      this.controls.show();    },    toggle: function() {      if(this.enabled) {        this.disable();      } else {        this.enable();      };    },    start: function() {      if(this.running || !this.enabled) return false;      var context = this;      this.running = true;      this.controls.addClass('ad-slideshow-running');      this._next();      this.fireCallback(this.settings.onStart);	  alert('after fireCallback');      return true;    },    stop: function() {      if(!this.running) return false;      this.running = false;      //this.countdown.hide();      this.controls.removeClass('ad-slideshow-running');      clearInterval(this.countdown_interval);      this.fireCallback(this.settings.onStop);      return true;    },    _next: function() {      var context = this;      //var pre = this.settings.countdown_prefix;      //var su = this.settings.countdown_sufix;      clearInterval(context.countdown_interval);      //this.countdown.show().html(pre + (this.settings.speed / 1000) + su);      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;          };          var sec = parseInt(context.countdown.text().replace(/[^0-9]/g, ''), 10);          sec--;          if(sec > 0) {            //context.countdown.html(pre + sec + su);          };        },        1000      );    },    fireCallback: function(fn) {      if($.isFunction(fn)) {        fn.call(this);      };    }  };})(jQuery);
