var SLImageChanger = Class.create();
SLImageChanger.prototype = {
	initialize : function(id, images, speed) {
		this.id = id;
		this.images = images;
		this.speed = speed;
		this.pos = 1;

		setTimeout(this.onTimeout.bind(thid), this.speed);
	},

	onTimeout : function() {
		$(this.id).src = this.images[this.pos++];
		if (this.pos == this.images.length) {
			this.pos = 0;
		}

		setTimeout(this.onTimeout.bind(this), this.speed);
	}
}

function slChangeImages(id, images, speed) {
	new SLImageChanger(id, images, speed);
}

var SLImageView = Class.create();
SLImageView.prototype = {
	initialize : function(id) {
		this.id = id;
		this.images = new Array();
	},

	add : function(url) {
		this.images.push(url);
	},

	show : function(index) {
		$(this.id).src = this.images[index];
	}
}

var SLImageFader = Class.create();
SLImageFader.prototype = {
	initialize : function(id, speed) {
		this.id = id;
		this.images = new Array();
		this.texts = new Array();
		this.speed = speed * 1000;

		this.showTexts = $(id + '_t') != null;

		this.pos = 1;

		this.links = new Array();
		this.useLinks = false;
	},

	add : function(url, text, link) {
		this.images.push(url);
		this.texts.push(text);
		this.links.push(link);

		if (link != null) {
			this.useLinks = true;
		}

		if (this.images.length == 1) {
			this.registerTimeout();
		}

	},

	registerTimeout : function() {
		setTimeout(this.onTimeout.bind(this), this.speed);
	},

	onTimeout : function() {
		new Effect.Opacity(this.id + '_v', {
			duration :0.5,
			from :1.0,
			to :0.1,
			afterFinish :this.onFadeOut.bind(this)
		});
	},

	onFadeOut : function() {
		if (this.pos == this.images.length) {
			this.pos = 0;
		}

		var img = $(this.id + '_v');

		img.src = this.images[this.pos];

		if (this.showTexts) {
			var text = this.texts[this.pos];
			if (text != null) {
				Element.update(this.id + '_t', text);
			} else {
				Element.update(this.id + '_t', "");
			}
		}

		if (this.useLinks) {
			var link = this.links[this.pos];
			if (link != null) {
				var a = img.up();
				if (a != null) {
					a.href = link;
				}
			}
		}

		this.pos++;

		new Effect.Opacity(this.id + '_v', {
			duration :0.5,
			from :0.1,
			to :1.0,
			afterFinish :this.onFadeIn.bind(this)
		});
	},

	onFadeIn : function() {
		this.registerTimeout();
	}
}

var SLImageSlider = Class.create();
SLImageSlider.prototype = {

	initialize : function(id, duration, horizontal) {
		this.id = id;
		this.pos = 0;
		this.duration = duration;
		this.active = false;
		this.horizontal = horizontal;
		/*
		 * Event.observe(window, 'load', this.init.bind(this)); },
		 * 
		 * init : function(){
		 */
		this.images = $(this.id + '_s').getElementsByTagName('li');

		var next = $(this.id + '_n');
		next.observe('click', this.onNext.bind(this));

		var prev = $(this.id + '_p');
		prev.observe('click', this.onPrev.bind(this));

		this.nextImg = next.down();
		this.prevImg = prev.down();

		this.nextImgParts = this.nextImg.src.split('.png');
		this.prevImgParts = this.prevImg.src.split('.png');

		this._updateButtons();
	},

	_updateButtons : function() {
		if (this._getNextVisible() >= 0) {
			this.nextImg.src = this.nextImgParts[0] + '.png';
		} else {
			this.nextImg.src = this.nextImgParts[0] + '_d.png';
		}

		var prev = this._getPrevVisible();

		if (prev != 0 || prev != this.pos) {
			this.prevImg.src = this.prevImgParts[0] + '.png';
		} else {
			this.prevImg.src = this.prevImgParts[0] + '_d.png';
		}
	},

	_getSize : function() {
		if (this.horizontal) {
			return $(this.id + '_v').getWidth();
		}

		return $(this.id + '_v').getHeight();
	},

	_getNextVisible : function() {

		var start = 0;
		var size = this._getSize();

		for (i = this.pos; i < this.images.length - 1; i++) {
			var element = this.images[i];
			if (this.horizontal) {
				start += Element.getWidth(element);
			} else {
				start += Element.getHeight(element);
			}
			if (start >= size) {
				return i + 1;
			}
		}

		return -1;
	},

	_getPrevVisible : function() {

		var start = 0;
		var size = this._getSize();

		for (i = this.pos; i > 0; i--) {
			var element = this.images[i];
			if (this.horizontal) {
				start += Element.getWidth(element);
			} else {
				start += Element.getHeight(element);
			}
			if (start >= size) {
				return i - 1;
			}
		}

		return 0;
	},

	_getOffset : function() {

		var offset = 0;
		for (i = 0; i < this.pos; i++) {
			var element = this.images[i];
			if (this.horizontal) {
				offset -= Element.getWidth(element);
			} else {
				offset -= Element.getHeight(element);
			}
		}

		return offset;
	},

	_onFinish : function() {
		this.active = false;
	},

	onNext : function() {
		if (this.active) {
			return;
		}

		var newPos = this._getNextVisible();
		if (newPos == -1) {
			return;
		}

		this.active = true;

		this.pos = newPos;

		if (this.horizontal) {
			new Effect.Move(this.id + '_s', {
				x :this._getOffset(),
				mode :'absolute',
				duration :this.duration,
				afterFinish :this._onFinish.bind(this)
			});
		} else {
			new Effect.Move(this.id + '_s', {
				y :this._getOffset(),
				mode :'absolute',
				duration :this.duration,
				afterFinish :this._onFinish.bind(this)
			});
		}

		this._updateButtons();
	},

	onPrev : function() {
		if (this.active || this.pos == 0) {
			return;
		}

		this.active = true;

		this.pos = this._getPrevVisible();

		if (this.horizontal) {
			new Effect.Move(this.id + '_s', {
				x :this._getOffset(),
				mode :'absolute',
				duration :this.duration,
				afterFinish :this._onFinish.bind(this)
			});
		} else {
			new Effect.Move(this.id + '_s', {
				y :this._getOffset(),
				mode :'absolute',
				duration :this.duration,
				afterFinish :this._onFinish.bind(this)
			});
		}

		this._updateButtons();
	}

}

