/**
 * jQuery Galleriffic plugin
 *
 * Copyright (c) 2008 Trent Foley (http://trentacular.com)
 * Licensed under the MIT License:
 *   http://www.opensource.org/licenses/mit-license.php
 *
 * Much thanks to primary contributer Ponticlaro (http://www.ponticlaro.com)
 */
var current_page = '';
var menu_down_height = 0;
var menu_up_height = 0;

;(function($) {
	// Globally keep track of all images by their unique hash.  Each item is an image data object.
	var allImages = {};
	var imageCounter = 0;

	// Galleriffic static class
	$.galleriffic = {
	version: '2.0.1',

		// Strips invalid characters and any leading # characters
			normalizeHash: function(hash) {
				return hash.replace(/^.*#/, '').replace(/\?.*$/, '');
			},

			getImage: function(hash) {
				if (!hash)
					return undefined;

				hash = $.galleriffic.normalizeHash(hash);
				return allImages[hash];
			},

		// Global function that looks up an image by its hash and displays the image.
		// Returns false when an image is not found for the specified hash.
		// @param {String} hash This is the unique hash value assigned to an image.
			gotoImage: function(hash) {
				var imageData = $.galleriffic.getImage(hash);
				if (!imageData)
					return false;

				var gallery = imageData.gallery;
				gallery.gotoImage(imageData);

				return true;
			},

		// Removes an image from its respective gallery by its hash.
		// Returns false when an image is not found for the specified hash or the
		// specified owner gallery does match the located images gallery.
		// @param {String} hash This is the unique hash value assigned to an image.
		// @param {Object} ownerGallery (Optional) When supplied, the located images
		// gallery is verified to be the same as the specified owning gallery before
		// performing the remove operation.
			removeImageByHash: function(hash, ownerGallery) {
				var imageData = $.galleriffic.getImage(hash);
				if (!imageData)
					return false;

				var gallery = imageData.gallery;
				if (ownerGallery && ownerGallery != gallery)
					return false;

				return gallery.removeImageByIndex(imageData.index);
			}
	};

	var defaults = {
	delay:                     3000,
			numThumbs:                 20,
			preloadAhead:              40, // Set to -1 to preload all images
			enableTopPager:            false,
			enableBottomPager:         true,
			maxPagesToShow:            7,
			imageContainerSel:         '',
			captionContainerSel:       '',
			controlsContainerSel:      '',
			loadingContainerSel:       '',
			renderSSControls:          true,
			renderNavControls:         true,
			playLinkText:              'Play',
			pauseLinkText:             'Pause',
			prevLinkText:              'Previous',
			nextLinkText:              'Next',
			nextPageLinkText:          'Next &rsaquo;',
			prevPageLinkText:          '&lsaquo; Prev',
			enableHistory:             true,
			enableKeyboardNavigation:  true,
			autoStart:                 false,
			syncTransitions:           false,
			defaultTransitionDuration: 1000,
			onSlideChange:             undefined, // accepts a delegate like such: function(prevIndex, nextIndex) { ... }
			onTransitionOut:           undefined, // accepts a delegate like such: function(slide, caption, isSync, callback) { ... }
			onTransitionIn:            undefined, // accepts a delegate like such: function(slide, caption, isSync) { ... }
			onPageTransitionOut:       undefined, // accepts a delegate like such: function(callback) { ... }
			onPageTransitionIn:        undefined, // accepts a delegate like such: function() { ... }
			onImageAdded:              undefined, // accepts a delegate like such: function(imageData, $li) { ... }
			onImageRemoved:            undefined  // accepts a delegate like such: function(imageData, $li) { ... }
	};

	// Primary Galleriffic initialization function that should be called on the thumbnail container.
	$.fn.galleriffic = function(settings) {
		//  Extend Gallery Object
		$.extend(this, {
			// Returns the version of the script
		version: $.galleriffic.version,

			// Current state of the slideshow
				isSlideshowRunning: false,
				slideshowTimeout: undefined,

			// This function is attached to the click event of generated hyperlinks within the gallery
				clickHandler: function(e, link) {
					this.pause();

					if (!this.enableHistory) {
					// The href attribute holds the unique hash for an image
						var hash = $.galleriffic.normalizeHash($(link).attr('href'));
						$.galleriffic.gotoImage(hash);
						e.preventDefault();
					}
				},

			// Appends an image to the end of the set of images.  Argument listItem can be either a jQuery DOM element or arbitrary html.
			// @param listItem Either a jQuery object or a string of html of the list item that is to be added to the gallery.
				appendImage: function(listItem) {
					this.addImage(listItem, false, false);
					return this;
				},

			// Inserts an image into the set of images.  Argument listItem can be either a jQuery DOM element or arbitrary html.
			// @param listItem Either a jQuery object or a string of html of the list item that is to be added to the gallery.
			// @param {Integer} position The index within the gallery where the item shouold be added.
				insertImage: function(listItem, position) {
					this.addImage(listItem, false, true, position);
					return this;
				},

			// Adds an image to the gallery and optionally inserts/appends it to the DOM (thumbExists)
			// @param listItem Either a jQuery object or a string of html of the list item that is to be added to the gallery.
			// @param {Boolean} thumbExists Specifies whether the thumbnail already exists in the DOM or if it needs to be added.
			// @param {Boolean} insert Specifies whether the the image is appended to the end or inserted into the gallery.
			// @param {Integer} position The index within the gallery where the item shouold be added.
				addImage: function(listItem, thumbExists, insert, position) {
					var $li = ( typeof listItem === "string" ) ? $(listItem) : listItem;
					var $aThumb = $li.find('a.thumb');
					var slideUrl = $aThumb.attr('href');
					var title = $aThumb.attr('title');
					var $caption = $li.find('.caption').remove();
					var hash = $aThumb.attr('name');

				// Increment the image counter
					imageCounter++;

				// Autogenerate a hash value if none is present or if it is a duplicate
					if (!hash || allImages[''+hash]) {
						hash = imageCounter;
					}

				// Set position to end when not specified
					if (!insert)
						position = this.data.length;

					var imageData = {
						title:title,
							slideUrl:slideUrl,
							caption:$caption,
							hash:hash,
							gallery:this,
							index:position
					};

				// Add the imageData to this gallery's array of images
					if (insert) {
						this.data.splice(position, 0, imageData);

					// Reset index value on all imageData objects
						this.updateIndices(position);
					}
					else {
						this.data.push(imageData);
					}

					var gallery = this;

				// Add the element to the DOM
					if (!thumbExists) {
					// Update thumbs passing in addition post transition out handler
						this.updateThumbs(function() {
							var $thumbsUl = gallery.find('ul.thumbs');
							if (insert)
								$thumbsUl.children(':eq('+position+')').before($li);
							else
								$thumbsUl.append($li);

							if (gallery.onImageAdded)
								gallery.onImageAdded(imageData, $li);
						});
					}

				// Register the image globally
					allImages[''+hash] = imageData;

				// Setup attributes and click handler
					$aThumb.attr('rel', 'history')
						.attr('href', '#'+hash)
						.removeAttr('name')
						.click(function(e) {
							gallery.clickHandler(e, this);
						});

					return this;
				},

			// Removes an image from the gallery based on its index.
			// Returns false when the index is out of range.
				removeImageByIndex: function(index) {
					if (index < 0 || index >= this.data.length)
						return false;

					var imageData = this.data[index];
					if (!imageData)
						return false;

					this.removeImage(imageData);

					return true;
				},

			// Convenience method that simply calls the global removeImageByHash method.
				removeImageByHash: function(hash) {
					return $.galleriffic.removeImageByHash(hash, this);
				},

			// Removes an image from the gallery.
				removeImage: function(imageData) {
					var index = imageData.index;

				// Remove the image from the gallery data array
					this.data.splice(index, 1);

				// Remove the global registration
					delete allImages[''+imageData.hash];

				// Remove the image's list item from the DOM
					this.updateThumbs(function() {
						var $li = gallery.find('ul.thumbs')
							.children(':eq('+index+')')
							.remove();

						if (gallery.onImageRemoved)
							gallery.onImageRemoved(imageData, $li);
					});

				// Update each image objects index value
					this.updateIndices(index);

					return this;
				},

			// Updates the index values of the each of the images in the gallery after the specified index
				updateIndices: function(startIndex) {
					for (i = startIndex; i < this.data.length; i++) {
						this.data[i].index = i;
					}

					return this;
				},

			// Scraped the thumbnail container for thumbs and adds each to the gallery
				initializeThumbs: function() {
					this.data = [];
					var gallery = this;

					this.find('ul.thumbs > li').each(function(i) {
						gallery.addImage($(this), true, false);
					});

					return this;
				},

				isPreloadComplete: false,

			// Initalizes the image preloader
				preloadInit: function() {
					if (this.preloadAhead == 0) return this;

					this.preloadStartIndex = this.currentImage.index;
					var nextIndex = this.getNextIndex(this.preloadStartIndex);
					return this.preloadRecursive(this.preloadStartIndex, nextIndex);
				},

			// Changes the location in the gallery the preloader should work
			// @param {Integer} index The index of the image where the preloader should restart at.
				preloadRelocate: function(index) {
				// By changing this startIndex, the current preload script will restart
					this.preloadStartIndex = index;
					return this;
				},

			// Recursive function that performs the image preloading
			// @param {Integer} startIndex The index of the first image the current preloader started on.
			// @param {Integer} currentIndex The index of the current image to preload.
				preloadRecursive: function(startIndex, currentIndex) {
				// Check if startIndex has been relocated
					if (startIndex != this.preloadStartIndex) {
						var nextIndex = this.getNextIndex(this.preloadStartIndex);
						return this.preloadRecursive(this.preloadStartIndex, nextIndex);
					}

					var gallery = this;

				// Now check for preloadAhead count
					var preloadCount = currentIndex - startIndex;
					if (preloadCount < 0)
						preloadCount = this.data.length-1-startIndex+currentIndex;
					if (this.preloadAhead >= 0 && preloadCount > this.preloadAhead) {
					// Do this in order to keep checking for relocated start index
						setTimeout(function() { gallery.preloadRecursive(startIndex, currentIndex); }, 500);
						return this;
					}

					var imageData = this.data[currentIndex];
					if (!imageData)
						return this;

				// If already loaded, continue
					if (imageData.image)
						return this.preloadNext(startIndex, currentIndex);

				// Preload the image
					var image = new Image();

					image.onload = function() {
						imageData.image = this;
						gallery.preloadNext(startIndex, currentIndex);
					};

					image.alt = imageData.title;
					image.src = imageData.slideUrl;

					return this;
				},

			// Called by preloadRecursive in order to preload the next image after the previous has loaded.
			// @param {Integer} startIndex The index of the first image the current preloader started on.
			// @param {Integer} currentIndex The index of the current image to preload.
				preloadNext: function(startIndex, currentIndex) {
					var nextIndex = this.getNextIndex(currentIndex);
					if (nextIndex == startIndex) {
						this.isPreloadComplete = true;
					} else {
					// Use setTimeout to free up thread
						var gallery = this;
						setTimeout(function() { gallery.preloadRecursive(startIndex, nextIndex); }, 100);
					}

					return this;
				},

			// Safe way to get the next image index relative to the current image.
			// If the current image is the last, returns 0
				getNextIndex: function(index) {
					var nextIndex = index+1;
					if (nextIndex >= this.data.length)
						nextIndex = 0;
					return nextIndex;
				},

			// Safe way to get the previous image index relative to the current image.
			// If the current image is the first, return the index of the last image in the gallery.
				getPrevIndex: function(index) {
					var prevIndex = index-1;
					if (prevIndex < 0)
						prevIndex = this.data.length-1;
					return prevIndex;
				},

			// Pauses the slideshow
				pause: function() {
					this.isSlideshowRunning = false;
					if (this.slideshowTimeout) {
						clearTimeout(this.slideshowTimeout);
						this.slideshowTimeout = undefined;
					}

					if (this.$controlsContainer) {
						this.$controlsContainer
							.find('div.ss-controls a').removeClass().addClass('play')
							.attr('title', this.playLinkText)
							.attr('href', '#play')
							.html(this.playLinkText);
					}

					return this;
				},

			// Plays the slideshow
				play: function() {
					this.isSlideshowRunning = true;

					if (this.$controlsContainer) {
						this.$controlsContainer
							.find('div.ss-controls a').removeClass().addClass('pause')
							.attr('title', this.pauseLinkText)
							.attr('href', '#pause')
							.html(this.pauseLinkText);
					}

					if (!this.slideshowTimeout) {
						var gallery = this;
						this.slideshowTimeout = setTimeout(function() { gallery.ssAdvance(); }, this.delay);
					}

					return this;
				},

			// Toggles the state of the slideshow (playing/paused)
				toggleSlideshow: function() {
					if (this.isSlideshowRunning)
						this.pause();
					else
						this.play();

					return this;
				},

			// Advances the slideshow to the next image and delegates navigation to the
			// history plugin when history is enabled
			// enableHistory is true
				ssAdvance: function() {
					if (this.isSlideshowRunning)
						this.next(true);

					return this;
				},

			// Advances the gallery to the next image.
			// @param {Boolean} dontPause Specifies whether to pause the slideshow.
			// @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled.
				next: function(dontPause, bypassHistory) {
					this.gotoIndex(this.getNextIndex(this.currentImage.index), dontPause, bypassHistory);
					return this;
				},

			// Navigates to the previous image in the gallery.
			// @param {Boolean} dontPause Specifies whether to pause the slideshow.
			// @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled.
				previous: function(dontPause, bypassHistory) {
					this.gotoIndex(this.getPrevIndex(this.currentImage.index), dontPause, bypassHistory);
					return this;
				},

			// Navigates to the next page in the gallery.
			// @param {Boolean} dontPause Specifies whether to pause the slideshow.
			// @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled.
				nextPage: function(dontPause, bypassHistory) {
					var page = this.getCurrentPage();
					var lastPage = this.getNumPages() - 1;
					if (page < lastPage) {
						var startIndex = page * this.numThumbs;
						var nextPage = startIndex + this.numThumbs;
						this.gotoIndex(nextPage, dontPause, bypassHistory);
					}

					return this;
				},

			// Navigates to the previous page in the gallery.
			// @param {Boolean} dontPause Specifies whether to pause the slideshow.
			// @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled.
				previousPage: function(dontPause, bypassHistory) {
					var page = this.getCurrentPage();
					if (page > 0) {
						var startIndex = page * this.numThumbs;
						var prevPage = startIndex - this.numThumbs;
						this.gotoIndex(prevPage, dontPause, bypassHistory);
					}

					return this;
				},

			// Navigates to the image at the specified index in the gallery
			// @param {Integer} index The index of the image in the gallery to display.
			// @param {Boolean} dontPause Specifies whether to pause the slideshow.
			// @param {Boolean} bypassHistory Specifies whether to delegate navigation to the history plugin when history is enabled.
				gotoIndex: function(index, dontPause, bypassHistory) {
					if (!dontPause)
						this.pause();

					if (index < 0) index = 0;
					else if (index >= this.data.length) index = this.data.length-1;

					var imageData = this.data[index];

					if (!bypassHistory && this.enableHistory)
						$.historyLoad(String(imageData.hash));  // At the moment, historyLoad only accepts string arguments
					else
						this.gotoImage(imageData);

					return this;
				},

			// This function is garaunteed to be called anytime a gallery slide changes.
			// @param {Object} imageData An object holding the image metadata of the image to navigate to.
				gotoImage: function(imageData) {
					var index = imageData.index;

					if (this.onSlideChange)
						this.onSlideChange(this.currentImage.index, index);

					this.currentImage = imageData;
					this.preloadRelocate(index);

					this.refresh();

					return this;
				},

			// Returns the default transition duration value.  The value is halved when not
			// performing a synchronized transition.
			// @param {Boolean} isSync Specifies whether the transitions are synchronized.
				getDefaultTransitionDuration: function(isSync) {
					if (isSync)
						return this.defaultTransitionDuration;
					return this.defaultTransitionDuration / 2;
				},

			// Rebuilds the slideshow image and controls and performs transitions
				refresh: function() {
					var imageData = this.currentImage;
					if (!imageData)
						return this;

					var index = imageData.index;

				// Update Controls
					if (this.$controlsContainer) {
						this.$controlsContainer
							.find('div.nav-controls a.prev').attr('href', '#'+this.data[this.getPrevIndex(index)].hash).end()
							.find('div.nav-controls a.next').attr('href', '#'+this.data[this.getNextIndex(index)].hash);
					}

					var previousSlide = this.$imageContainer.find('span.current').addClass('previous').removeClass('current');
					var previousCaption = 0;

					if (this.$captionContainer) {
						previousCaption = this.$captionContainer.find('span.current').addClass('previous').removeClass('current');
					}

				// Perform transitions simultaneously if syncTransitions is true and the next image is already preloaded
					var isSync = this.syncTransitions && imageData.image;

				// Flag we are transitioning
					var isTransitioning = true;
					var gallery = this;

					var transitionOutCallback = function() {
					// Flag that the transition has completed
						isTransitioning = false;

					// Remove the old slide
						previousSlide.remove();

					// Remove old caption
						if (previousCaption)
							previousCaption.remove();

						if (!isSync) {
							if (imageData.image && imageData.hash == gallery.data[gallery.currentImage.index].hash) {
								gallery.buildImage(imageData, isSync);
							} else {
							// Show loading container
								if (gallery.$loadingContainer) {
									gallery.$loadingContainer.show();
								}
							}
						}
					};

					if (previousSlide.length == 0) {
					// For the first slide, the previous slide will be empty, so we will call the callback immediately
						transitionOutCallback();
					} else {
						if (this.onTransitionOut) {
							this.onTransitionOut(previousSlide, previousCaption, isSync, transitionOutCallback);
						} else {
							previousSlide.fadeTo(this.getDefaultTransitionDuration(isSync), 0.0, transitionOutCallback);
							if (previousCaption)
								previousCaption.fadeTo(this.getDefaultTransitionDuration(isSync), 0.0);
						}
					}

				// Go ahead and begin transitioning in of next image
					if (isSync)
						this.buildImage(imageData, isSync);

					if (!imageData.image) {
						var image = new Image();

					// Wire up mainImage onload event
						image.onload = function() {
							imageData.image = this;

						// Only build image if the out transition has completed and we are still on the same image hash
							if (!isTransitioning && imageData.hash == gallery.data[gallery.currentImage.index].hash) {
								gallery.buildImage(imageData, isSync);
							}
						};

					// set alt and src
						image.alt = imageData.title;
						image.src = imageData.slideUrl;
					}

				// This causes the preloader (if still running) to relocate out from the currentIndex
					this.relocatePreload = true;

					return this.syncThumbs();
				},

			// Called by the refresh method after the previous image has been transitioned out or at the same time
			// as the out transition when performing a synchronous transition.
			// @param {Object} imageData An object holding the image metadata of the image to build.
			// @param {Boolean} isSync Specifies whether the transitions are synchronized.
				buildImage: function(imageData, isSync) {
					var gallery = this;
					var nextIndex = this.getNextIndex(imageData.index);

				// Construct new hidden span for the image
// 				var newSlide = this.$imageContainer
// 					.append('<span class="image-wrapper current"><a class="advance-link" rel="history" href="#'+this.data[nextIndex].hash+'" title="'+imageData.title+'">&nbsp;</a></span>')
// 					.find('span.current').css('opacity', '0');
//
// 				newSlide.find('a')
// 					.append(imageData.image)
// 					.click(function(e) {
// 						gallery.clickHandler(e, this);
// 					});
					var newSlide = this.$imageContainer
						.append('<span class="image-wrapper current" style="width:'+iw+'px;height:'+ih+';"></span>')
						.find('span.current').css('opacity', '0');

					newSlide
						.append(imageData.image)
						.find('img').css('width',iw).css('height',ih)
						.click(function(e) {
							gallery.clickHandler(e, this);
						});

					var newCaption = 0;
					if (this.$captionContainer) {
					// Construct new hidden caption for the image
						newCaption = this.$captionContainer
							.append('<span class="image-caption current"></span>')
							.find('span.current').css('opacity', '0')
							.append(imageData.caption);
					}

				// Hide the loading conatiner
					if (this.$loadingContainer) {
						this.$loadingContainer.hide();
					}

				// Transition in the new image
					if (this.onTransitionIn) {
						this.onTransitionIn(newSlide, newCaption, isSync);
					} else {
						newSlide.fadeTo(this.getDefaultTransitionDuration(isSync), 1.0);
						if (newCaption)
							newCaption.fadeTo(this.getDefaultTransitionDuration(isSync), 1.0);
					}

					if (this.isSlideshowRunning) {
						if (this.slideshowTimeout)
							clearTimeout(this.slideshowTimeout);

						this.slideshowTimeout = setTimeout(function() { gallery.ssAdvance(); }, this.delay);
					}

					return this;
				},

			// Returns the current page index that should be shown for the currentImage
				getCurrentPage: function() {
					return Math.floor(this.currentImage.index / this.numThumbs);
				},

			// Applies the selected class to the current image's corresponding thumbnail.
			// Also checks if the current page has changed and updates the displayed page of thumbnails if necessary.
				syncThumbs: function() {
					var page = this.getCurrentPage();
					if (page != this.displayedPage)
						this.updateThumbs();

				// Remove existing selected class and add selected class to new thumb
					var $thumbs = this.find('ul.thumbs').children();
					$thumbs.filter('.selected').removeClass('selected');
					$thumbs.eq(this.currentImage.index).addClass('selected');

					return this;
				},

			// Performs transitions on the thumbnails container and updates the set of
			// thumbnails that are to be displayed and the navigation controls.
			// @param {Delegate} postTransitionOutHandler An optional delegate that is called after
			// the thumbnails container has transitioned out and before the thumbnails are rebuilt.
				updateThumbs: function(postTransitionOutHandler) {
					var gallery = this;
					var transitionOutCallback = function() {
					// Call the Post-transition Out Handler
						if (postTransitionOutHandler)
							postTransitionOutHandler();

						gallery.rebuildThumbs();

					// Transition In the thumbsContainer
						if (gallery.onPageTransitionIn)
							gallery.onPageTransitionIn();
						else
							gallery.show();
					};

				// Transition Out the thumbsContainer
					if (this.onPageTransitionOut) {
						this.onPageTransitionOut(transitionOutCallback);
					} else {
						this.hide();
						transitionOutCallback();
					}

					return this;
				},

			// Updates the set of thumbnails that are to be displayed and the navigation controls.
				rebuildThumbs: function() {
					var needsPagination = this.data.length > this.numThumbs;

				// Rebuild top pager
					if (this.enableTopPager) {
						var $topPager = this.find('div.top');
						if ($topPager.length == 0)
							$topPager = this.prepend('<div class="top pagination"></div>').find('div.top');
						else
							$topPager.empty();

						if (needsPagination)
							this.buildPager($topPager);
					}

				// Rebuild bottom pager
					if (this.enableBottomPager) {
						var $bottomPager = this.find('div.bottom');
						if ($bottomPager.length == 0)
							$bottomPager = this.append('<div class="bottom pagination"></div>').find('div.bottom');
						else
							$bottomPager.empty();

						if (needsPagination)
							this.buildPager($bottomPager);
					}

					var page = this.getCurrentPage();
					var startIndex = page*this.numThumbs;
					var stopIndex = startIndex+this.numThumbs-1;
					if (stopIndex >= this.data.length)
						stopIndex = this.data.length-1;

				// Show/Hide thumbs
					var $thumbsUl = this.find('ul.thumbs');
// 				current_page = $('.menu .active').attr('id');

					current_page = $('.menu ul ul .active'); // portfolio child

					if (current_page.length == 0) {
						current_page = $('.menu ul .active');
					}
// 				alert('context='+current_page.context);
					var dmp = '';
					for(var item in current_page.attr) {dmp+=' item='+item+'='+typeof(item);}
// 				alert(dmp);
				//alert('current_page='+current_page+': name='+current_page.name);
					current_grandparent = current_page.parent().parent().attr('id');
// 				alert('current_grandparent='+current_grandparent);
					current_page = current_page.attr('id');

					menu_up_height = $('div.menu').height()+th+10+'px';
					menu_down_height = $('div.menu').height()+'px';
					if (current_grandparent == 'mi_51' || current_page == 'mi_52' || current_page == 'mi_53') {
						$('#body-bottom').css('height', menu_up_height);
					}
					else {
						$('#body-bottom').css('height', menu_down_height);
					}
					var menu_mouseout = function(event) {
						var target = event.relatedTarget;
						if (target && target.nodeName == 'DIV') {
							$('#body-bottom').css('height', menu_down_height);
						}
					};
					var menu_mouseover = function(event) {
						var target = event.relatedTarget;
						if (target && target.nodeName == 'DIV') {
							$('#body-bottom').css('height', menu_up_height);
						}
					};
// 				alert('current_page[0]='+current_page[0]);
					if (current_page == 'mi_55' || current_page == 'mi_56' || current_page == 'mi_57' || current_page == 'mi_58' || current_page == 'mi_60' || current_page == 'mi_53') {
					// portfolio
						$('div.menu').bind('mouseover', menu_mouseover);
						$('div.menu').bind('mouseout', menu_mouseout);
						$().mousemove(function(e){
							var menu_left = parseInt($('#masthead').css('left'))+235-3;
							var menu_right = menu_left+iw;

							if (e.pageX < menu_left || e.pageX > menu_right) {
								$('#body-bottom').css('height', menu_down_height);
							}
							else {
								var menu_top = $('#body-bottom').position().top;
								if (e.pageY > menu_top) {
									$('#body-bottom').css('height', menu_up_height);
								}
							}
						});
					}
					else {
					}
					$('ul#navigation-container').height(th+'px');
					$thumbsUl.css('padding-left', 0);
					$thumbsUl.find('li').each(function(i) {
						var $li = $(this);
						if (i >= startIndex && i <= stopIndex) {
							$li.show().height(th+'px').width(tw+'px').find('img').height(th+'px').width(tw+'px');
						} else {
							$li.hide();
						}
					});

					this.displayedPage = page;

				// Remove the noscript class from the thumbs container ul
					$thumbsUl.removeClass('noscript');

					return this;
				},

			// Returns the total number of pages required to display all the thumbnails.
				getNumPages: function() {
					return Math.ceil(this.data.length/this.numThumbs);
				},

			// Rebuilds the pager control in the specified matched element.
			// @param {jQuery} pager A jQuery element set matching the particular pager to be rebuilt.
				buildPager: function(pager) {
					var gallery = this;
					var numPages = this.getNumPages();
					var page = this.getCurrentPage();
					var startIndex = page * this.numThumbs;
					var pagesRemaining = this.maxPagesToShow - 1;

					var pageNum = page - Math.floor((this.maxPagesToShow - 1) / 2) + 1;
					if (pageNum > 0) {
						var remainingPageCount = numPages - pageNum;
						if (remainingPageCount < pagesRemaining) {
							pageNum = pageNum - (pagesRemaining - remainingPageCount);
						}
					}

					if (pageNum < 0) {
						pageNum = 0;
					}

				// Prev Page Link
					if (page > 0) {
						var prevPage = startIndex - this.numThumbs;
						pager.append('<a rel="history" href="#'+this.data[prevPage].hash+'" title="'+this.prevPageLinkText+'">'+this.prevPageLinkText+'</a>');
					}

				// Create First Page link if needed
					if (pageNum > 0) {
						this.buildPageLink(pager, 0, numPages);
						if (pageNum > 1)
							pager.append('<span class="ellipsis">&hellip;</span>');

						pagesRemaining--;
					}

				// Page Index Links
					while (pagesRemaining > 0) {
						this.buildPageLink(pager, pageNum, numPages);
						pagesRemaining--;
						pageNum++;
					}

				// Create Last Page link if needed
					if (pageNum < numPages) {
						var lastPageNum = numPages - 1;
						if (pageNum < lastPageNum)
							pager.append('<span class="ellipsis">&hellip;</span>');

						this.buildPageLink(pager, lastPageNum, numPages);
					}

				// Next Page Link
					var nextPage = startIndex + this.numThumbs;
					if (nextPage < this.data.length) {
						pager.append('<a rel="history" href="#'+this.data[nextPage].hash+'" title="'+this.nextPageLinkText+'">'+this.nextPageLinkText+'</a>');
					}

					pager.find('a').click(function(e) {
						gallery.clickHandler(e, this);
					});

					return this;
				},

			// Builds a single page link within a pager.  This function is called by buildPager
			// @param {jQuery} pager A jQuery element set matching the particular pager to be rebuilt.
			// @param {Integer} pageNum The page number of the page link to build.
			// @param {Integer} numPages The total number of pages required to display all thumbnails.
				buildPageLink: function(pager, pageNum, numPages) {
					var pageLabel = pageNum + 1;
					var currentPage = this.getCurrentPage();
					if (pageNum == currentPage)
						pager.append('<span class="current">'+pageLabel+'</span>');
					else if (pageNum < numPages) {
						var imageIndex = pageNum*this.numThumbs;
						pager.append('<a rel="history" href="#'+this.data[imageIndex].hash+'" title="'+pageLabel+'">'+pageLabel+'</a>');
					}

					return this;
				}
		});

		// Now initialize the gallery
		$.extend(this, defaults, settings);
// 		this.enableHistory = true;
		// Verify the history plugin is available

		if (this.enableHistory && !$.historyInit)
			this.enableHistory = false;

		// Select containers
		if (this.imageContainerSel) this.$imageContainer = $(this.imageContainerSel);
		if (this.captionContainerSel) this.$captionContainer = $(this.captionContainerSel);
		if (this.loadingContainerSel) this.$loadingContainer = $(this.loadingContainerSel);

		// Initialize the thumbails
		this.initializeThumbs();

		if (this.maxPagesToShow < 3)
			this.maxPagesToShow = 3;

		this.displayedPage = -1;
		this.currentImage = this.data[0];
		var gallery = this;

		// Hide the loadingContainer
		if (this.$loadingContainer)
			this.$loadingContainer.hide();

		// Setup controls
		if (this.controlsContainerSel) {
			this.$controlsContainer = $(this.controlsContainerSel).empty();

			if (this.renderSSControls) {
				if (this.autoStart) {
					this.$controlsContainer
						.append('<div class="ss-controls"><a href="#pause" class="pause" title="'+this.pauseLinkText+'">'+this.pauseLinkText+'</a></div>');
				} else {
					this.$controlsContainer
						.append('<div class="ss-controls"><a href="#play" class="play" title="'+this.playLinkText+'">'+this.playLinkText+'</a></div>');
				}

				this.$controlsContainer.find('div.ss-controls a')
					.click(function(e) {
						gallery.toggleSlideshow();
						e.preventDefault();
						return false;
					});
			}

			if (this.renderNavControls) {
				this.$controlsContainer
					.append('<div class="nav-controls w-'+dr+' h-'+dr+'"><a class="prev" rel="history" title="'+this.prevLinkText+'">'+this.prevLinkText+'</a><a class="next" rel="history" title="'+this.nextLinkText+'">'+this.nextLinkText+'</a></div>')
					.find('div.nav-controls a')
					.click(function(e) {
						gallery.clickHandler(e, this);
					});
			}
		}

		var initFirstImage = !this.enableHistory || !location.hash;
		if (this.enableHistory && location.hash) {
			var hash = $.galleriffic.normalizeHash(location.hash);
			var imageData = allImages[hash];
			if (!imageData)
				initFirstImage = true;
		}

		// Setup gallery to show the first image
		if (initFirstImage)
			this.gotoIndex(0, false, true);

		// Setup Keyboard Navigation
		if (this.enableKeyboardNavigation) {
			$(document).keydown(function(e) {
				var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
				switch(key) {
				case 32: // space
						gallery.next();
					e.preventDefault();
					break;
				case 33: // Page Up
						gallery.previousPage();
					e.preventDefault();
					break;
				case 34: // Page Down
						gallery.nextPage();
					e.preventDefault();
					break;
				case 35: // End
						gallery.gotoIndex(gallery.data.length-1);
					e.preventDefault();
					break;
				case 36: // Home
						gallery.gotoIndex(0);
					e.preventDefault();
					break;
				case 37: // left arrow
						gallery.previous();
					e.preventDefault();
					break;
				case 39: // right arrow
						gallery.next();
					e.preventDefault();
					break;
				}
			});
		}

		// Auto start the slideshow
		if (this.autoStart)
			this.play();

		// Kickoff Image Preloader after 1 second
		setTimeout(function() { gallery.preloadInit(); }, 1000);

		return this;
	};
})(jQuery);

