﻿/**
 * jQuery.slideshow - A simple slideshow
 * Written by Michael Kerr (mike AT onlysport DOT co DOT nz)
 * Licensed under the WTFPL (http://sam.zoy.org/wtfpl/).
 * Date: 2009/10/26
 *
 * @author Michael Kerr
 * @version 0.1.3
 *
 **/
 
jQuery.fn.extend({
	slideshow: function()
	{
		_args = arguments;

		return this.each(function() {
			var _continue = jQuery._slideshow.init(this, _args);
			if (_continue !== false && typeof _args[0].autoStart != 'undefined' && _args[0].autoStart == true) jQuery._slideshow.start();
		});
	},

	slideshow_pause: function() { return this.each(function() { jQuery._slideshow.pause(); }); },
	slideshow_play: function() { return this.each(function() { jQuery._slideshow.start(); }); },
	slideshow_toggle_play: function(_this) { return this.each(function() { jQuery._slideshow.toggle_play(_this); }); },

	slideshow_next: function() { return this.each(function() { jQuery._slideshow.next(); }); },
	slideshow_prev: function() { return this.each(function() { jQuery._slideshow.prev(); }); },

	slideshow_set_time: function(mod) { return this.each(function() { jQuery._slideshow._set_time(mod); }); },
	slideshow_set_transition: function(trans) { return this.each(function() { jQuery._slideshow._set_transition(trans); }); }
});

