﻿

/**
 * NEXT
 *
 *	- Hide / show LOADING STATE
 */


/// <reference path="../../../../../jQuery/1.3.2/jquery-1.3.2-vsdoc.js" />


/**
 * ImageGallery
 *
 * Lightbox style overlay imageGallery functionality
 *
 * Author : Liam Prescott
 */

	//Check that namespace into which the Class definition will be creates has been defined & if not then create
	if (!couk.liamprescott.global.isNamespaceDefined("couk.liamprescott.common.display.imageGallery")) couk.liamprescott.global.createNamespace("couk.liamprescott.common.display.imageGallery", "1.0");
	
	
	// Class definition
	couk.liamprescott.common.display.imageGallery.ImageGallery = Object.subClass(
		{
			/*
			 =============================
			 CONSTANTS
			 =============================
			 */
				JQUERY_ID_IMAGE			: "#image",
				JQUERY_ID_LINK_NEXT		: "#navigation-next",
				JQUERY_ID_LINK_LAST		: "#navigation-last",
				JQUERY_ID_LINK_CLOSE	: "#close-window-link",
				
				JQUERY_ID_IFRAME			: "#overlay-iframe-fix",
				JQUERY_ID_BACKGROUND		: "#overlay-background",
				JQUERY_ID_WINDOW_CONTAINER	: "#overlay-window-container",
				JQUERY_ID_WINDOW			: "#overlay-window",
				JQUERY_ID_LOADING_ICON		: "#loading-icon-container",
				
				CLASS_PAGINATION_LINK_DISABLED	: "navigation-link-disabled",
				
				//BLANK_IMAGE_URL : "/assets/images/image-gallery/_blank.gif",
			
			
			/*
			 =============================
			 CONFIGURATION PROPERTIES
			 =============================
			 */
				// [ String ] Target element target string
				_targetID : "gallery-image",
				
				// [ Boolean ] : Display image titles flag
				_displayTitles : false,
				
				// [ Boolean ] : Display summary (Image x of x) flag
				_displaySummary : false,
				
				// [ Boolean ] : Display summary (Image x of x) flag
				_displayData : false,
			
			
			
			/*
			 =============================
			 CONSTRUCTOR
			 =============================
			 */	
				init : function (targetID, displayTitles, displaySummary)
				{
					this._this = this;
					
					// Store config properties
					if (targetID && targetID != "") this._targetID = targetID;
					
					if (displayTitles) 
					{
						this._displayTitles = displayTitles;
						this._displayData	= true;
					}
					
					if (displaySummary) 
					{
						this._displaySummary	= displaySummary;
						this._displayData		= true;
					}
					
					// Create new imageData array
					this._imageData = [];
										
					//Local reference to self (instance)
					var __this = this;
					$(document).ready(function()
					{
						__this._setup();
					});
					
				},
				
			
			
			/*
			 =============================
			 INTERNAL RUN-TIME PROPERTIES
			 =============================
			 */	
				// [ ImageGallery ] : Self scope reference
				_this : undefined,
				
				
				// [ Array ] : Collection of image data arrays - an array of [url, title] format arrays
				_imageData : undefined,
				
				
				// [ int ] : ID (internal) of current image being displayed
				_displayID : undefined,
				
				
				// [ Image ] : Preloader image instance
				_preloader : undefined,
				
				
				// [ Boolean ] : Display ready for loaded image flag
				_displayReady : false,
				
				
				// [ Boolean ] : Currently loading an image flag
				_loading : false,
				
				
				// [ Boolean ] : Currently active flag
				_active : false,
				
				
				// [ String ] : Html string appended to document
				_html : "",
				
				
				// [ Boolean ] : Loop image display
				_loopImages : true,
				
				
				// [ int ] : Resize duration
				_resizeDuration : 700,
				
				// [ String ] : Resize easing function
				_resizeEasingFunction : "easeOutCubic", // "easeOutBounce"; // "easeOutCubic"; // "easeLinear";
				
				
				// [ int ] : image fade in duration
				_imageShowDuration : 300,
				
				// [ String ] : image fade in easing function
				_imageShowFunction : "easeOutCubic",
				
				
				// [ int ] : target display width of newly loaded image
				_targetDisplayWidth : undefined,
				
				// [ int ] : target display height of newly loaded image
				_targetDisplayHeight : undefined,
				
				
				// [ int ] : current display width
				_displayWidth : undefined,
				
				// [ int ] : current display height
				_displayHeight : undefined,


			
			/*
			 =============================
			 PUBLIC METHODS
			 =============================
			 */
				// @param	url [String]	image url
				// @param	title [String]	image title (if undefined will auto add empty string)
				// @return	[int]			resultant image id (to use when opening gallery)
				addImage : function (url, title)
				{
					this._imageData.push([url, ((title != undefined) ? title : "")]);
					return this._imageData.length-1;	
				},
				
				
				
				// @param	id [int]	image id to display
				displayImage : function (id)
				{
					//alert("displayImage - " + id);
					
					// Set current display ID
					this._displayID = id;
					
					// Create display
					this._setupDisplay(id);
					
					// Load image
					this._loadImage();
				},
			
			
				closeDisplay : function ()
				{
					// Clear any loading image
					if (this._preloader)
					{
						this._preloader.onload = function(){};
						this._preloader.src = "";
					}
					
					// Reset display parameters
					this._targetDisplayWidth	= undefined;
					this._targetDisplayHeight	= undefined;
					this._displayWidth			= undefined;
					this._displayHeight			= undefined;
					
					// Destroy display
					this._destroyDisplay();
					
					// Set display ready = false
					this._displayReady = false;
					
					// set loading image = false
					this._loading = false;
					
					// Clear keyboard functionality
				},
			
			
			
			/*
			 =============================
			 INTERNAL METHODS
			 =============================
			 */
				/*
				 =============================
				 UTILITIES
				 =============================
				 */
					// @param	id [int] Internal id / array position
					// @return	[Array]
					_getImageData : function (id)
					{
						return this._imageData[id];
					},
					
					
					// @param	imageData Array [url, title]
					// @return	[String]
					_getImageUrl : function (data)
					{
						return data[0];
					},
					
					
					// @param	imageData Array [url, title]
					// @return	[String]
					_getImageTitle : function (data)
					{
						return data[1];
					},
				
				
				
				/*
				 =============================
				 SETUP
				 =============================
				 */
					_setup : function ()
					{
						// Configure and Store html string (if ie)
						if($.browser.msie && $.browser.version < 7 ) 
						{
							this._html += '<iframe id="overlay-iframe-fix"></iframe>';
						}
						
						this._html +=
						(
							'<div id="overlay-background" class="overlay-background"></div>' +
							'<div id="overlay-window-container" style="overflow:visible !important; overflow-x:visible !important; overflow-y:visible !important;">' +
								'<div id="overlay-window">' +
									'<div id="loading-icon-container">' +
										'<img src="assets/images/image-gallery/loading.gif" />' +
									'</div>' +
									'<div id="overlay-window-body">' +
										'<img id="image" src="assets/images/image-gallery/_blank.gif" style="display:none" />' +
									'</div>' +
									'<div id="tl" class="png"></div>' +
									'<div id="tr" class="png"></div>' +
									'<div id="bl" class="png"></div>' +
									'<div id="br" class="png"></div>' +
									'<div id="t" class="png"></div>' +
									'<div id="l" class="png"></div>' +
									'<div id="b" class="png"></div>' +
									'<div id="r" class="png"></div>' +
									'<div id="navigation-last"><a id="navigation-last-link" class="a-auto-hover navigation-link">Last</a></div>' +
									'<div id="navigation-next"><a id="navigation-next-link" class="a-auto-hover navigation-link">Next</a></div>' +
									'<div id="close-window"><a id="close-window-link" class="png a-auto-hover"></a></div>' +
								'</div>' +
							'</div>'
						);
						
						// Process link items
						var items	= $('a[rel^=' + this._targetID + ']');
						var __this	= this;
						items.each(function (i)
						{
							__this._processLinkItem(this, i);
						});
						
					},
					
					
					
					// @param domElement	
					// @param i	[int]
					_processLinkItem : function (domElement, i)
					{
						var element = $(domElement)
						
						// Extract url from rel property of <a>
						var id		= "url["; 
						var s		= element.attr('rel')
						var start	= s.indexOf(id) + id.length;
						var finish	= s.indexOf("]", start);
						
						var url = s.slice(start, finish);
						
						// Extraxt image title
						var title	= element.attr('title');
						
						// Store image data and save returned id
						var id = this.addImage(url, title);
						
						// Attach click functionality to link
						var __this = this;
						element.click(function ()
						{
							__this.displayImage(id);
						});
						
					},
					
					
					
					_setupCloseFunctionality : function ()
					{
						var __this = this;
						
						// Add close click to link
						$(this.JQUERY_ID_LINK_CLOSE).click(function ()
						{
							__this.closeDisplay();
						});
						
						// Add close click to overlay elements
						$(this.JQUERY_ID_BACKGROUND + "," + this.JQUERY_ID_WINDOW_CONTAINER).click(function ()
						{
							__this.closeDisplay();
						});
						
						// Add close click override to STOP close click functionality when actual window / contents are clicked - this way user HAS to click OUTSIDE window
						$(this.JQUERY_ID_WINDOW).click(function (e)
						{
							e.stopPropagation();
						});
					},
					
					
					
					_prepareDisplayForImageLoad : function ()
					{
						// Hide next / last buttons
						var next	= $(this.JQUERY_ID_LINK_NEXT);
						var last	= $(this.JQUERY_ID_LINK_LAST);
						var c		= this.CLASS_PAGINATION_LINK_DISABLED;
						
						if (!last.hasClass(c)) last.addClass(c);
						if (!next.hasClass(c)) next.addClass(c);
						
						
						
						// TODO :: Hide sumamry text and image title
					
					},
					
					
					
					_configureNavigationLinks : function ()
					{
						// Set next / last button opacity
						var next = $(this.JQUERY_ID_LINK_NEXT);
						var last = $(this.JQUERY_ID_LINK_LAST);
						
						var id	= this._displayID;
						var c	= this.CLASS_PAGINATION_LINK_DISABLED;
						
						// if !loop	: remove click events from first / last links where appropriate
						//			: add disabled class names to first / last links where appropriate
						
						// Always unbind as CANNOT check for existance of click event
						last.unbind("click");
						next.unbind("click");
						
						if (id == 0 && !this._loopImages) {	if (!last.hasClass(c)) last.addClass(c); }
						else 
						{
							if (last.hasClass(c)) last.removeClass(c);
							last.bind("click", {_this : this}, this._handleLoadImageLast);
						}
						
						if (id == this._imageData.length-1 && !this._loopImages) { if (!next.hasClass(c)) next.addClass(c); }
						else 
						{
							if (next.hasClass(c)) next.removeClass(c);
							next.bind("click", {_this : this}, this._handleLoadImageNext);
						}
												
					},
					
					
				
				
				/*
				 =============================
				 DISPLAY CREATION
				 =============================
				 */
					_setupDisplay : function (id)
					{
						// Add html
						$('body').append(this._html);
						
						// Display Window (will resize on image load)
						$(this.JQUERY_ID_WINDOW_CONTAINER).css("display", "block");
						
						// Run png fix
						var pngs = $("#overlay-window-container #overlay-window .png");
						for (var i = 0; i < pngs.length; i++) 
						{
							fix_PNG(pngs[i]);
						}
						
						// Run auto-hover activation
						setupHoverBehaviour("#overlay-window-container #overlay-window .a-auto-hover");
						
						
						// Deactivate
						this._active = false;
						
						// Prepare display for image load
						this._prepareDisplayForImageLoad();
						
						// Setup close functionality
						this._setupCloseFunctionality();
					},
					
					
					
					_destroyDisplay : function ()
					{
						// Remove html display assets
						$(this.JQUERY_ID_WINDOW_CONTAINER).remove();
						$(this.JQUERY_ID_BACKGROUND).remove();
						
						if ($.browser.msie && $.browser.version < 7)
						{
							$(this.JQUERY_ID_IFRAME).remove();
						}
					},
					
					
					_updateDisplay : function (imageID)
					{
						// Deactivate
						this._active = false;
						
						// Prepare display for image load
						this._prepareDisplayForImageLoad();
						
						// Hide current image
						this._hideImage();
						
						// Set current display ID
						this._displayID = imageID;
						
						// Load image
						this._loadImage();
							
					},
				
				
				/*
				 =============================
				 IMAGE LOADING
				 =============================
				 */	
					_loadImage : function ()
					{
						var __this		= this;
						var __imageUrl	= this._getImageUrl(this._getImageData(this._displayID));
						
						// Set loadng state
						this._loading = true;
						
						// Display loading icon
						$(this.JQUERY_ID_LOADING_ICON).css("visibility", "visible");
						
						// Preload image
						this._preloader = new Image();
						this._preloader.onload = function ()
						{
							// Clear onload functionality
							__this._preloader.onload=function(){};
							// Handle image loaded
							__this._handleImageLoaded(__imageUrl);
						} 
						//alert("LOAD IMAGE : image url = = " + __imageUrl);
						this._preloader.src = __imageUrl;
					},
					
					
					
					_handleImageLoaded : function (imageUrl)
					{
						// Hide loading icon
						$(this.JQUERY_ID_LOADING_ICON).css("visibility", "hidden");
						
						this._loading = false;
						//alert("w = " + this._preloader.width + " // h = " + this._preloader.height);
						
						// Set image src to preloader src (hidden therefore wont be visible)
						$(this.JQUERY_ID_IMAGE).attr("src", imageUrl);
						
						// Extract and save image dimensions
						this._targetDisplayWidth	= this._preloader.width;
						this._targetDisplayHeight	= this._preloader.height;
						
						// Trigger display resize
						this._resizeDisplay();
						
					},
				
				
				
				/*
				 =============================
				 DISPLAY CONTROL
				 =============================
				 */
					_showImage : function () 
					{
						$(this.JQUERY_ID_IMAGE).css("opacity", "0");
						$(this.JQUERY_ID_IMAGE).css("display", "inline-block");
						// Animate opacity (MUST set callback to empty function)
						$(this.JQUERY_ID_IMAGE).animate({"opacity" : 1}, this._imageShowDuration, this._imageShowFunction, function (){});
					},
					
					
					_hideImage : function ()
					{
						$(this.JQUERY_ID_IMAGE).css("opacity", "0");
						$(this.JQUERY_ID_IMAGE).css("display", "none");
						//$(this.JQUERY_ID_IMAGE).hide();
					},
					
					
					_showDetails : function (){},
					
					
					_hideDetails : function (){},
					
					
					_resizeDisplay : function ()
					{
						if (this._targetDisplayWidth != this._displayWidth)
						{
							this._displayWidth = this._targetDisplayWidth;
							this._resizeDisplayWidth();
						}
						else if (this._targetDisplayHeight != this._displayHeight) this._resizeDisplayHeight(this);
						else this._handleResizeComplete(this);
					},
					
					
					_resizeDisplayWidth : function ()
					{
						var __this = this;
						$(this.JQUERY_ID_WINDOW_CONTAINER).animate({"width" : this._displayWidth}, this._resizeDuration, this._resizeEasingFunction, function (){ __this._resizeDisplayHeight(__this); });
					},
					
					
					_resizeDisplayHeight : function (__this)
					{
						var __this = __this;
						
						if (__this._displayHeight != __this._targetDisplayHeight)
						{
							__this._displayHeight = __this._targetDisplayHeight;
							$(__this.JQUERY_ID_WINDOW_CONTAINER).animate({"height" : __this._displayHeight}, __this._resizeDuration, __this._resizeEasingFunction, function (){ __this._handleResizeComplete(__this); });
						}
						else __this._handleResizeComplete(__this);
					},
					
					
					_handleResizeComplete : function (__this)
					{
						__this._configureDisplay();
					},
				
					
					_configureDisplay : function ()
					{
						this._configureNavigationLinks();
						this._showImage();
						
						// Activate
						this._active = true;
					},
					
					
				/*
				 =============================
				 INTERNAL EVENT HANDLERS
				 =============================
				 */
					
					_handleLoadImageNext : function (e)
					{
						//alert("click next");
						var _this = e.data._this;
						if (_this._active)
						{
							var displayID = _this._displayID;
							var nextID;
							
							if (displayID < _this._imageData.length-1) nextID = displayID + 1;
							else
							{
								if (!_this._loopImages) return false;
								else nextID = 0;
							}
							
							_this._updateDisplay(nextID);
						}
					},
					
					_handleLoadImageLast : function (e)
					{
						//alert("click last");
						var _this = e.data._this;
						if (_this._active)
						{
							var displayID = _this._displayID;
							var nextID;
							
							if (displayID > 0 ) nextID = displayID - 1;
							else
							{
								if (!_this._loopImages) return false;
								else nextID = _this._imageData.length-1;
							}
							
							_this._updateDisplay(nextID);
						}
					}
			 
			 
		}
	)
	
	
		
	