var artGalleries = new Array();

function getArtGallery(name) {
	var ret = null;
	
	artGalleries.each(function(g) {if (g.galleryName==name) ret=g});
	
	return ret;
}

var ArtGallery = Class.create();

ArtGallery.prototype = {

	captions         : null,
	artPath          : '',
	artCount         : 0,
	artComplete      : 0,
	useLightbox      : false,
	galleryWidth     : null,
	galleryLeft      : null,
	galleryRight     : null,
	galleryMid       : null,
	galleryPos       : 1,
	galleryCache     : new Array(),
	galleryName      : null,
	galleryStarted   : false,
	galleryMouseOver : false,
	artSpacing       : null,
	maxWidth         : 0,
	timerId          : 0,
	slideShowSpeed   : null,
	
	cancelQueue      : function (scope) {
		var q = Effect.Queues.get(scope);
		q.each(function(e) { e.cancel() });
	},
	
	play: function() {
		
		var galName = this.galleryName;
		
		// clear any existing callbacks
		if (this.timerId)
			clearInterval( this.timerId );
			
		// set new callback
		this.timerId = setInterval( function() { var g = getArtGallery(galName); g.moveTo( (g.galleryPos) % g.artCount + 1 ); }, this.slideShowSpeed );

		if (this.galleryMouseOver) {
			Appear( galName + '-button-pause', {to:.8} );
			Disappear( galName + '-button-play' );
		}
	},
	
	stop: function() {
		
		clearInterval( this.timerId );
		this.timerId = 0;
		
		if (this.galleryMouseOver) {
			Appear( this.galleryName + '-button-play', {to:.8} );
			Disappear( this.galleryName + '-button-pause' );
		}
	},
	
	computeDims      : function() {
		if (this.maxWidth<480)
			this.maxWidth=480;
		this.artSpacing   = Math.round( this.maxWidth*0.15 );
		
		this.galleryWidth = $(this.galleryName).getWidth();
		
		this.galleryMid   = this.galleryWidth/2 - this.maxWidth/2;
		this.galleryLeft  = this.galleryMid - 0.15*this.maxWidth + this.artSpacing;
		this.galleryRight = this.galleryMid + this.maxWidth - this.artSpacing;
		
		$(this.galleryName+'-caption').setStyle({
			'width' :this.maxWidth+'px',
			'height':this.maxWidth*.3+'px',
			'left'  :this.galleryLeft+'px',
			'bottom':'0px'
		});
	},
	
	resize           : function() {
		this.computeDims();
		this.refresh();
	},
	
	refresh          : function() {
		this.restoreForward();
		var i;
		
		// place buttons
		var button = ['play','pause'];
		for (i=0;i<button.length;++i) {
			var b = $(this.galleryName+'-button-'+button[i]);
			b.setStyle({'left':(this.galleryWidth/2 - b.getWidth()/2)+'px'});
		}
		
		// place art
		for (i=1;i<=this.artCount;++i) {
			$(this.galleryName+'-img-r'+i).setStyle({'left':(this.galleryRight + this.artSpacing*(i-this.galleryPos))+'px'});
			$(this.galleryName+'-img-l'+i).setStyle({'left':(this.galleryLeft  + this.artSpacing*(i-this.galleryPos))+'px'});
		}
		
		// Make everything appear
		if (!this.galleryStarted) {
			var effects = new Array();
			for (i=this.galleryPos+1; i<=this.artCount; ++i) {
				effects.push( new Effect.Appear( this.galleryName+'-img-r'+i, {sync:true} ) );
			}
			
			new Effect.Parallel( effects, {queue:{position:'front',scope:this.galleryName+'-begin'},duration:1} );
			
			this.galleryStarted = true;
		}
	},
	
	checkComplete    : function (objImg) {
		this.artComplete++;

		var w = $(objImg).getWidth();
		this.maxWidth = (w > this.maxWidth) ? w : this.maxWidth;
		
		if (this.artComplete == this.artCount*3) {
			$(this.galleryName+'-busy').hide();
			this.resize();
			this.play();
		}
	},
	
	initialize       : function (galName, imgCount, options) {
		
		options = Object.extend( {slideShowSpeed:4000,useLightbox:false, path:'', captions:new Array()}, options );
		
		// Create image objects
		this.galleryName    = galName;
		this.artPath        = options.path;
		this.artCount       = imgCount;
		this.useLightbox    = options.useLightbox;
		this.captions       = options.captions;
		this.slideShowSpeed = options.slideShowSpeed;
		
		// add self to artGalleries array
		artGalleries.push( this );
		
		var objGallery = $(this.galleryName);
		objGallery.setStyle({'left':'0px','top':'0px','overflow':'hidden','position':'relative'});
		
		var objBusy = $(document.createElement('div'));
		objBusy.setAttribute('id',this.galleryName+'-busy');
		objBusy.setStyle({'position':'absolute'});
		objGallery.appendChild(objBusy);
				
		for (i=1;i<=this.artCount;++i) {
			this.captions[i-1] = i+'/'+this.artCount;
			
			var objImg = $(document.createElement('img'));
			objImg.setAttribute('id',this.galleryName+'-img-l'+i);
			objImg.setStyle({'position':'absolute','bottom':'0px','cursor':'pointer'});
			objGallery.appendChild(objImg);
			
			objImg = $(document.createElement('img'));
			objImg.setAttribute('id',this.galleryName+'-img-r'+(this.artCount-i+1));
			objImg.setStyle({'position':'absolute','bottom':'0px','cursor':'pointer'});
			objGallery.appendChild(objImg);
			
			// gallery cache
			objImg = $(document.createElement('img'));
			objImg.setAttribute('id',this.galleryName+'-img-cache'+i);
			objImg.setStyle({'display':'none'});
			objGallery.appendChild(objImg);
			
			// Lightbox links
			if (this.useLightbox) {
				var objA = $(document.createElement('a'));
				objA.setAttribute('id',this.galleryName+'-link-' + i);
				objA.setAttribute('href',this.artPath+'art'+i+'-big.jpg');
				objA.setAttribute('rel','lightbox['+this.galleryName+']');
				if (this.captions.length>=i)
					objA.setAttribute('title',this.captions[i-1]);
				objA.setStyle({'display':'none'});	// hide from display
				objGallery.appendChild(objA);
			}
		}
		
		var objImg = $(document.createElement('img'));
		objImg.setAttribute('id',this.galleryName+'-img-0');				
		objImg.setStyle({'position':'absolute','bottom':'0px','border':'none'});
		if (this.useLightbox) {
			objImg.setAttribute('title','Click to englarge');
			objImg.setStyle({'cursor':'pointer'});
		}
		
		objGallery.appendChild(objImg);
		/*
		var objButton = $(document.createElement('div'));
		objButton.setAttribute('id',this.galleryName+'-button-left');
		objButton.setStyle({'position':'absolute','opacity':0,'cursor':'pointer'});
		//objButton.onmouseover = function() { Fade(this, {to:.5}) }
		//objButton.onmouseout  = function() { Fade(this, {to:.1}) }
		objButton.onclick     = function() { var g = getArtGallery(galName); g.moveTo( g.galleryPos-1 ) }
		objGallery.appendChild(objButton);
		
		objButton = $(document.createElement('div'));
		objButton.setAttribute('id',this.galleryName+'-button-right');
		objButton.setStyle({'position':'absolute','opacity':0,'cursor':'pointer'});
		//objButton.onmouseover = function() { Fade(this, {to:.5}) }
		//objButton.onmouseout  = function() { Fade(this, {to:.1}) }
		objButton.onclick     = function() { var g = getArtGallery(galName); g.moveTo( g.galleryPos+1 ) }
		objGallery.appendChild(objButton);
		*/
		objButton = $(document.createElement('div'));
		objButton.setAttribute('id',this.galleryName+'-button-play');
		objButton.setStyle({'position':'absolute','opacity':0,'cursor':'pointer','display':'none'});
		objButton.onclick     = function() {
			var g = getArtGallery(galName);
			g.play();
			g.moveTo( g.galleryPos % g.artCount + 1 );
		}
		objGallery.appendChild(objButton);
		
		objButton = $(document.createElement('div'));
		objButton.setAttribute('id',this.galleryName+'-button-pause');
		objButton.setStyle({'position':'absolute','opacity':0,'cursor':'pointer','display':'none'});
		objButton.onclick     = function() { getArtGallery(galName).stop(); }
		objGallery.appendChild(objButton);
		
		objButton = $(document.createElement('div'));
		objButton.setAttribute('id',this.galleryName+'-button-prev');
		objButton.setStyle({'position':'absolute','opacity':0,'cursor':'pointer','display':'none'});
		objButton.onclick     = function() { var g = getArtGallery(galName); g.stop(); g.moveTo( g.galleryPos-1 ) }
		objGallery.appendChild(objButton);
		
		objButton = $(document.createElement('div'));
		objButton.setAttribute('id',this.galleryName+'-button-next');
		objButton.setStyle({'position':'absolute','opacity':0,'cursor':'pointer','display':'none'});
		objButton.onclick     = function() { var g = getArtGallery(galName); g.stop(); g.moveTo( g.galleryPos+1 ) }
		objGallery.appendChild(objButton);
		
		// Caption div
		var objCaption = $(document.createElement('div'));
		objCaption.setAttribute('id',this.galleryName+'-caption');
		objCaption.setStyle({'position':'absolute','opacity':0,'text-align':'center'});
		objGallery.appendChild(objCaption);
		
		$(this.galleryName).onmouseover = function() {
			var g = getArtGallery(galName);
			if (g.timerId)
				Fade( galName+'-button-pause', {to:.8} );
			else
				Fade( galName+'-button-play', {to:.8} );
			if (g.galleryPos>1)
				Fade( galName+'-button-prev',  {to:.8} );
			if (g.galleryPos<g.artCount)
				Fade( galName+'-button-next', {to:.8} );
			Fade( galName+'-caption',      {to:1}  );
			g.galleryMouseOver = true;
		}
		$(this.galleryName).onmouseout = function() {
			var g = getArtGallery(galName);
			if (g.timerId)
				Disappear( galName+'-button-pause' );
			else
				Disappear( galName+'-button-play' );
			
			Disappear( galName+'-button-prev' );
			Disappear( galName+'-button-next' );
			Disappear( galName+'-caption' );
			g.galleryMouseOver = false;
		}
		
		if (this.useLightbox) {
			initLightbox();
			$(this.galleryName+'-img-0').onclick = function() {
				var g=getArtGallery(galName);
				g.stop();	// stop the slideshow, if it is running
				myLightbox.start($(g.galleryName+'-link-'+g.galleryPos))
			}
		}
			
		this.computeDims();
		$(this.galleryName+'-busy').setStyle({'left':this.galleryWidth/2-objBusy.getWidth()/2+'px','top':$(this.galleryName).getHeight()/2-objBusy.getHeight()/2+'px'});
		$(this.galleryName+'-img-0').hide();
								
		for (i=1;i<=this.artCount;++i) {
			// begin preloading forward iamges
			var art = $(this.galleryName+'-img-cache'+i);
			art.onload = function(){ getArtGallery(galName).checkComplete(this) }
			art.src = this.artPath+'art'+i+'-forward.jpg';
			this.galleryCache[i] = art;
			
			// load right-side images
			art = $(this.galleryName+'-img-r'+i);
			art.setStyle({'opacity':'0','display':'none'});
			art.onclick = function() {
				var gal=getArtGallery(galName);
				gal.stop();
				gal.moveTo( this.id.substr(gal.galleryName.length+6) );
			}
			art.onload = function()  { getArtGallery(galName).checkComplete(this) }
			art.src = this.artPath+'art'+i+'-right.jpg';
			
			// load left-side images
			art = $(this.galleryName+'-img-l'+i);
			art.setStyle({'opacity':'0','display':'none'});
			art.onclick = function() {
				var gal=getArtGallery(galName);
				gal.stop();
				gal.moveTo( this.id.substr(gal.galleryName.length+6) );
			}
			art.onload = function()  { getArtGallery(galName).checkComplete(this) }
			art.src = this.artPath+'art'+i+'-left.jpg';
		}
		
	},
	
	moveTo : function (n) {
		if (n>0 && n<=this.artCount)
			this.galleryMove(n-this.galleryPos);
	},
		
	galleryMove : function(delta) {
		this.galleryPos += delta;
		
		var effects = new Array();
		this.cancelQueue(this.galleryName+'-restore');
		var galName = this.galleryName;
		new Effect.Fade( this.galleryName+'-img-0',{queue:{position:'front',scope:this.galleryName+'-restore'},duration:.3, afterFinish: function(){getArtGallery(galName).restoreForward()}, transition: Effect.Transitions.linear } );	
		FadeOut( this.galleryName+'-caption',{duration:.3,transition: Effect.Transitions.linear} );
		
		for (i=1; i<=this.artCount; ++i) {
			if (i>this.galleryPos) {
				effects.push( new Effect.Fade  ( this.galleryName+'-img-l'+i, {sync:true} ) );
				effects.push( new Effect.Appear( this.galleryName+'-img-r'+i, {sync:true} ) );
			}
			else if (i<this.galleryPos) {
				effects.push( new Effect.Fade  ( this.galleryName+'-img-r'+i, {sync:true} ) );
				effects.push( new Effect.Appear( this.galleryName+'-img-l'+i, {sync:true} ) );
			} else {
				effects.push( new Effect.Fade( this.galleryName+'-img-r'+i, {sync:true} ) );
				effects.push( new Effect.Fade( this.galleryName+'-img-l'+i, {sync:true} ) );
			}
		}
			
		// The following loop either
		// 1 - scrolls the art if it is currently or will be visible when done scrolling
		// 2 - instantly moves the art if it is not currently visible or about to be
		// The idea is to avoid unnecessary effects on objects outside the viewing window
		
		var oldPos = this.galleryPos - delta;
		for (i=1;i<=this.artCount;++i) {
			var x    = this.galleryRight + this.artSpacing*(i-this.galleryPos);
			var oldx = this.galleryRight + this.artSpacing*(i-oldPos);
			this.setPosition( this.galleryName+'-img-r'+i,
							  x,
							  (x<this.galleryWidth && i>=this.galleryPos) || (oldx<this.galleryWidth && i>=oldPos),
							  effects );
			
			x    = this.galleryLeft  + this.artSpacing*(i-this.galleryPos);
			oldx = this.galleryLeft  + this.artSpacing*(i-oldPos);
			this.setPosition( this.galleryName+'-img-l'+i,
							  x,
							  (x>-this.artSpacing && i<=this.galleryPos) || (oldx>-this.artSpacing && i<=oldPos),
							  effects );
		}
		
		this.cancelQueue(this.galleryName+'-move');
		new Effect.Parallel( effects, {queue:{position:'front',scope:this.galleryName+'-move'},duration: 1} );
	},
	
	setPosition: function( name, left, condition, effects ) {
		if (condition)
			effects.push( new Effect.Morph( name, {style:'left:'+left+'px',sync:true} ) );
		else
			$(name).setStyle({'left':left+'px'});
	},

	restoreForward : function() {
		$(this.galleryName+'-img-0').src = this.galleryCache[this.galleryPos].src;
		$(this.galleryName+'-img-0').setStyle({'left':(this.galleryWidth/2-this.galleryCache[this.galleryPos].getWidth()/2)+'px'});
		
		var caption = '';
		if (this.captions.length>=this.galleryPos)
			caption = this.captions[this.galleryPos-1];
					
		$(this.galleryName+'-caption').innerHTML = caption;
			
			
		this.cancelQueue(this.galleryName+'-restore');
		new Effect.Appear(this.galleryName+'-img-0', {queue:{position:'front',scope:this.galleryName+'-restore'},duration:.7} );
		
		if (this.galleryMouseOver) {
			Appear( this.galleryName+'-caption', {to:1,duration:.7}  );
			if (this.galleryPos>1)
				Fade( this.galleryName+'-button-prev',  {to:.8} );
			else
				Disappear( this.galleryName+'-button-prev' );
				
			if (this.galleryPos<this.artCount)
				Fade( this.galleryName+'-button-next', {to:.8} );
			else
				Disappear( this.galleryName+'-button-next' );
		}
	}
}