(function($) {
  $.fn.fsslideshow = function(action, options) {
    if (typeof(action) == 'object' || action == undefined) {
      options = action;
      action = 'initialize';
    }
    args = Array.prototype.slice.call(arguments, 1);
    var options =  $.extend($.fn.fsslideshow.defaults, options);  
    
    return this.each(function () {
      var instance = $.data(this, "slideshow");
      (!instance && action == 'initialize' &&
        $.data(this, "slideshow", new $.fsslideshowWidget(this, options)));
      (instance && action != 'initialize' && $.isFunction(instance[action]) &&
        instance[action].apply(instance, args));
    });
  };
  $.fn.fsslideshow.defaults = {
    previousButton: '.previous_button',
    nextButton: '.next_button',
    closeButton: '.close_button',
    transitionDuration: 'slow',
    loadingMessage: 'loading...',
		animateZoom: true
  };
  $.fsslideshowWidget = function(container, options) {
    var obj = this;
    var pictures = new Array();
    var legends = new Array();
    this.options = $.extend({}, options);
		if ($('#fsslideshow').length == 0) {
			$('body').append('<div id="fsslideshow" class="slideshow"></div>');
	    this.element = $('#fsslideshow');
	    this.element.append('<img id="pic1" />')
			.append('<img id="pic2" />')
	    .append('<div class="legend"></div>')
	    .append('<div class="loading">'+ this.options.loadingMessage +'</div>');
		} else {
	    this.element = $('#fsslideshow').hide();			
		}
		this.container = $(container);
    this.container.find('a[rel=slideshow]')
    .each(function(i, e) {
      pictures.push($(this).attr('href'));
      legends.push($('.legend', this).html());
			$(e).click(function (ev) {
				obj.start(i);
				return false;
			});
    });
		this.nav = this.element.find('.nav');
		this.element.hide()
		.find('img').hide();
    this.element.find('.loading').hide();
    this.pictureIndex = -1;
    this.pictures = pictures;
    this.legends = legends;
    this.running = false;
  };
  $.fsslideshowWidget.prototype = {
    start: function(i) {
      if (!this.running) {
        this.element.find('.nav').show();
				this.setupZoom();
        this.showPicture(i);
        this.element.trigger({
          type: 'start'
        });
        this.running = true;
      }
    },
    showPicture: function(i) {
      var obj = this;      
      if (i >= 0 && i < this.pictures.length) {
        this._disableButtons();
        this.pictureIndex = i;
        this.imagePreloader = new Image();
        this._showLoading();
        $(this.imagePreloader).unbind().load(function() {
          obj._hideLoading();
          obj._pictureLoaded();
        }).attr('src', this.pictures[i]);
      }
    },
    _pictureLoaded: function() {
      var obj = this;      
      var images = this.element.find('img');
      var src = this.pictures[this.pictureIndex];
      $(images[0]).insertAfter(images[1]).hide();
      $(images[1]).attr('src', src).show();
      var legend = this.element.find('.legend').html(this.legends[this.pictureIndex]);
      $(images[1]).css({
        'left': 0,
        'width': 'auto',
        'height': "100%"
      });
      //legend.css({ 'left': (this.imagePreloader.width * $(window).height() / this.imagePreloader.height + 10) +"px" })
      this._enableButtons();
      this._preloadNeighbors();
    },
    _preloadNeighbors: function() {
      if (this.pictureIndex < this.pictures.length - 1) {
        nextPict = new Image();
        nextPict.src = this.pictures[this.pictureIndex + 1];
      }
      if (this.pictureIndex > 0) {
        prevPict = new Image();
        prevPict = this.pictures[this.pictureIndex - 1];
      }
    },
    nextPicture: function() {
      if (this.pictureIndex == this.pictures.length - 1) {
        this.showPicture(0);
      } else {
        this.showPicture(this.pictureIndex + 1);
      }
    },
    previousPicture: function() {
      if (this.pictureIndex == 0) {
        this.showPicture(this.pictures.length - 1);
      } else {
        this.showPicture(this.pictureIndex - 1);
      }      
    },
    _disableButtons: function() {
      this.element.find('img').unbind('click');
      this.element.find(this.options.nextButton).unbind('click').css({ opacity: 0.4 });
      this.element.find(this.options.previousButton).unbind('click').css({ opacity: 0.4 });
      this.element.find(this.options.closeButton).unbind('click').css({ opacity: 0.4 });
    },
    _enableButtons: function() {
      var obj = this;
      if (this.pictures.length > 1) {
      	this.element.find(this.options.nextButton).click(function() {
        	obj.nextPicture();
      	})
      	.css({ opacity: 1 });
      	this.element.find(this.options.previousButton).click(function() {
        	obj.previousPicture();
      	})
      	.css({ opacity: 1 });
      	this.element.find('img').click(function() {
        	obj.nextPicture();
      	});
			} else {
				this.element.find(this.options.nextButton).css({ 'visibility' : 'hidden'});
				this.element.find(this.options.previousButton).css({ 'visibility' : 'hidden'});
			}
      this.element.find(this.options.closeButton).click(function() {
        obj.stop();
      })
      .css({ opacity: 1 });
    },
    _showLoading: function() {
      this.element.find('.loading').show();
    },
    _hideLoading: function() {
      this.element.find('.loading').hide();
    },
    _resizeScroll: function() {
      this.element.css({
        'left': ($(document).scrollLeft()) + 'px',
        'top': ($(document).scrollTop()) + 'px',
        'width': $(window).width() + 'px',
        'height': $(window).height() + 'px'
      })
    },
    setupZoom: function() {
      var obj = this;
      if (this.zoomEnabled) {
        return;
      }
      $('#header').css({'z-index': 50});

			if (this.options.backgroundColor != undefined) {
				this.element.css({ 'background-color': this.options.backgroundColor });
				$('.legend', this.element).css({ 'background-color': this.options.backgroundColor });
			}
      var img = this.element.css({
        'z-index': 100,
        'top': ($(document).scrollTop()) + 'px',
        'left': ($(document).scrollLeft()) + 'px',
        'width': $(window).width() + 'px',
        'height': $(window).height() + 'px'
      })
			.show()
      .find('img:first').css({
        'top': 0,
        'width': 'auto',
        'height': '100%',
				'left': 0,
				'display': 'none'
      });				

      $(window).bind("resize scroll", function() { obj._resizeScroll(); });
      this.zoomEnabled = true;
      this.element.find('.nav').css({ 'opacity': 0.5 }).hover(
        function() { 
          $(this).css({ 'opacity': 1});
        },
        function() {
          $(this).css({ 'opacity': 0.3});
      });
    },
    unzoom: function(callback) {
      if (!this.zoomEnabled) {
        if (callback != null) {
          callback();
        }
        return;
      }
      $(window).unbind("resize scroll");
			this.element.hide();
      $('#header').css({'z-index': 500});
      this.element.find('.nav').unbind("mouseenter mouseleave");
      this.zoomEnabled = false;
      if ($.isFunction(callback)) {
        callback();
      }			
    },
    stop: function() {
      var obj = this;
      if (this.running) {
        this._disableButtons();
        if (this.zoomEnabled) {
          this.unzoom(function() { obj.stop() });
        } else {
          this.element.trigger({
            type: 'stop'
          });
          this._hideLoading();
        }
				this.running = false;
      }
    }
  };
})(jQuery);

