/************************************************ 
 * Copyright © 2009 FL-2. All Rights Reserved.  *
 * Updated by: Matt Wiggins, 20-Apr-2009        *
 *                                              *
 * What about the image gallery times?          *
 *                                              *
 * NOTE: Requires jQuery.                       *
 ************************************************
/                                              */
ImageGallery = {
	/************************************************ 
	 * class members                                *
	 ************************************************
	/                                              */
	// gallery stuff
	_ready:false,
	_locked:false,
	_loaded:false,
	_images:new Array(),
	_index:0,
	_totalImages:0,
	
	// slideshow stuff
	_slideshow:false, // set to true for autoplay
	_ssTimeout:0, // timeout id
	_ssTime:5000, // slideshow time in milliseconds
	
	// event stuff
	_addedListener:function(){},
	_removedListener:function(){},
	_changeListener:function(){},
	
	/************************************************ 
	 * init:void                                    *
	 *                                              *
	 * NOTE: a call to this method is required and  *
	 * must be made after the document is ready.    *
	 *                                              *
	 * container:String - desired containing div    *
	 ************************************************
	/                                              */
	init:function(container) {
		// if jQuery hasn't joined the party ...
		if(typeof($) == 'undefined')
		{
			throw("Error: jQuery is required for this page to function properly.");
			return;
		}
		
		// build gallery loading divs
		var divImgGallery = document.createElement('div');
		
		divImgGallery.id = 'fl2-image-gallery';
		divImgGallery.style.position = "relative";
		divImgGallery.style.width = '100%';
		divImgGallery.style.height = '100%';
		
		divImgGallery.innerHTML = '<img id="container-img" src="" width="0" height="0" alt="" />';
		
		var divLoader = document.createElement('div');
		
		divLoader.id = 'loading';
		divLoader.style.position = 'absolute';
		divLoader.style.top = '50%';
		divLoader.style.left = '50%';
		divLoader.style.marginTop = '-8px';
		divLoader.style.marginLeft = '-8px';
		divLoader.style.width = '16px';
		divLoader.style.height = '16px';
		divLoader.style.display = 'none';
		
		divLoader.innerHTML = '<img src="data/images/preloader.gif" width="16" height="16" alt="" />';
		
		divImgGallery.appendChild(divLoader);
		document.getElementById(container).appendChild(divImgGallery);
		
		// initially hide the container image and
		// register a load handler
		$('#container-img').attr('style', 'display:none');
		$('#container-img').load(ImageGallery._onImageLoad);
		
		ImageGallery._ready = true;
	},
	
	/************************************************ 
	 * add:void                                     *
	 *                                              *
	 * Add an image to the gallery.                 *
	 *                                              *
	 * path   :String - path to the image           *
	 * alt    :String - alternate text              *
	 * width  :Number - image width                 *
	 * height :Number - image height                *
	 ************************************************
	/                                              */
	add:function(path, alt, width, height, description) {
		if(!ImageGallery._ready) return;
		
		// add image, load it if it's the first one
		ImageGallery._images[ImageGallery._totalImages] = {path:path, alt:alt, width:width, height:height, description:description};
		if(ImageGallery._totalImages == 0) ImageGallery._loadImage(ImageGallery._images[0]);
		ImageGallery._totalImages++;
		
		// dispatch event
		ImageGallery._addedListener();
	},
	
	/************************************************ 
	 * remove:void                                  *
	 *                                              *
	 * Remove an image to the gallery.              *
	 *                                              *
	 * id :Number - index to remove                 *
	 ************************************************
	/                                              */
	remove:function(id) {
		if(!ImageGallery._ready) return;
		if(id > (ImageGallery._images.length - 1) || id < 0)
		{	
			throw('Error: ImageGallery.remove() index \'' + id + '\' is out of range.');
		}
		
		ImageGallery._images.splice(id, 1);
		ImageGallery._totalImages--;
		
		// dispatch event
		ImageGallery._removedListener();
	},
	
	/************************************************ 
	 * previous:void                                *
	 *                                              *
	 * Move to the previous image if this is not    *
	 * the first image in the gallery.              *
	 ************************************************
	/                                              */
	previous:function() {
		if(!ImageGallery._ready || ImageGallery._locked) return;
		
		ImageGallery._locked = true;
		
		if(ImageGallery._index == 0) ImageGallery._index = ImageGallery._images.length - 1;
		else ImageGallery._index--;
		
		ImageGallery._loadImage(ImageGallery._images[ImageGallery._index]);
	},
	
	/************************************************ 
	 * next:void                                    *
	 *                                              *
	 * Move to the next image if this is not        *
	 * the last image in the gallery.               *
	 ************************************************
	/                                              */
	next:function() {
		if(!ImageGallery._ready || ImageGallery._locked) return;
		
		ImageGallery._locked = true;
		
		if(ImageGallery._index == ImageGallery._images.length - 1) ImageGallery._index = 0;
		else ImageGallery._index++;
		ImageGallery._loadImage(ImageGallery._images[ImageGallery._index]);
	},
	
	/************************************************ 
	 * move:void                                    *
	 *                                              *
	 * Move to the specified index if it exists.    *
	 *                                              *
	 * id :Number - index to move to                *
	 ************************************************
	/                                              */
	move:function(id) {
		if(!ImageGallery._ready || ImageGallery._locked) return;
		
		ImageGallery._locked = true;
		
		if(id < 0 || id >= ImageGallery._images.length - 1)
		{
			throw("Error: Index out of range.");
			return;	
		}
		else ImageGallery._index = id;
		ImageGallery._loadImage(ImageGallery._images[ImageGallery._index]);
	},
	
	/************************************************ 
	 * slideshowOn:void                             *
	 *                                              *
	 * Toggle slideshow on.                         *
	 ************************************************
	/                                              */
	slideshowOn:function(ssTime) {
		if(!ImageGallery._ready) return;		
		if(typeof(ssTime) == 'undefined') ssTime = 5000;

		ImageGallery._slideshow = true;
		ImageGallery._ssTime = ssTime;
		ImageGallery._ssTimeout = setTimeout(ImageGallery.next, ImageGallery._ssTime);
	},
	
	/************************************************ 
	 * slideshowOff:void                            *
	 *                                              *
	 * Toggle slideshow off.                        *
	 ************************************************
	/                                              */
	slideshowOff:function() {
		if(!ImageGallery._ready) return;

		clearTimeout(ImageGallery._ssTimeout);
		ImageGallery._slideshow = false;
	},
	
	/************************************************ 
	 * events                                       *
	 ************************************************
	/                                              */
	
	/************************************************ 
	 * onImageAdded:void                            *
	 *                                              *
	 * Register an event listener for when an       *
	 * image is added to the gallery.               *
	 ************************************************
	/                                              */
	onImageAdded:function(fn) {
		if(!ImageGallery._ready || typeof(fn) != 'function') return;
		ImageGallery._addedListener = fn;
	},
	
	/************************************************ 
	 * onImageRemoved:void                          *
	 *                                              *
	 * Register an event listener for when an       *
	 * image is removed from the gallery.           *
	 ************************************************
	/                                              */
	onImageRemoved:function(fn) {
		if(!ImageGallery._ready || typeof(fn) != 'function') return;
		ImageGallery._removedListener = fn;
	},
	
	/************************************************ 
	 * onImageChange:void                           *
	 *                                              *
	 * Register an event listener for image         *
	 * change.                                      *
	 ************************************************
	/                                              */
	onImageChange:function(fn) {
		if(!ImageGallery._ready || typeof(fn) != 'function') return;
		ImageGallery._changeListener = fn;
	},
	
	/************************************************ 
	 * private functions                            *
	 ************************************************
	/                                              */
	
	/************************************************ 
	 * loadImage:void (private)                     *
	 *                                              *
	 * Load a new image.                            *
	 *                                              *
	 * img :Object - image to load                  *
	 ************************************************
	/                                              */
	_loadImage:function(img) {
		if(ImageGallery._loaded)
		{
			$('#container-img').fadeOut(750, function() {
				$('#loading').fadeIn('fast');
				$('#container-img').attr('src', img.path);
				$('#container-img').attr('alt', img.alt);
				$('#container-img').attr('width', img.width);
				$('#container-img').attr('height', img.height);
			});
		} else {
			$('#container-img').attr('src', img.path);
			$('#container-img').attr('alt', img.alt);
			$('#container-img').attr('width', img.width);
			$('#container-img').attr('height', img.height);
			ImageGallery._loaded = true;
		}
	},
	
	/************************************************ 
	 * onImageLoad:void (private)                   *
	 *                                              *
	 * Handle image loading complete.               *
	 ************************************************
	/                                              */
	_onImageLoad:function() {
		$('#loading').fadeOut('fast', function() {
			$('#container-img').fadeIn(750, function() {
				ImageGallery._locked = false;
				if(ImageGallery._slideshow) ImageGallery._ssTimeout = setTimeout(ImageGallery.next, ImageGallery._ssTime);
				
				// dispatch event
				ImageGallery._changeListener();
			});
		});
	},
	
	/************************************************ 
	 * getter/setter                                *
	 ************************************************
	/                                              */
	
	/************************************************ 
	 * gReady:Boolean (getter)                      *
	 *                                              *
	 * Read-only ready                              *
	 ************************************************
	/                                              */
	gReady:function() {
		return ImageGallery._ready;	
	},
	
	/************************************************ 
	 * gIndex:Number (getter)                       *
	 *                                              *
	 * Current displayed index. Set with public     *
	 * show() method.                               *
	 ************************************************
	/                                              */
	gIndex:function() {
		return ImageGallery._index;	
	},
	
	/************************************************ 
	 * gDescription:String (getter)                 *
	 *                                              *
	 * The current selected photo's description.    *
	 ************************************************
	/                                              */
	gDescription:function() {
		return ImageGallery._images[ImageGallery._index].description;
	},
	
	/************************************************ 
	 * gTotalImages:Number (getter)                 *
	 *                                              *
	 * Get the total number of images currently     *
	 * loaded into the gallery.                     *
	 ************************************************
	/                                              */
	gTotalImages:function() {
		return ImageGallery._totalImages;
	}
}