var LiveGallery = Class.create({
	
	// Adjustable vars
	scriptDir: '/modules/gettysgallery/lib',
	fadeTime: .65,
	slideShowFadeTime: 1,
	slideShowDuration: 5,

	swapHook: function(){},
	postEffectSwapHook: function(){},
	prevNextHook: function(){},
	enableSlideshow: false,
	
	// other vars
	swapWait: false,
	isIE: false,
	fullWidth: 0,
	fullHeight: 0,	
	stageWidth: 0,
	stageHeight: 0,
	slideshowActive: false,	
	
	captionContainerWidth: 0,
	captionContainerTop: 0,
	detailBoxTop: 120,
	detailBoxWidth: 196,

	initialize: function(galleryName, scriptDir, initialImgNum, mode){
		
		this.isIE = navigator.userAgent.indexOf('MSIE') != -1;
		
		this.galleryName = galleryName;
		this.scriptDir = scriptDir;
		this.mode = mode;
		this.enableSlideshow = (this.mode=='home');

		this.inactiveThumbImgs = $$('.'+galleryName+' .thumbImg');
		
		if(this.inactiveThumbImgs.length == 0){ return; }

		initialImgNum = (initialImgNum == null)? 0 : initialImgNum;
		initialImgNum = (initialImgNum == 'random')? Math.floor(Math.random()*this.inactiveThumbImgs.length+1)-1 : initialImgNum;
		initialImgNum = (initialImgNum >= this.inactiveThumbImgs.length)? 0 : initialImgNum;
				
		this.ssCounter = initialImgNum;
		this.activeThumb = this.inactiveThumbImgs[initialImgNum];

		this.inactiveThumbImgs.each(function(e,i){

			e.isActive = false;
			e.fullSrc = e.href;
			
			var thisLink = e.up('div');
			e.place = thisLink.down('h2').innerHTML;
			e.location = thisLink.down('h3').innerHTML;			
			e.specs = thisLink.down('div.specs').innerHTML;	
			e.caption = thisLink.down('div.caption').innerHTML;	
			e.thumbImg = e.down('img');

		}.bind(this));
		

		this.stage = $$('.'+galleryName+' .stage')[0];
	
		this.stageWidth = this.stage.getWidth();
		this.stageHeight = this.stage.getHeight();
									
		this.thumbsContainer = $$('.'+galleryName+' .thumbs')[0];

		this.slide1 = new Element('div', { 'class': 'slide slide1' }).setStyle({'width':this.stageWidth+'px', 'height':this.stageHeight+'px'}).hide();
		this.slide2 = new Element('div', { 'class': 'slide slide2' }).setStyle({'width':this.stageWidth+'px', 'height':this.stageHeight+'px'}).hide();
		this.stage.appendChild(this.slide1);
		this.stage.appendChild(this.slide2);		
		
		this.slide1Img = new Element('img', { 'class': 'slideImg slide1Img', 'src': this.scriptDir+'/images/spacer.gif' });
		this.slide2Img = new Element('img', { 'class': 'slideImg slide2Img', 'src': this.scriptDir+'/images/spacer.gif' });
		this.slide1.appendChild(this.slide1Img);
		this.slide2.appendChild(this.slide2Img);		

		this.captionContainerTop = this.stageHeight-23;
		this.captionContainerWidth = (this.mode=='content')? 332 : 380;
		this.captionContainerLeft = (this.mode=='content')? -352 : -501;

		this.captionContainer1 = new Element('div', { 'class': 'captionContainer captionContainer1'
											 		}).setStyle({
														'top': this.captionContainerTop+'px',
														'left': this.captionContainerLeft+'px',
														'width': this.captionContainerWidth+'px'
													});
		
		this.captionContainer2 = new Element('div', { 'class': 'captionContainer captionContainer2'
													}).setStyle({
														'top': this.captionContainerTop+'px',
														'left': this.captionContainerLeft+'px',
														'width': this.captionContainerWidth+'px'
													});		

		this.caption1 = new Element('span', { 'class': 'caption caption1' }).hide();
		this.caption2 = new Element('span', { 'class': 'caption caption2' }).hide();
		this.captionContainer1.appendChild(this.caption1);
		this.captionContainer2.appendChild(this.caption2);
		
		this.slide1.appendChild(this.captionContainer1);
		this.slide2.appendChild(this.captionContainer2);
		this.slide1.captionContainer = this.captionContainer1;
		this.slide2.captionContainer = this.captionContainer2;		

		this.detailBox1 = new Element('div', { 'class': 'detailBox detailBox1' 
									  		 }).setStyle({ 'top': this.detailBoxTop+'px', 
											 			   'left': this.stageWidth+'px', 
														   'width': this.detailBoxWidth+'px' });
		this.detailBox2 = new Element('div', { 'class': 'detailBox detailBox2' 
									  		 }).setStyle({ 'top': this.detailBoxTop+'px', 
											 			   'left': this.stageWidth+'px',
														   'width': this.detailBoxWidth+'px'});
		this.slide1.appendChild(this.detailBox1);
		this.slide2.appendChild(this.detailBox2);
		this.slide1.detailBox = this.detailBox1;
		this.slide2.detailBox = this.detailBox2;
		
		this.detailBoxTop1 = new Element('div', { 'class': 'detailBoxTop detailBoxTop1' });
		this.detailBoxTop2 = new Element('div', { 'class': 'detailBoxTop detailBoxTop2' });
		this.detailBoxBottom1 = new Element('div', { 'class': 'detailBoxBottom detailBoxBottom1' });
		this.detailBoxBottom2 = new Element('div', { 'class': 'detailBoxBottom detailBoxBottom2' });
		
		this.detailBox1.appendChild(this.detailBoxTop1);
		this.detailBox2.appendChild(this.detailBoxTop2);
		this.detailBox1.appendChild(this.detailBoxBottom1);
		this.detailBox2.appendChild(this.detailBoxBottom2);
		
		this.slide1.detailBoxTop = this.detailBoxTop1;
		this.slide2.detailBoxTop = this.detailBoxTop2;
		this.slide1.detailBoxBottom = this.detailBoxBottom1;
		this.slide2.detailBoxBottom = this.detailBoxBottom2;		
		
		var stageEnterEvent = this.isIE? 'mouseenter' : 'mouseover';
		var stageLeaveEvent = this.isIE? 'mouseleave' : 'mouseout';
		this.stage.observe(stageEnterEvent, this.showCaption.bindAsEventListener(this) ); 
		this.stage.observe(stageLeaveEvent, this.hideCaption.bindAsEventListener(this) );
		this.stage.observe(stageEnterEvent, this.showDetailBox.bindAsEventListener(this) ); 
		this.stage.observe(stageLeaveEvent, this.hideDetailBox.bindAsEventListener(this) );
				
		
		this.activeSlide = this.slide1;
		this.inactiveSlide = this.slide2;
		this.activeSlideImg = this.slide1Img;
		this.inactiveSlideImg = this.slide2Img;
		
		this.activeSlide.imgSrc = '';
		this.inactiveSlide.imgSrc = '';

		this.fixIEStyles();
		this.preloadPreloader();
		
		this.activateThumb(this.activeThumb, 'fade');
		this.startSlideshow();
	},
	

	showDetailBox: function(event) { 	
	
		if(!this.isIE && Position.within(this.activeSlide.detailBox, Event.pointerX(event),Event.pointerY(event))){ return; }	
	
		this.cancelDetailBoxSlideEffects();
		
	
		this.detailBoxSlideEffect = new Effect.Parallel( 
			[		
				new Effect.Move( this.activeSlide.detailBox , { x: this.stageWidth - this.detailBoxWidth, y: this.detailBoxTop, mode: 'absolute', sync: true }) ,
				new Effect.Move( this.inactiveSlide.detailBox , { x: this.stageWidth - this.detailBoxWidth, y: this.detailBoxTop, mode: 'absolute', sync: true }) 
			],
			{duration: .25 });
	},
	hideDetailBox: function(event) { 
	
		if(!this.isIE && Position.within(this.activeSlide.detailBox, Event.pointerX(event),Event.pointerY(event))){ return; }	
	
		this.cancelDetailBoxSlideEffects();
		
		this.detailBoxSlideEffect = new Effect.Parallel(
			[
				new Effect.Move( this.activeSlide.detailBox , { x: this.stageWidth, y: this.detailBoxTop, mode: 'absolute', sync: true }) ,
				new Effect.Move( this.inactiveSlide.detailBox , { x: this.stageWidth, y: this.detailBoxTop, mode: 'absolute', sync: true }) 
			],
			{duration: .25 });
	},
	
	cancelDetailBoxSlideEffects: function(){
		if(this.detailBoxSlideEffect){
			this.detailBoxSlideEffect.effects.invoke('cancel');
		}	
	},
	
	
	
	
	
	
	
	
	

	showCaption: function(event) { 	
	
		if(!this.isIE && Position.within(this.activeSlide.captionContainer, Event.pointerX(event),Event.pointerY(event))){ return; }	
	
		this.cancelCaptionSlideEffects();
	
		this.captionSlideEffect = new Effect.Parallel( 													  
			[		
				new Effect.Move( this.activeSlide.captionContainer , { x: 0, y: (this.stageHeight - 23), mode: 'absolute', sync: true }) ,
				new Effect.Move( this.inactiveSlide.captionContainer , { x: 0, y: (this.stageHeight - 23), mode: 'absolute', sync: true }) 
			],
			{duration: .25 });
	},
	hideCaption: function(event) { 
	
		if(!this.isIE && Position.within(this.activeSlide.captionContainer, Event.pointerX(event),Event.pointerY(event))){ return; }	
	
		this.cancelCaptionSlideEffects();
	
		this.captionSlideEffect = new Effect.Parallel(
			[
				new Effect.Move( this.activeSlide.captionContainer , { x: this.captionContainerLeft, y: (this.stageHeight - 23), mode: 'absolute', sync: true }) ,
				new Effect.Move( this.inactiveSlide.captionContainer , { x: this.captionContainerLeft, y: (this.stageHeight - 23), mode: 'absolute', sync: true }) 
			],
			{duration: .25 });
	},
	
	cancelCaptionSlideEffects: function(){
		if(this.captionSlideEffect){
			this.captionSlideEffect.effects.invoke('cancel');
		}	
	},

	startSlideshow: function(){	
		if(this.enableSlideshow){
			this.slideShowInterval = setInterval( this.startSlideshow2.bind(this), this.slideShowDuration * 1000);
		}
	},

	startSlideshow2: function(){
		if(this.enableSlideshow){			
			this.inactiveThumbImgs.each(function(e,i){
				if(this.activeThumb == e){
					this.ssCounter = i;
					this.ssCounter = (this.ssCounter==this.inactiveThumbImgs.length-1)? 0 : this.ssCounter+1; 
				}
			}.bind(this));
			
			this.activateThumb(this.inactiveThumbImgs[this.ssCounter],'fade');
			this.slideshowActive = true;
		}
	},
	
	stopSlideshow: function(){
		clearInterval(this.slideShowInterval);
		this.slideshowActive = false;
	},

	activateThumb: function(e, effect, direction){

		if(this.swapWait){ return false; }
		
		this.activeThumb.isActive = false;
		//this.activeThumb.removeClassName('active');
		//this.activeThumb.src = this.activeThumb.inactiveThumbSrc;		
		
		e.isActive = true;
		//e.src = e.activeThumbSrc;
		//e.addClassName('active');
		this.activeThumb = e;
		
		this.swapSlides(effect, direction);
	},

	swapSlides: function(effect, direction) {


		if(this.swapWait){
			return false;
		}

		this.swapWait = true;
		this.startPreloader();

		this.preloadImage(this.activeThumb.fullSrc, function(){

			this.stopPreloader();
			
			//this.inactiveSlide.setStyle({backgroundImage : 'url('+this.activeThumb.fullSrc+')'});	
			this.inactiveSlideImg.src = this.activeThumb.fullSrc;
			this.inactiveSlide.imgSrc = this.activeThumb.fullSrc;
			
			this.inactiveSlide.detailBoxBottom.update(this.activeThumb.specs);

			if(this.mode=='home' || this.inactiveThumbImgs.length <=1 ){

				this.inactiveSlide.detailBoxTop.update( '<h2>'+this.activeThumb.place+'</h2>' +
													   	'<h3>'+this.activeThumb.location+'</h3>');
				
			}else{

				this.inactiveSlide.detailBoxBottom.update(this.activeThumb.specs);
				this.inactiveSlide.detailBoxTop.update('');

				//var prevBtn = new Element('a',{href:'javascript:;'}).update('&#9668;');
				//prevBtn.observe('click', function(){ this.prevNext('prev'); }.bind(this) );
				//this.inactiveSlide.detailBoxTop.appendChild(prevBtn);

				this.inactiveSlide.detailBoxTop.addClassName('detailBoxTopThumbs');

				this.inactiveThumbImgs.each(function(e, i){
				
					var inlineThumb = new Element('a',{href:'javascript:;'});
					
					if(e.thumbImg.src==''){
						inlineThumb.update(i+1);
					}else{
						inlineThumb.update('<img src="'+e.thumbImg.src+'" class="detailBoxThumbImg" alt="'+(e.caption)+'"/>');
					}
					
					inlineThumb.observe('click', function(){ setTimeout(function(){this.activateThumb(e, 'fade');}.bind(this), 50); }.bind(this) );
					
					if(e == this.activeThumb){
						inlineThumb.addClassName('active');
					}
					
					this.inactiveSlide.detailBoxTop.appendChild(inlineThumb);
					

				}.bind(this));

				//var nextBtn = new Element('a',{href:'javascript:;'}).update('&#9658;');
				//nextBtn.observe('click', function(){ this.prevNext('next'); }.bind(this) );
				//this.inactiveSlide.detailBoxTop.appendChild(nextBtn);
			}
			
			this.doSwapEffect(effect, direction);

		}.bind(this));	
	},
	
	prevNext: function(direction){

		this.stopSlideshow();

		var designatedIndex = 0;
		this.inactiveThumbImgs.each(function(img,imgIndex){
			if( img == this.activeThumb ){ 
				designatedIndex = imgIndex;
			}
		}.bind(this));
		
		if(direction=='next'){
			designatedIndex++;
		}else{
			designatedIndex--;
		}
		
		if (!this.inactiveThumbImgs[designatedIndex]) {
			designatedIndex = (designatedIndex > 0)? 0 : this.inactiveThumbImgs.length - 1;
		}

		var designatedThumb = this.inactiveThumbImgs[designatedIndex];
		//this.activateThumb(designatedThumb, 'fade');

		setTimeout(function(){this.activateThumb(designatedThumb, 'fade');}.bind(this), 50); 

		this.prevNextHook();
	},

	doSwapEffect: function(effect, direction, afterFinishFunc) {

		this.swapHook();

		if(this.activeThumb.caption !== ''){
			this.inactiveSlide.captionContainer.update(this.activeThumb.caption).show();
		}else{
			this.inactiveSlide.captionContainer.hide();
		}

		if(effect=='fade'){

			this.inactiveSlide.setStyle({zIndex:20});
			this.activeSlide.setStyle({zIndex:10});

			new Effect.Appear(this.inactiveSlide, {
				duration: this.enableSlideshow? this.slideShowFadeTime : this.fadeTime,
				afterFinish:function(){
					this.postEffectSwapHook();
					this.swapActiveSlide();
					this.resetInactiveSlideProps();
					if(afterFinishFunc){
						afterFinishFunc();
					}
					this.swapWait=false;
				}.bind(this)
			});	
		}
	},
	
	swapActiveSlide: function(){
		var tmp = this.inactiveSlide;
		var tmp2 = this.inactiveSlideImg;
		
		this.inactiveSlide = this.activeSlide;
		this.inactiveSlideImg = this.activeSlideImg;

		this.activeSlide = tmp;
		this.activeSlideImg = tmp2;

		this.inactiveSlide.hide();
	},	

	resetInactiveSlideProps: function(){
		this.inactiveSlideImg.setStyle({ width:'auto', height:'auto', top:0, left:0});
	},
	
	preloadImage: function(src,onload){
		var e = document.createElement("img");
		e.onload = (onload==null)? function(){} : onload;
		e.onerror = (onload==null)? function(){} : onload;
		e.src = src;
		e.style.left = '-99999px';
		e.style.top = 0;
		e.style.position = 'absolute';
		e.style.visibility = 'hidden';
		document.body.appendChild(e);
		return e;
	},
	
	preloaderFrame: 1,
	preloaderInterval: null,
	preloaderOn: false,
	preloaderDelay: null,
	
	preloadPreloader: function(){
		this.preloader = new Element('div', { 'class': 'preloader' 
											}).setStyle({
												'left':( this.stageWidth / 2 - 25) + 'px',
												'top':( this.stageHeight / 2 - 25) + 'px'
											}).hide();
		
		this.stage.appendChild(this.preloader);
		
		for(i=1; i<=12; i++){
			this.preloadImage(this.scriptDir + '/images/spinner/'+i+'.png');
		}		
	},
	
	stopPreloader: function(){
		if(this.preloaderOn){
			clearTimeout(this.preloaderDelay);
			clearTimeout(this.preloaderTimeout);
			
			this.preloaderOn = false;
			this.preloader.hide();
		}
	},
	
	startPreloader: function(){
		//give the browser a second to catch up before showing the preloader
		this.preloaderOn = true;
		this.preloaderDelay = setTimeout(function(){this.startPreloader2()}.bind(this),300);
	},
	
	startPreloader2: function(){
		if(!this.slideshowActive){
			this.preloader.show();
			this.preloaderNextFrame();
		}
	},
	
	preloaderNextFrame: function(){
		this.preloader.removeClassName('preloader'+this.preloaderFrame);
		this.preloaderFrame = (this.preloaderFrame == 12)? 1 : this.preloaderFrame+1;
		this.preloader.addClassName('preloader'+this.preloaderFrame);
		this.preloaderTimeout = setTimeout(function(){this.preloaderNextFrame();}.bind(this),100);
	},

	fixIEStyles: function(){		
	
		if(this.isIE){
			//preloader styles
			for(i=1; i<=12; i++){			
				document.styleSheets[document.styleSheets.length-1].addRule(".preloader"+i, "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+this.scriptDir+"/images/spinner/"+i+".png');");
				document.styleSheets[document.styleSheets.length-1].addRule(".preloader"+i, "background-image: none");
			}

			this.slide1Img.galleryimg='no';
			this.slide2Img.galleryimg='no';			
		}
	},
	
	destroy: function(){
		this.stage.innerHTML = '';
	}
});