var SLImageDialog = Class.create( {
	initialize : function(id, images) {
		this.id = id;
		this.images = new Array()
		this.image_ids = new Array();
		this.image_texts = new Array();
		this.hidden = true;
		this.closeOnClick = false;
		Event.observe(window, 'load', this.init.bind(this));
	},

	init : function() {
		this.dialog = $(this.id + '_d');
		this.overlay = $(this.id + '_o');
		this.image = this._getElement('gui_img_dialog_img');
		this.imageLoader = null;
		this.shown = false;
		this.current = -1;
		this.hiddenObjects = null;
		this.currentElement = this._getElement('gui_img_dialog_current');
		this.numImagesElement = this._getElement('gui_img_dialog_num_images');

		this.textElement = this._getElement('gui_img_dialog_text');

		this._reparent(this.overlay);
		this._reparent(this.dialog);

		this.overlay.observe('click', this._hideDialog.bind(this));

		var element = this._getElement('gui_img_dialog_close');
		if (element != null) {
			element.observe('click', this._hideDialog.bind(this));
		}

		element = this._getElement('gui_img_dialog_next');
		if (element != null) {
			element.observe('click', this._onNext.bind(this));
		}

		element = this._getElement('gui_img_dialog_prev');
		if (element != null) {
			element.observe('click', this._onPrev.bind(this));
		}

		this.image.observe('click', this._onImgClick.bind(this));
	},

	setCloseOnClick : function() {
		this.closeOnClick = true;
	},

	_getElement : function(className) {
		var elements = this.dialog.getElementsByClassName(className);
		if (elements == null) {
			return null;
		}

		return elements[0];
	},

	_onImgClick : function() {
		if (this.closeOnClick) {
			this._hideDialog();
			return;
		}

		if (this.current < this.images.length - 1) {
			this.current++;
		} else {
			this.current = 0;
		}
		this._changeImage();
	},

	_onNext : function() {
		if (this.current < this.images.length - 1) {
			this.current++;
			this._changeImage();
		}
	},

	_onPrev : function() {
		if (this.current > 0) {
			this.current--;
			this._changeImage();
		}
	},

	_updateNextPrev : function() {
		element = this._getElement('gui_img_dialog_next');
		if (element != null) {
			if (this.current < this.images.length - 1) {
				element.style.visibility = 'visible';
			} else {
				element.style.visibility = 'hidden';
			}
		}

		element = this._getElement('gui_img_dialog_prev');
		if (element != null) {
			if (this.current > 0) {
				element.style.visibility = 'visible';
			} else {
				element.style.visibility = 'hidden';
			}
		}
	},

	add : function(image, text) {
		this.images.push(image);
		this.image_texts.push(text);
	},

	addWithID : function(image, image_id, text) {
		this.images.push(image);
		this.image_ids.push(image_id);
		this.image_texts.push(text);
	},

	_reparent : function(element) {
		var parent = element.up();

		if (parent != null) {
			element.remove();
		}

		var body = document.getElementsByTagName('body').item(0);

		body.appendChild(element);
	},

	_showDialog : function() {

		if (this.numImagesElement != null) {
			this.numImagesElement.update(this.images.length);
		}

		this.overlay.setStyle( {
			width :document.viewport.getWidth() + "px",
			height :document.viewport.getHeight() + "px"
		});

		var scroll = document.viewport.getScrollOffsets();
		this.overlay.setStyle( {
			left :scroll[0] + "px",
			top :scroll[1] + "px"
		});

		this.hidden = false;

		new Effect.Appear(this.overlay, {
			duration :1.0,
			from :0.0,
			to :0.4,
			afterFinish :this._changeImage.bind(this)
		});
	},

	_hideDialog : function() {
		this.hidden = true;
		this.overlay.style.display = 'none';
		this.dialog.style.display = 'none';
		this._showObjects();
	},

	_onImageLoad : function() {
		this.image.src = this.images[this.current];

		if (this.currentElement != null) {
			this.currentElement.update(this.current + 1);
		}

		if (this.textElement != null) {
			var text = this.image_texts[this.current];
			if (text != null) {
				this.textElement.update(text);
			} else {
				this.textElement.update("");
			}
		}

		this._updateNextPrev();

		var posX = document.viewport.getWidth() / 2;
		var posY = document.viewport.getHeight() / 2;

		// posX -= this.imageLoader.width / 2;
	// posY -= this.imageLoader.height / 2;
	posX -= Element.getWidth(this.dialog) / 2;
	posY -= Element.getHeight(this.dialog) / 2;

	var scroll = document.viewport.getScrollOffsets();
	posX += scroll[0];
	posY += scroll[1];

	if (this.hidden) {
		return;
	}

	new Effect.Parallel( [ new Effect.Move(this.dialog, {
		duration :0.0,
		mode :'absolute',
		x :posX,
		y :posY
	}), new Effect.Appear(this.dialog, {
		duration :0.0
	})
	/*
	 * , new Effect.Morph(this.dialog, { duration : 5.0, width :
	 * this.imageLoader.width, height : this.imageLoader.height })
	 */
	]

	);
},

_changeImage : function() {
	this.imageLoader = new Image();

	this.imageLoader.onload = this._onImageLoad.bind(this);
	this.imageLoader.src = this.images[this.current];
},

show : function(i) {
	if ((!this.hidden && this.current == i) || i >= this.images.length) {
		return;
	}

	this.current = i;

	if (this.hidden) {
		this._hideObjects();
		this._showDialog();
	} else {
		this._changeImage();
	}
},

showById : function(image_id) {
	for (i = 0; i < this.images.length; i++) {
		if (this.image_ids[i] == image_id) {
			this.show(i);
			return;
		}
	}
},

_hideObjects : function() {
	var objects = document.getElementsByTagName('object');

	this.hiddenObjects = new Array();

	for (i = 0; i < objects.length; i++) {
		if (objects[i].style.visibility != 'hidden') {
			this.hiddenObjects.push(objects[i]);
			objects[i].style.visibility = 'hidden';
		}
	}
},

_showObjects : function() {
	if (this.hiddenObjects == null) {
		return;
	}

	for (i = 0; i < this.hiddenObjects.length; i++) {
		this.hiddenObjects[i].style.visibility = 'visible';
	}

	this.hiddenObjects = null;
}
});

