
(function($) {
	var cache = [];
	$.preLoadImages = function() {
		var args_len = arguments.length;
		for (var i = args_len; i--;) {
			var cacheImage = document.createElement('img');
			cacheImage.src = arguments[i];
			cache.push(cacheImage);
		}
	};

	$.fn.cycleImages = function(arg, parameters) {
		var _cycleImageObject = this;
		var _cycleImageObjectContainer = $(this).parent();

		if(typeof(arg)=="object") {
			options = arg;
			var defaultConfig = {
				imageHolder: '#image',
				imageCaption: '#caption',
				fadeOutOpacity: 0.4,
				normalOpacity: 1,
				intervalSeconds: 5,
				maxCount: 3,
				stopObject: false,
				forwardObject: false,
				backObject: false,
				hideNavIfPossible: false,
				animSpeed: 250,
				autoCycle: true,
				useAltAsCaption: false
			}, settings = $.extend(defaultConfig, options), returnVal;
			$(_cycleImageObject).data("_currentIndex", 0);
			$(_cycleImageObject).data("_currentHideGroup", 0);
			$(_cycleImageObject).data("_maxGroupCount", 0);
			$(_cycleImageObject).data("_disable", false);
			$(_cycleImageObject).data("_interval", false);

			if($(settings['imageCaption']).length==0) {
				settings['imageCaption'] = "";
			}
		} else {
			var settings = $(_cycleImageObject).data("settings");
		}

		var _previousHideGroup = 0;

		var _currentClass = "__ciCurrent";
		var _hideGroupClass = "__ciHideGroup_";
		var _firstItem = false;
		var _firstCycle = true;
		var _multiplier = 1000;

		var _index = 0;
		var _hideMode = false;
		var _hideGroup = 0;
		var _forceLoadThisImage = false;

		_cycleImagesFf = function(anchor, useDataAsSource, fn) {
			var href = $(anchor).attr("href");
			var alt = $("img", anchor).attr("alt");
			var sibling = $(anchor).next();
			if(!$(settings['imageHolder']+" img").attr("height"))
				$(settings['imageHolder']+" img").height("auto");

			if(!$(settings['imageHolder']+" img").attr("width"))
				$(settings['imageHolder']+" img").width("auto");

			$(settings['imageCaption']).fadeOut(settings['animSpeed']);
			$(settings['imageHolder']+" img").fadeOut(settings['animSpeed'], function() {

				if(self._forceLoadThisImage) {
					$(settings['imageHolder']+" img").attr("src", self._forceLoadThisImage);
					self._forceLoadThisImage = false;
				} else if(useDataAsSource) {
					$(settings['imageHolder']+" img").attr("src", $("img", anchor).data(useDataAsSource));
				} else {
					$(settings['imageHolder']+" img").attr("src", href);
				}
				if(alt!="" && settings['useAltAsCaption']) {
					$(settings['imageCaption']).text(alt);
					$(settings['imageHolder']+" img").attr("alt",alt);
					$(settings['imageHolder']+" img, "+settings['imageCaption']).fadeIn(settings['animSpeed']);
				} else if(!settings['useAltAsCaption']) {

					$(settings['imageCaption']).html($(sibling).html());
					$(settings['imageHolder']+" img").attr("alt",alt);
					$(settings['imageHolder']+" img, "+settings['imageCaption']).fadeIn(settings['animSpeed']);
				} else {
					$(settings['imageHolder']+" img").fadeIn(settings['animSpeed']);
				}
			});

			$("img."+_currentClass).stop(true, true).animate({ opacity: settings['fadeOutOpacity'] }, settings['animSpeed']);
			$("img", _cycleImageObject).removeClass(_currentClass);
			$("img", anchor).addClass(_currentClass);
			$("img", anchor).stop(true, true).animate({ opacity: settings['normalOpacity'] }, settings['animSpeed'], fn);
		};

		_cycleImageGroup = function(forceDirection, forceCycle) {
			if((($(_cycleImageObject).data("_currentIndex")%settings['maxCount'])==0 && (($(_cycleImageObject).data("_currentIndex")==0 && !_firstCycle) || $(_cycleImageObject).data("_currentIndex")>0)) || forceDirection || forceCycle) {

				_previousHideGroup = $(_cycleImageObject).data("_currentHideGroup");
				if(forceDirection) {
					self._stopCycle();
					if(forceDirection=="forward") {
						if($(_cycleImageObject).data("_currentHideGroup")+1>$(_cycleImageObject).data("_maxGroupCount")) {
							$(_cycleImageObject).data("_currentHideGroup", 0);
						} else {
							$(_cycleImageObject).data("_currentHideGroup", $(_cycleImageObject).data("_currentHideGroup")+1);
						}

					} else if(forceDirection=="back") {
						if($(_cycleImageObject).data("_currentHideGroup")-1<0) {
							$(_cycleImageObject).data("_currentHideGroup", $(_cycleImageObject).data("_maxGroupCount"));
						} else {
							$(_cycleImageObject).data("_currentHideGroup", $(_cycleImageObject).data("_currentHideGroup")-1);
						}
					}
					$(_cycleImageObject).data("_currentIndex", (settings['maxCount']*$(_cycleImageObject).data("_currentHideGroup")));
					self._cycleImagesFf($("a", _cycleImageObject).get($(_cycleImageObject).data("_currentIndex")));
					$(_cycleImageObject).data("_currentIndex", parseInt($($("a", _cycleImageObject).get($(_cycleImageObject).data("_currentIndex"))).data("_index"))+1);
					self._startCycle();

					if($(_cycleImageObject).data("_currentIndex")==$("a", _cycleImageObject).length) {
						$(_cycleImageObject).data("_currentIndex", 0);
						_firstCycle = false;
					}

				} else {
					$(_cycleImageObject).data("_currentHideGroup", Math.floor($(_cycleImageObject).data("_currentIndex")/settings['maxCount']));
				}
				if(_previousHideGroup!=$(_cycleImageObject).data("_currentHideGroup")) {
					$("."+_hideGroupClass+_previousHideGroup, _cycleImageObjectContainer).slideUp(settings['animSpeed']);
					$("."+_hideGroupClass+$(_cycleImageObject).data("_currentHideGroup"), _cycleImageObjectContainer).slideDown(settings['animSpeed']);
				}
			}
		}

		_stopCycle = function() {
			clearInterval($(_cycleImageObject).data("_interval"));
			$(_cycleImageObject).data("_currentIndex", 0);
		};

		_startCycle = function(initialise) {
			if(initialise) {
				self._autoCycle();
				if($(_cycleImageObject).data("_currentIndex")==-1)
					$(_cycleImageObject).data("_currentIndex", 0);
			}

			if(settings['autoCycle']) {
				clearInterval($(_cycleImageObject).data("_interval"));
				$(_cycleImageObject).data("_interval", setInterval(_autoCycle, settings['intervalSeconds']*_multiplier));
			}
		};

		_autoCycle = function() {
			$("a", _cycleImageObject).each(function() {
				if(parseInt($(this).data("_index"))==$(_cycleImageObject).data("_currentIndex")) {
					self._cycleImagesFf(this);
					self._cycleImageGroup();

					$(_cycleImageObject).data("_currentIndex", parseInt($(this).data("_index"))+1);

					if($(_cycleImageObject).data("_currentIndex")==$("a", _cycleImageObject).length) {
						$(_cycleImageObject).data("_currentIndex", 0);
						_firstCycle = false;
					}


					return false;
				}
			});
		};

		_jumpTo = function(jumpIndex, useDataAsSource, fn) {
			if(jumpIndex>$("a", _cycleImageObject).length-1 || jumpIndex==$(_cycleImageObject).data("_currentIndex")) {
				if(fn)
					fn();
				return false;
			} else {
				$(_cycleImageObject).data("_currentIndex", jumpIndex);
				self._cycleImagesFf($("a", _cycleImageObject).get(jumpIndex), useDataAsSource, fn);
				self._cycleImageGroup(false, true);
			}

		}

		_disable = function() {
			$(_cycleImageObject).data("_disable", true);
		}

		_enable = function() {
			$(_cycleImageObject).data("_disable", false);
		}

		_toggleCaption = function(force) {
			if(force==false || ($(settings['imageCaption']).css("opacity")!="0" && force!=true)) {
				$(settings['imageCaption']).stop(true, true).animate({opacity: 0 }, settings['animSpeed']);
			} else {
				$(settings['imageCaption']).stop(true, true).animate({opacity: 1 }, settings['animSpeed']);
			}
		}

		if(typeof(arg)=="object") {
			$(settings['imageCaption']).hide();
			$(_cycleImageObject).data("_currentIndex", -1)
			$(_cycleImageObject).each(function() {
				if(_hideMode) {
					$(this).hide();
				}
				$(this).addClass(_hideGroupClass+_hideGroup);

				if(!settings['useAltAsCaption']) {
					var sibling = $("img", this).parent().next();
					$(sibling).hide();
				}

				$("img", this).mouseover(
					function () {
						if($(_cycleImageObject).data("_disable")==false) {
							if(!$(this).hasClass(_currentClass))
								$(this).stop(true, true).animate({ opacity: settings['normalOpacity'] }, settings['animSpeed'])
						}
					});

				$("img", this).mouseout(function () {
						if($(_cycleImageObject).data("_disable")==false) {
							if(!$(this).hasClass(_currentClass))
								$(this).stop(true, true).animate({ opacity: settings['fadeOutOpacity'] }, settings['animSpeed'])
						}
					}
				)

				$("a", this).each(function(e) {
					var href = $(this).attr("href");
					$.preLoadImages(href);
					if(!_firstItem)
						_firstItem = this;
					$(this).data("_index", _index);
				});

				$("a", this).click(function(e) {
					if($(_cycleImageObject).data("_disable")==false) {
						self._cycleImagesFf(this);
						$(_cycleImageObject).data("_currentIndex", parseInt($(this).data("_index"))+1);
						if($(_cycleImageObject).data("_currentIndex")==$("a", _cycleImageObject).length)
							$(_cycleImageObject).data("_currentIndex", 0);
						self._startCycle();
					}
					e.stopPropagation();
					return false;
				});

				_index++;
				if(_index==settings['maxCount']) {
					_hideMode = true;
				}
				if((_index%settings['maxCount'])==0) {
					_hideGroup++;
				}
				$(_cycleImageObject).data("_maxGroupCount", _hideGroup);

			});

			if(settings['stopObject'])
				$(settings['stopObject']).click(function() { self._stopCycle(); })

			if(settings['forwardObject'])
				$(settings['forwardObject']).click(function() { if($(_cycleImageObject).data("_disable")==false) self._cycleImageGroup('forward'); })

			if(settings['backObject'])
				$(settings['backObject']).click(function() { if($(_cycleImageObject).data("_disable")==false) self._cycleImageGroup('back'); })

			if(settings['autoCycle']==true) {
				$(_cycleImageObject).data("_currentIndex", 0);
				self._startCycle(true);
			}

		} else {
			if(!parameters)
				parameters = new Array();

			if(parameters['forceImage']!="") {
				self._forceLoadThisImage = parameters['forceImage'];
			}

			if(!self._forceLoadThisImage) {
				$.preLoadImages(self._forceLoadThisImage);
			}

			switch(arg) {
				case "stopCycle":
					settings['autoCycle'] = false;
					self._stopCycle();
				break;

				case "startCycle":
					settings['autoCycle'] = true;
					self._startCycle(true);
				break;

				case "jumpTo":
					if(parameters['useDataAsSource']!="") {
						$.preLoadImages($("img", $("a", _cycleImageObject).get(parseInt(parameters['image']))).data(parameters['useDataAsSource']));
					} else {
						parameters['useDataAsSource'] = false;
					}

					if(!parameters['callback'])
						parameters['callback'] = false;

					self._jumpTo(parseInt(parameters['image']), parameters['useDataAsSource'], parameters['callback']);
				break;

				case "toggleCaption":
					if(parameters['visibility']=="show") {
						self._toggleCaption(true);
					} else if(parameters['visibility']=="hide") {
						self._toggleCaption(false);
					} else {
						self._toggleCaption();
					}
				break;

				case "disable":
					self._disable();
					break;

				case "enable":
					self._enable();
					break;

			}
		}

		$(_cycleImageObject).data("settings", settings);
	}
})(jQuery);



