// Check requirements
if ("undefined" == typeof(Prototype)) {
	throw "JK.Slideshow requires Prototype to be loaded.";
}

// Check namespace
if ("undefined" == typeof(JK)) {
	JK = {};
}
if ("undefined" == typeof(JK.Url)) {
	JK.Url = {};
}
// Link element, used to find the absolute url.
JK.Url._e = null;
JK.Url.absolute = function(url) {
	if (Object.isString(url)) {
		if (null == JK.Url._e) {
			JK.Url._e = new Element("a", {"style": "display:none;"});
		}
		JK.Url._e.setAttribute("href", url);
		url = JK.Url._e.href;
	} else {
		url = null;
	}
	return url;
}

JK.Slideshow = Class.create({
	initialize: function(params) {
		this._imgUrls = $A();
		this._idxCurr = -1;
		this._e1 = null;
		this._e2 = null;
		this._interval = 5;
		this._nextInterval = 5;
		this._duration = 1;
		this._nextEarliestStartTS = null;
	
		params = $H(params);
		if (Object.isArray(params.get("imgUrls"))) {
			$A(params.get("imgUrls")).each(function(url) {
				if (Object.isString(url)) {
					this._imgUrls.push(JK.Url.absolute(url));
				}
			}.bind(this));
		}
		// Other parameters must only be inspected if the slide show contains
		// at least one image.
		if (0 != this._imgUrls.length) {
			if (!Object.isUndefined(params.get("element"))) {
				var e = $(params.get("element"));
				if (Object.isElement(e)) {
					if("IMG" == e.nodeName) {
						this._e1 = e;
						var url = JK.Url.absolute(this._e1.getAttribute("src"));
						this._idxCurr = this._imgUrls.indexOf(url);
						if (-1 == this._idxCurr) {
							// Current visible image is not set in the slideshow array.
							// Add it if this is not denied by parameter.
							if (Object.isUndefined(params.get("includeCurrentInSlideshow"))
									|| new Boolean(params.get("includeCurrentInSlideshow"))) {
								this._imgUrls.push(url);
								this._idxCurr = this._imgUrls.length - 1;
							}
						}
					} else {
						this._e1 = e.insert(new Element("img"));
					}
				}
			}
			
			// Continue only if the image-element exists.
			if (null != this._e1) {
				// Create the second image tag to fade between the images.
				this._e2 = new Element("img");
				this._e1.insert({"before": this._e2});
				$w(this._e1.className).each(this._e2.addClassName);
				this._e2.clonePosition(this._e1);
				
				this._e2.observe("load", function(evt) {
					var delay = (this.nextEarliestStartTS - new Date().getTime()) / 1000;
					if (0 < delay) {
						this._fade.bind(this).delay(delay);
					} else {
						this._fade();
					}
				}.bindAsEventListener(this));
				
				if (Object.isNumber(params.get("interval"))) {
					if (0 < params.get("interval")) {
						this._interval = params.get("interval");
					}
				}
				this._nextInterval = this._interval;
				if (Object.isNumber(params.get("initialDelay"))) {
					if (0 <= params.get("initialDelay")) {
						this._nextInterval = params.get("initialDelay");
					}
				}
				
				if (Object.isNumber(params.get("duration"))) {
					if (0 < params.get("duration")) {
						this._duration = params.get("duration");
					}
				}
				
				this._next();
			}
		}
	},
	
	_next: function() {
		this._idxCurr++;
		if (this._imgUrls.length == this._idxCurr) {
			this._idxCurr = 0;
		}
		this.nextEarliestStartTS = new Date().getTime() + this._nextInterval * 1000;
		this._nextInterval = this._interval;
		this._e2.setAttribute("src", this._imgUrls[this._idxCurr]);
	},
	
	_fade: function() {
		new Effect.Opacity(this._e1, {"duration": this._duration, "to": 0, "afterFinish": this._afterFade.bindAsEventListener(this)});
	},
	
	_afterFade: function() {
		this._e1.setAttribute("src", this._imgUrls[this._idxCurr]);
		this._e1.setOpacity(1);
		this._next();
	}
});