var SLSlideShow = Class.create();
SLSlideShow.prototype = {

	initialize : function(id, duration) {
		this.id = id;
		this.pos = 1;
		this.duration = duration * 1000;
		Event.observe(window, 'load', this.init.bind(this));
	},

	init : function() {
		this.registerTimeout();
	},

	registerTimeout : function() {
		setTimeout(this.onTimeout.bind(this), this.duration);
	},

	onTimeout : function() {
		new Effect.Opacity(this.getElementName(), {
			duration :0.5,
			from :1.0,
			to :0.1,
			afterFinish :this.onFadeOut.bind(this)
		});
	},

	getElementName : function() {
		return this.id + "_i" + this.pos;
	},

	onFadeOut : function() {

		var oldElement = $(this.getElementName());

		this.pos++;

		var newElement = $(this.getElementName());

		if (!newElement) {
			this.pos = 1;
			newElement = $(this.getElementName());
		}

		oldElement.style.display = 'none';

		Element.setOpacity(newElement, 0.0);
		newElement.style.display = 'block';

		new Effect.Opacity(newElement, {
			duration :0.5,
			from :0.1,
			to :1.0,
			afterFinish :this.onFadeIn.bind(this)
		});

	},

	onFadeIn : function() {
		this.registerTimeout();
	}
}