jQuery.extend({
	_slideshow: {
		slideshow: '0.1.3',

		_max_time: 10000,
		_min_time: 3000,
		_time_mod: 0.05,

		_transition_time: 4000,

		_available_methods: ['fade', 'slide', 'slide_up', 'fade_slide'],
		_method: 'fade',

		_lmnt: null,
		_slide_timer: null,

		_tick_count: 0,

		_paused: false,
		_in_transition: false,

		init: function(_this, _o)
		{
			var self = this;
			self._lmnt = $(_this);
			_o = _o[0];

			if (typeof _o.slideClass != 'undefined') self._slide_class = _o.slideClass;
			if (typeof _o.maxTime != 'undefined') self._max_time = _o.maxTime;
			if (typeof _o.minTime != 'undefined') self._min_time = _o.minTime;
			if (typeof _o.transitionTime != 'undefined') self._transition_time = _o.transitionTime;
			if (typeof _o.transition != 'undefined') self._set_transition(_o.transition);

			if (typeof _o.toolbar != 'undefined')
			{
				self._toolbar = $(_o.toolbar);

				self._toolbar_showing = false;
				self._toolbar.css({ 'display': 'block'});
				self._toolbar.attr('state', 'closed').css({ opacity: 0.25 });
			}
			else
				self._toolbar = null;

			if (self._lmnt.children('.' + self._slide_class).length <= 1 && self._toolbar) { self._toolbar.css({ 'display': 'none' }); return false; }

			if (typeof _o.tick == 'function') self._tickFunction = _o.tick;

			if (typeof _o.newSlide == 'function') self._transitionCompleteFunction = _o.newSlide;

			self._lmnt.mouseenter(function () { self._show_toolbar(); });
			self._lmnt.mouseleave(function () { self._hide_toolbar(); });
		},

		start: function()
		{
			var self = this;

			if (self._lmnt.children('.' + self._slide_class).length <= 1) { self._paused = true; return false; }

			if (self._paused)
			{
				self.toggle_play($('#slidetoggleplay'));
				return;
			}

			self._paused = false;

			self._set_time(self._time_mod);

			self._slide_timer = setTimeout(function() { self._tick(); }, self._time / 10);

			if (typeof self._transitionCompleteFunction == 'function')
				self['_transitionCompleteFunction'].call(self, (self._lmnt.children('.' + self._slide_class).index(self._lmnt.find('.active')) + 1), self._lmnt.children('.' + self._slide_class).length);
		},

		pause: function()
		{
			var self = this;
			self._paused = true;
		},

		toggle_play: function(_this)
		{
			var self = this;

			$(_this).html(self._paused == false ? 'RESUME SLIDESHOW' : 'PAUSE SLIDESHOW');

			if (self._paused == true)
			{
				self._paused = false;
				self._slide_timer = setTimeout(function() { self._tick(); }, self._time / 10);
			}
			else
			{
				clearTimeout(self._slide_timer);
				self._paused = true;
			}
		},

		_set_time: function(mod)
		{
			var self = this;

			if (mod < 0 || mod > 1) return;

			// reverse the modifier so 0.25 becomes 0.75, this is required as the max is slower then the min.
			mod = 1 - mod;

			self._time_mod = mod;

			if (mod == 0) 
				self._time = self._min_time;
			else
				self._time = ((self._max_time - self._min_time) * mod) + self._min_time;
		},

		_set_transition: function(trans) { var self = this; if (jQuery.inArray(trans, self._available_methods) == -1) return; self._method = trans; },

		_tick: function()
		{
			var self = this;

			if (typeof self._tickFunction == 'function')
				self['_tickFunction'].call(self, (self._tick_count / 10));
			
			if (self._tick_count < 10)
			{
				if (self._paused == true) return;

				self._tick_count++;
				self._slide_timer = setTimeout(function() { self._tick(); }, self._time / 10);
				return
			}

			self.next();
		},

		next: function()
		{
			var self = this;

			clearTimeout(self._slide_timer);
			self._slide_timer = false;

			if (self._in_transition == true) return;

			self._tick_count = 0;

			var $active = self._lmnt.find('.active');

			if ( $active.length == 0 ) $active = self._lmnt.find('.' + self._slide_class + ':last');

			var $next = $active.next('.' + self._slide_class).length > 0 ? $active.next('.' + self._slide_class) : self._lmnt.find('.' + self._slide_class + ':first');

			$active.addClass('last-active');

			if ($.browser.msie && $.browser.version == "6.0")
			{
				$next.addClass('active');
				self._transition_complete($active, $next, 1);
			}
			else
				self[self._method].call(self, $active, $next, 1);
		},

		prev: function()
		{
			var self = this;

			clearTimeout(self._slide_timer);
			self._slide_timer = false;

			if (self._in_transition == true) return;

			self._tick_count = 0;

			var $active = self._lmnt.find('.active');

			if ( $active.length == 0 ) $active = self._lmnt.find('.' + self._slide_class + ':last');

			var $prev = $active.prev('.' + self._slide_class).length > 0 ? $active.prev('.' + self._slide_class) : self._lmnt.find('.' + self._slide_class + ':last');

			$active.addClass('last-active');

			if ($.browser.msie && $.browser.version == "6.0")
			{
				$next.addClass('active');
				self._transition_complete($active, $prev, -1);
			}
			else
				self[self._method].call(self, $active, $prev, -1);
		},

		fade: function(_active, _next, _direction)
		{
			var self = this;
			var _fade_mod = 0.8;

			self._in_transition = true;

			_active.css({ left: 0, top: 0, opacity: 1 }).animate({ opacity: 0 }, parseInt((self._transition_time * _fade_mod) * 0.9));

			_next.css({ left: 0, top: 0, opacity: 0 }).addClass('active').animate({ opacity: 1 }, parseInt(self._transition_time * _fade_mod), function() 
			{
				self._transition_complete(_active, _next, _direction);
			});
		},

		slide: function(_active, _next, _direction)
		{
			var self = this;

			self._in_transition = true;

			if (_direction == 1)
			{
				_active_target = 0 - _active.width();
				_next_from = _active.width();
			}
			else
			{
				_active_target = _active.width();
				_next_from = 0 - _active.width();
			}

			_active.animate({ left: _active_target }, self._transition_time);

			_next.css({ left: _next_from, top: 0, opacity: 1.0 }).addClass('active').animate({ left: 0 }, self._transition_time, function(){
				self._transition_complete(_active, _next, _direction);
			});
		},

		slide_up: function(_active, _next, _direction)
		{
			var self = this;

			self._in_transition = true;

			if (_direction == 1)
			{
				_active_target = 0 - _active.height();
				_next_from = _active.height();
			}
			else
			{
				_active_target = _active.height();
				_next_from = 0 - _active.height();
			}
			
			_active.animate({ top: _active_target }, self._transition_time);

			_next.css({ top: _next_from, left: 0, opacity: 1.0 }).addClass('active').animate({ top: 0 }, self._transition_time, function(){
				self._transition_complete(_active, _next, _direction);
			});
		},

		fade_slide: function(_active, _next, _direction)
		{
			var self = this;

			self._in_transition = true;

			if (_direction == 1)
			{
				_active_target = 0 - _active.width();
				_next_from = _active.width();
			}
			else
			{
				_active_target = _active.width();
				_next_from = 0 - _active.width();
			}

			_active.css({ top: 0, opacity: 1 }).animate({ left: _active_target, opacity: 0 }, self._transition_time);

			_next.css({ left: _next_from, top: 0, opacity: 0 }).addClass('active').animate({ left: 0, opacity: 1 }, self._transition_time, function(){
				self._transition_complete(_active, _next, _direction);
			});
		},

		_transition_complete: function(_active, _next, _direction)
		{
			var self = this;

			_active.removeClass('active last-active').css({ opacity: 1.0 });

			self._in_transition = false;

			if (typeof self._transitionCompleteFunction == 'function')
				self['_transitionCompleteFunction'].call(self, (self._lmnt.children('.' + self._slide_class).index(self._lmnt.find('.active')) + 1), self._lmnt.children('.' + self._slide_class).length);

			if (typeof self._tickFunction == 'function')
				self['_tickFunction'].call(self, (self._tick_count / 10));

			if (self._paused == true) return;

			self._slide_timer = setTimeout(function() { self._tick(); }, self._time / 10);
		},

		_show_toolbar: function()
		{
			if ($.browser.msie && $.browser.version == "6.0") return this;

			//if (this._toolbar.attr('state') == 'open') return;
			$(this._toolbar).stop().animate({ 'opacity': 1.0 }, 500, function() { $(this).attr('state', 'open'); }); //css({ 'bottom': 0, 'left': 0, 'opacity': 0.25, 'display': 'block' }).
		},

		_hide_toolbar: function()
		{
			if ($.browser.msie && $.browser.version == "6.0") return this;

			//if (this._toolbar.attr('state') == 'closed') return;
			$(this._toolbar).stop().animate({ 'opacity': 0.25 }, 500, function() { $(this).attr('state', 'closed'); }); //css({ 'bottom': 0, 'left': 0, 'opacity': 1.0, 'display': 'block' }).
		}
	}
});
