/*
 * mini_gallery.js (V.1.0)
 * Iterates between a set of fixed size images, with a fade in effect.
 * @author : Jean Semere (Baggage Claim)
 *
 * You have no right to use or redistribute this code unless Baggage Claim SARL
 * authorizes you to do so.
 *
 * Needs Prototype 1.6+ and Scriptaculous 1.5+
 *
 */

MiniGallery = Class.create();
MiniGallery.prototype =
{
	initialize: function(name, pictures, captions, options)
	{
		this.element = $(name);
		this.height = this.element.getHeight();
		this.width = this.element.getWidth();
		this.imgh = 0;
		this.imgw = 0;
		this.pictures = pictures;
		this.captions = captions;
		this.visible = true;
		options = options || {};
		this.nextButton = $(options.nextButton) || false;
		this.prevButton = $(options.prevButton) || false;
		this.random = $(options.random) || false;
		this.style = options.style || "border: 3px solid white";
		this.caption = options.caption || true;
		this.duration = options.duration || 3;
		this.popup = options.popup || false;
		this.loop = options.loop || true;
		this.size = pictures.length;
		this.current = -1;
		if (this.random)
			this.current = Math.floor(Math.random()*(this.size-1));
		this.cumulative = 0;
		this.loadIndex = 0;
		this.loading = false;
		this.loadCurrent = null;
		if (this.caption)
		{
			if ($("exhibitionTotal"))
				$("exhibitionTotal").innerHTML = this.size.toString();
		}
		this.img = (this.size - 1) % this.size;
		if (this.nextButton)
			Event.observe(this.nextButton, 'click', this.drawNext.bindAsEventListener(this), false);
		if (this.prevButton)
			Event.observe(this.prevButton, 'click', this.drawPrev.bindAsEventListener(this), false);
		Event.observe(window, 'resize', this.refresh.bindAsEventListener(this), false);
		this.loadImages();
		this.init();
	},
	
	init: function()
	{
		this.drawNext();
	},
	
	loadImages: function()
	{
		if (this.loadIndex >= this.size)
			return;
		if (this.loading)
		{
			if (this.loadCurrent.complete)
			{
				this.loadIndex++;
				this.loading = false;
			}
			this.loadImages.bind(this).delay(0.1);
		}
		else
		{
			this.loading = true;
			this.loadCurrent = new Image();
			this.loadCurrent.src = this.pictures[this.loadIndex];
		}
	},
	
	removeDeprecatedChild: function()
	{
		n = this.cumulative - 1;
		deprecatedChild = $("slideshow_"+n);
		if (deprecatedChild != null)
			this.element.removeChild(deprecatedChild);
	},
	
	drawPrev: function()
	{
		this.img = new Image();
		this.img.src = this.pictures[(this.size+this.current-1)%this.size];
		this.current--;
		this.current = (this.size + this.current) % this.size;
		this.draw();
	},
	
	drawNext: function()
	{
		this.img = new Image();
		this.img.src = this.pictures[(this.current+1)%this.size];
		this.current++;
		this.current = this.current % this.size;
		this.draw();
	},
	
	refresh: function()
	{
		this.height = this.element.getHeight();
		this.width = this.element.getWidth();
		if (this.effect)
			this.effect.cancel();
		this.draw();
	},
	
	draw: function()
	{
		if (this.img.complete)
		{
			if ($("slideshow_"+this.cumulative))
				new Effect.Fade("slideshow_"+this.cumulative);
			this.cumulative++;
			zindex = 20 + this.cumulative;
			this.imgh = parseInt(this.img.height);
			this.imgw = parseInt(this.img.width);
			imgratio = this.imgh / this.imgw;
			divratio = this.height / this.width;
			if (imgratio > 1)
			{
				if (this.height / imgratio < this.width)
					aspect = "height: " + this.height + "px; width: " + this.height / imgratio + "px; top: 0px; left: " + ((this.width - this.height/imgratio) / 2) + "px;";
				else
					aspect = "width: " + this.width + "px; height: " + this.width * imgratio + "px; left: 0px; top: " + ((this.height - this.width*imgratio) / 2) + "px;";
			}
			else
			{
				if (this.width * imgratio < this.height)
					aspect = "width: " + this.width + "px; height: " + this.width * imgratio + "px; left: 0px; top: " + ((this.height - this.width*imgratio) / 2) + "px;";
				else
					aspect = "height: " + this.height + "px; width: " + this.height / imgratio + "px; top: 0px; left: " + ((this.width - this.height/imgratio) / 2) + "px;";
			}
			if (this.popup)
			{
				node = Builder.node('img', {
					id: "slideshow_"+this.cumulative,
					style: "cursor: pointer; position: absolute; display: none; " + aspect + this.style,
					src: this.img.src,
					onclick: "window.open('"+this.img.src+"','Image','height="+this.imgh+",width="+this.imgw+",scrollbars,resizable')"
				});
			}
			else
			{
				node = Builder.node('img', {
					id: "slideshow_"+this.cumulative,
					style: "position: absolute; display: none; " + aspect + this.style,
					src: this.img.src
				});
			}
			this.element.appendChild(node);
			this.effect = new Effect.Appear("slideshow_"+this.cumulative, { afterFinish: this.removeDeprecatedChild.bind(this) });
			if (this.caption)
			{
				$("exhibitionCounter").innerHTML = (this.current + 1).toString();
				alt = this.captions[this.current].split(" :: ");
				$("galleryCaption").hide();
				$("galleryTitle").innerHTML = alt.first().toUpperCase();
				$("galleryOtherCaption").innerHTML = alt.last();
				this.captionAppear.bind(this).delay(0.1);
			}
		}
		else
		{
			this.draw.bind(this).delay(0.1);
		}
	},
	
	captionAppear: function()
	{
		$("galleryCaption").setStyle({
			left: $("slideshow_"+this.cumulative).cumulativeOffset().left + "px",
			top: $("slideshow_"+this.cumulative).cumulativeOffset().top - 18 + "px"
		});
		new Effect.Appear("galleryCaption");
		xOffset = $("slideshow_"+this.cumulative).cumulativeOffset().left + $("slideshow_"+this.cumulative).getWidth() - $("exhibitionCaption").getWidth();
		yOffset = $("slideshow_"+this.cumulative).cumulativeOffset().top + $("slideshow_"+this.cumulative).getHeight() + 10;
		new Effect.Move("exhibitionCaption", { x: xOffset, y: yOffset, mode: "absolute", afterFinish: function() { $("exhibitionCaption").setStyle({visibility: "visible"}); } });
	},
	
	toggleVisibility: function()
	{
		if (this.visible)
		{
			this.nextButton.setStyle({visibility: "hidden"});
			this.prevButton.setStyle({visibility: "hidden"});
			this.visible = false;
		}
		else
		{
			this.hideButtons();//.bind(this).delay(1);
			this.visible = true;
		}
	},
	
	hideButtons: function()
	{
		this.nextButton.setStyle({visibility: "visible"});
		this.prevButton.setStyle({visibility: "visible"});
	}
};
