//
// 
//  slideshow
//
//  Created by  on 2009-10-31.
//  Copyright (c) 2009 murat n konar. All rights reserved.
//

var Slideshow = new Class({

	// -------------------------------------------------------------
	//	initialize
	// -------------------------------------------------------------
	initialize: function (div)
	{
		if (this.validateStylesAndStructure(div))
		{
			// We want to build this structure:
			//
			//	<div id='slideshow'>
			//
			//		<div id='slide-a'>
			//			<img id='foto-a'>
			//			<p id='caption-a'>This is caption-a.</p>
			//		</div>
			//
			//		<div id='slide-b'>
			//			<img id='foto-b'>
			//			<p id='caption-b'>This is caption-a.</p>
			//		</div>
			//
			//	</div>
			
			
			this.imageDidDisplayHandler = undefined
			this.transitionStyle = 'crossfade'
		
			this.div = div
			this.div.controller = this
					
			this.slides = new Array()
			this.slides.include(this.makeNewSlide('a'))
			this.slides.include(this.makeNewSlide('b'))
		
			this.div.adopt(this.slides[0])
			this.div.adopt(this.slides[1])
						
			this.indexOfCurrentSlide = 0
			
			// setup a spinner
			if (Spinner != undefined)
			{
				var spinnerController = new Spinner({'inverted':true})
				this.spinnerNode = spinnerController.spinnerNode
				
				this.div.adopt(this.spinnerNode)
				this.spinnerNode.setStyle('z-index','1000')
				this.spinnerNode.hideSpinner()
			}
			
			// Add functions to the div for convenience.
			div.setImageSource = function (newImageSource)
			{
				div.controller.setImageSource(newImageSource)
			}

			div.setClickHandler = function (clickHandler)
			{
				div.controller.setClickHandler(clickHandler)
			}

			div.setImageDidDisplayHandler = function (handler)
			{
				div.controller.setImageDidDisplayHandler(handler)
			}
			
			div.setHidden = function (newHidden)
			{
				div.controller.setHidden(newHidden)
			}
			
			div.setNewSize = function (newsize)
			{
				div.controller.setNewSize(newsize)
			}
			
			this.hidden = false
		}
	},

	// -------------------------------------------------------------
	//	setNewSize
	// -------------------------------------------------------------
	setNewSize: function(newsize)
	{
		this.div.setStyles({'width': newsize.x, 'height':newsize.y})
		this.slides[0].setStyles({'width': newsize.x, 'height':newsize.y})
		this.slides[1].setStyles({'width': newsize.x, 'height':newsize.y})
		
		this.fixupImageSize(this.slides[0])
		this.fixupImageSize(this.slides[1])
	},

	// -------------------------------------------------------------
	//	fixupImageSize
	// -------------------------------------------------------------
	fixupImageSize: function(theSlide)
	{	
		var img 			= theSlide.getElement('img')
		var captionHeight	= theSlide.getElement('p').getCoordinates().height

	   	var imageAspect 	= img.getCoordinates().width/img.getCoordinates().height
	   	var imagePlusCaptionAspect 	= img.getCoordinates().width/(img.getCoordinates().height + captionHeight)
	   	var parentAspect 	= this.div.getCoordinates().width/this.div.getCoordinates().height
		
		if (imagePlusCaptionAspect > parentAspect)
		{
			img.setStyles({'height':'', 'width':'100%'})
		}
		else
		{
			var newImageHeight 	= this.div.getCoordinates().height - captionHeight
			
			img.setStyles({'height':newImageHeight+'px', 'width':''})
		}
	},

	// -------------------------------------------------------------
	//	centerElement
	// -------------------------------------------------------------
	centerSlide: function(theSlide)
	{		
	   	var imageWidth 		= img.getCoordinates().width
	   	var parentWidth 	= this.div.getCoordinates().width
		var imageLeft		= (parentWidth - imageWidth)/2
		
		img.setStyle('left', imageLeft + 'px')			
	},

	// -------------------------------------------------------------
	//	makeNewImageElement
	// -------------------------------------------------------------
	makeNewImageElement: function(id_suffix)
	{
		var e = new Element('img', {'id':'foto-' + id_suffix})
		
		var self = this
		
		// -------------------------------------------------------------
		// onload handler: inside here, 'self' refers to the slideshow 
		// object and 'this' refers to the image element that just loaded.
		// -------------------------------------------------------------
		e.addEvent('load', function(){
			
			// fix up dimensions for proper fit.
			self.fixupImageSize(this.getParent())

			// wrap up
			this.getParent().fade('in')
		
			this.getParent().getParent().controller.hideLoadingIndicator()
		
			if (this.getParent().getParent().controller.imageDidDisplayHandler != undefined)
			{
				this.getParent().getParent().controller.imageDidDisplayHandler()
			}
		})
		// -------------------------------------------------------------
		
		e.addEvent('error', function(){
			alert('Image load error while tring to load \n"' + this.src + '".');
		})
		
		return e
	},
	
	// -------------------------------------------------------------
	//	makeNewParagraphElement
	// -------------------------------------------------------------
	makeNewParagraphElement: function(id_suffix)
	{
		var p = new Element('p', {'id':'caption-'+id_suffix, 'class':'caption'})
		p.setStyles({'visibility':'visible', 'opacity': 100})

		p.setProperty('html', 'This is a caption.')

		return p
	},
	
	// -------------------------------------------------------------
	//	makeNewSlide
	// -------------------------------------------------------------
	makeNewSlide: function(id_suffix)
	{
		var e = new Element('div', {'id':'slide-'+id_suffix, 'class':'slide'})
		e.setStyles({'position':'absolute', 'top': 0, 'left': 0, 'visibility':'hidden', 'opacity': 0})
		e.adopt(this.makeNewImageElement(id_suffix), this.makeNewParagraphElement(id_suffix))
				
		return e
	},

	// -------------------------------------------------------------
	//	showLoadingIndicator
	// -------------------------------------------------------------
	showLoadingIndicator: function ()
	{
		if (this.customLoadingIndicator != undefined)
		{
			this.customLoadingIndicator.fade('in')
		}
		else
		{
			this.spinnerNode.showSpinner()
		}
	},
	
	// -------------------------------------------------------------
	//	hideLoadingIndicator
	// -------------------------------------------------------------
	hideLoadingIndicator: function ()
	{
		if (this.customLoadingIndicator != undefined)
		{
			this.customLoadingIndicator.fade('out')
		}
		else
		{
			this.spinnerNode.hideSpinner()
		}
	},

	// -------------------------------------------------------------
	//	validateStylesAndStructure
	// 	Verify that the 'slideshow' div exists and is properly positioned.	
	// -------------------------------------------------------------
	validateStylesAndStructure: function(theDiv)
	{
		var valid = true
	
		if (theDiv == undefined || theDiv == null)
		{
			alert('"slideshow" div not found!');
			valid = false
		}
		else 
		{
			var positioning = theDiv.getStyle('position')
			if (positioning != 'absolute' && positioning != 'relative' && positioning != 'fixed')
			{
				alert('"slideshow" div must be positioned absolute, relative, or fixed!');
				valid = false
			}
		}
		
		return valid
	},

	// -------------------------------------------------------------
	//	setTransitionStyle
	// -------------------------------------------------------------
	setTransitionStyle: function (transitionStyle)
	{
		// transitionStyle = 'crossfade' | 'fadeoutin' 
		
		if (transitionStyle == 'crossfade' || transitionStyle == 'fadeoutin')
		{
			this.transitionStyle = transitionStyle
		}
		else
		{
			alert('bad transition style');
		}
	},
	
	// -------------------------------------------------------------
	//	setClickHandler
	// -------------------------------------------------------------
	setClickHandler: function (theHandler)
	{
		this.div.addEvent('click', theHandler)
	},
	
	// -------------------------------------------------------------
	//	setImageDidDisplayHandler
	// -------------------------------------------------------------
	setImageDidDisplayHandler: function (theHandler)
	{
		this.imageDidDisplayHandler = theHandler
	},
	
	// -------------------------------------------------------------
	//	getImageSource
	// -------------------------------------------------------------
	getImageSource: function ()
	{
		// return the src of the image currently being displayed.
		return this.slides[this.indexOfCurrentSlide].getElement('img').getProperty('src')
	},
	
	// -------------------------------------------------------------
	//	getImageCoordinates
	// -------------------------------------------------------------
	getImageCoordinates: function ()
	{
		// return the coordinates of the image currently being displayed.
		return this.slides[this.indexOfCurrentSlide].getElement('img').getCoordinates()
	},
	
	// -------------------------------------------------------------
	//	setImageSource
	// -------------------------------------------------------------
	setImageSource: function (newImageSource, newCaption)
	{	
		if (this.getImageSource() != newImageSource)
		{
			// start fading the currently displayed img element
			this.slides[this.indexOfCurrentSlide].fade('out')
			
			// increment img index
			this.indexOfCurrentSlide = (this.indexOfCurrentSlide + 1) % 2		
			
			if (newImageSource == '')
			{
				this.slides[this.indexOfCurrentSlide].getElement('img').setProperty('src', 'slideshow/empty.png')
				this.slides[this.indexOfCurrentSlide].getElement('p').set('html', '')
			}
			else
			{
				if (this.slides[this.indexOfCurrentSlide].getElement('img').getProperty('src') != newImageSource) // (Avoid redundantly loading an image)
				{
					this.slides[this.indexOfCurrentSlide].getElement('img').setProperty('src', newImageSource)
					this.slides[this.indexOfCurrentSlide].getElement('p').set('html', newCaption)

					var complete = this.slides[this.indexOfCurrentSlide].getElement('img').getProperty('complete')
					if (complete == 'true')
					{						
						this.slides[this.indexOfCurrentSlide].fade('in')
						if (this.imageDidDisplayHandler != undefined)
						{
							this.imageDidDisplayHandler()
						}
					}
					else
					{
						this.showLoadingIndicator() // ...the onload handler will fade the image in.
					}
				}
				else
				{
					this.slides[this.indexOfCurrentSlide].fade('in')
					if (this.imageDidDisplayHandler != undefined)
					{
						this.imageDidDisplayHandler()
					}
				}
			}
		}
	},
	
	// -------------------------------------------------------------
	//	setHidden
	// -------------------------------------------------------------
	setHidden: function (newHidden)
	{
		if (newHidden != this.hidden)
		{
			if (newHidden)
			{
				this.div.fade('out')
				this.setImageSource('')
			}
			else
			{
				this.div.fade('in')
			}
			this.hidden = newHidden;
		}
	}
});
