if(detectBrowser.modernBrowser()){

// Image Gallery is loaded by both the "full screen" image 
// gallery page and the normal image gallery page

var currentIndex=0;
var ImageGallery = Class.create();
ImageGallery.prototype = {
	initialize:function(){
		
		this.container = $('image_gallery');
		if(!this.container) return;
		this.imageStackContainer = $('image_stack');
		this.imageContainer = $('gallery_image_area');
		this.captionContainer = $('caption_region');
		this.downloadContainer = $('download_image_box');
		this.toolbarContainer = $('gallery_toolbar');
		this.gridContainer = $('gallery_thumbgrid');
		this.gridContainerClose = $('gallery_thumbgrid_close');
		this.outsideCaptionContainer = $$('.image_gallery_fullscreen_outsidecaption')[0];
		
		
		this.imageSet = new ImageSet(this.container);
		
		//this.previousRange = this.currentRange; = this.imageSet.getFirstRange();
		this.previousRange = this.currentRange; 
		this.currentRange = this.imageSet.getFirstRange();
		this.endLabel = 0;
		this.imageIndex = 0;

		// pixel widths for stack of image ranges
		this.setStackSizes = { 'hiddenSize':67, 'openSize':414 };
		// pixel widths for image stack
		this.rangeStackSizes = { 'hiddenSize':27, 'openSize':120 };
		// delay in milliseconds that it takes the stack to respond
		this.responseDelay = 100;

		// Possible display modes : normal, fullscreen. Possible states: normal, grid
		this.displayMode = ($A(this.container.classNames()).include("image_gallery_fullscreen"))?"fullscreen":"normal";
		this.stackedDecks = [];
		
		this.drawComponents();
		currentIndex=this.currentRange.start;
		
	},

	// return a stack of all sets
	getSetsStack:function(){
		var ul = new Element("ul");
		this.imageSet.each(function(dataset,i){
			// create deck panel with another stack of images inside of it
			var li = new Element("li",{'className':'setstackitem '+((i==0)?"active":"inactive")});
			var rangeStackUl = this.getRangeStack(dataset['range']);
			//this.imageStackContainer.appendChild(rangeStackUl);
			this.stackedDecks.push({
				'deck':(new StackedDeck(rangeStackUl.getElementsBySelector("li"),rangeStackUl,{'horizontal':true})),
				'range':dataset['range'],
				'deckIndex':i
			});
			if(i!=0){
				var rangetab_end = li.appendChild(new Element('div',{'className':'rangetab_end'}));
			}
			li.appendChild(new Element("span",{'className':'rangetitle'}).update(dataset['range']['start']+"-"+dataset['range']['end']));
			li.appendChild(rangeStackUl);
			ul.appendChild(li);
		}.bind(this));
		
		// add another panel at the end to 'cap' the set.
		var setsEndCap = new Element('li',{'className':'setstackitem inactive end_cap'});
		var endCaprangetab_end = setsEndCap.appendChild(new Element('div',{'className':'rangetab_end'}));
		setsEndCap.appendChild(new Element('span',{'className':'rangetitle'}).update(' '));

		
		[this.setStackSizes['hiddenSize'], this.setStackSizes['openSize'], this.responseDelay, "sideways", "imageset"].each(function(className){
			ul.addClassName(className);
		});
		return ul;
	},

	// create a stack of images for a given range
	getRangeStack:function(rangeToGet){
		var ul = new Element("ul");
		var imageSet = this.imageSet.getRange(rangeToGet);
		imageSet['images'].each(function(imageItem,i){
			if(imageItem['placeholder']==true){
				// do nothing.
			} else {
				// create deck panel with image and index inside of it
				var li = new Element("li",{'className':'stackitem '+((i==0)?"active":"inactive")});
				var img = li.appendChild(new Element("img",{'src':imageItem.versions.thumbnail_small,'alt':'Click here to view gallery image','title':'Click here to view gallery image'}));
				var span = li.appendChild(new Element("span",{}).update(rangeToGet['start']+i));
				// attach click handler to image
				Event.observe(li,'click',function(){
					//console.debug("Click detected in img");
					this.goToRangeAndImage(rangeToGet,i);
				}.bind(this));
				ul.appendChild(li);
			}
		}.bind(this));
		[this.rangeStackSizes['hiddenSize'], this.rangeStackSizes['openSize'], this.responseDelay, "sideways", "imagerange"].each(function(className){
			ul.addClassName(className);
		});
		return ul;
	},

	
	moveToImage:function(newImageIndex){
		var newRange = this.currentRange;
		if(newImageIndex<0 || newImageIndex>9) {
			newRange = (newImageIndex<0)?(this.imageSet.getRangeBefore(this.currentRange)):(this.imageSet.getRangeAfter(this.currentRange));
			if(newRange){ // if there is a previous range, go to it
				newImageIndex = (newImageIndex<0)?9:0;
			} else {
				newImageIndex = this.imageIndex;
				newRange = this.currentRange;
			}
		}
		this.goToRangeAndImage(newRange,newImageIndex);
		//this.getCurrentImageItem();
	},


	// Draw deck and refresh gallery UI for the first time.
	drawComponents:function(){ 
		this.hideThumbGrid();
		Event.observe(this.toolbarContainer.getElementsBySelector('#btn_allthumbnails')[0],'click',function(ev){
			ev.stop();
			this.showThumbGrid();
			return false;
		}.bind(this));
		
		if(this.displayMode=="normal"){
			var setsStackUl = this.imageStackContainer.appendChild(this.getSetsStack());
			this.setStack = new StackedDeck(setsStackUl.getElementsBySelector("li.setstackitem"),setsStackUl,{'horizontal':true});
			var imagesetLeft = this.imageStackContainer.appendChild(new Element("div",{'className':'imageset_left'}));
			var imagesetRight = this.imageStackContainer.appendChild(new Element("div",{'className':'imageset_right'}));
			
			Event.observe(imagesetLeft,'click',function(){
			this.subDiv = $('sub');			
			if(masterArrayBlockCurrentIndex >  0)
			 {
				masterArrayBlockCurrentIndex--;
				 if(this.subDiv)
				 {
					this.subDiv .innerHTML='';
					document.getElementById("gallery_image_area").innerHTML='';
					document.getElementById("download_image_box").innerHTML='';
					document.getElementById("image_stack").innerHTML='';
					this.subDiv.innerHTML=masterArrayBlock[masterArrayBlockCurrentIndex];
				}
				 new ImageGallery();
			}
			}.bind(this));
			
			Event.observe(imagesetRight,'click',function(){
			this.subDiv = $('sub');			
			if( (masterArrayBlockCurrentIndex <  10 ) && ( (masterArrayBlockCurrentIndex+1) < masterArrayBlock.length ))
			 {
					 masterArrayBlockCurrentIndex++;
					 if(this.subDiv)
					 {
						 this.subDiv.innerHTML='';
						 document.getElementById("gallery_image_area").innerHTML='';
						 document.getElementById("download_image_box").innerHTML='';
						 document.getElementById("image_stack").innerHTML='';
						 
						 this.subDiv.innerHTML=masterArrayBlock[masterArrayBlockCurrentIndex];
					}
				
					 new ImageGallery();
					 
				
			 }
			}.bind(this));
		}
		// update onscreen elements
		this.refresh();
		// left and right (previous/next) image navigation
		if(this.displayMode == 'normal') {
			var previousImageButton = this.imageContainer.appendChild(new Element("div",{'className':'btn_image_prev'}));
			var nextImageButton = this.imageContainer.appendChild(new Element("div",{'className':'btn_image_next'}));
			
			
			Event.observe(previousImageButton,'click',function(){this.moveToImage(this.imageIndex - 1); }.bind(this));
			Event.observe(nextImageButton,'click',function(){ this.moveToImage(this.imageIndex + 1); }.bind(this));
			
		}else {
			var previousImageButton = this.imageContainer.appendChild(new Element("div",{'className':'btn_image_prev'}).insert(new Element("div",{'className':'btn_arrow_prev'})));
			var nextImageButton = this.imageContainer.appendChild(new Element("div",{'className':'btn_image_next'}).insert(new Element("div",{'className':'btn_arrow_next'})));
			
			Event.observe(previousImageButton,'click',function(){ this.moveToImage(this.imageIndex - 1); }.bind(this));
			Event.observe(nextImageButton,'click',function(){ this.moveToImage(this.imageIndex + 1); }.bind(this));
			
			var hideNav = this.imageContainer;
			var prevNav = this.imageContainer.getElementsBySelector("div.btn_image_prev")[0];
			var nextNav = this.imageContainer.getElementsBySelector("div.btn_image_next")[0];
		
	
		}
		
	},

	getCurrentImageItem:function(){
	
	var rangeObj = this.currentRange;
	var absImageIndex = this.imageIndex + 1;

	var imagePositionInListOfAllImages =  (rangeObj.start - 1) + this.imageIndex;
	var eachImage = new Array();
	var xmlPath = '';var htmlPath='';
	
	for(var i=0;i<listOfImages.length;i++)
	{
		eachImage = new Array();
		eachImage = listOfImages[i];

		if(imagePositionInListOfAllImages == i)
		{
			xmlPath = eachImage.detailedXMLPath;
			htmlPath = eachImage.detailedHTMLPath;
		}
	}
		
	var detailAssetURL = xmlPath;
	var retVal = false;
	 /* Inner Ajax */
	 
	 document.getElementById('btn_fullscreen').href=htmlPath;
	 
	new Ajax.Request(detailAssetURL,	
	  {
		 asynchronous:false,
	    method:'get',
	    onSuccess: function(transport,myIndex){		
		  
		   retVal = processDetailedRSS(transport.responseXML);
		    
		    
			    this.imageContainer = $('gallery_image_area');
	    },
	    onFailure: function(){ 
			//alert('Error Retrieving Source File ...');
			}
	   
	  });	  
	/* Inner Ajax */
	
	if(retVal == true)
	
	{
		var prevNav = this.imageContainer.getElementsBySelector("div.btn_image_prev")[0];
		var nextNav = this.imageContainer.getElementsBySelector("div.btn_image_next")[0];
				
		if(prevNav == null || prevNav == 'undefined') {
					
					
			prevNav = this.imageContainer.appendChild(new Element("div",{'className':'btn_image_prev'}));
			nextNav = this.imageContainer.appendChild(new Element("div",{'className':'btn_image_next'}));				
		}	
		Event.observe(prevNav,'click',function(){ this.moveToImage(this.imageIndex - 1); }.bind(this));
		Event.observe(nextNav,'click',function(){;this.moveToImage(this.imageIndex+ 1); }.bind(this));					
		
		if(this.displayMode=="normal" && typeof(this.captionScrollBar)=='undefined'){
			//do nothing - this scenario has already been handled
		}
		else
		{	
			this.captionScrollBar = new ScrollRegion(this.captionContainer.getElementsBySelector("div")[0]);
		}
		
	}
	else
	{
		// already handled
	}
	return this.imageSet.getRange(this.currentRange)['images'][this.imageIndex];
		
		
	},

	// fill in onscreen stuff including image, caption, title, download links
	// if replacementImageItem is not an image from some image set (i.e. undefined), fetch the "current" image and use that for refresh.
	refresh:function(replacementImageItem){
		if(typeof(replacementImageItem)=='undefined') replacementImageItem = this.getCurrentImageItem();

		if(this.displayMode=="normal"){
			// Slide outer slider: Go to the current range
			this.setStack.slideToIndex(this.imageSet.getRangeIndex(this.currentRange));

			// Slide slider: find inner slider, slide to it. NB: assumes that the slider exists!
			var innerStack = this.stackedDecks.find(function(slider){
				var rangeOfImage = this.imageSet.findRangeByImage(replacementImageItem);
				return ImageSet.prototype.compareRange(rangeOfImage,slider.range);
			}.bind(this));
			innerStack.deck.slideToIndex(this.imageIndex);
		}

		// update caption and title
		/*this.captionContainer.getElementsBySelector("p")[0].update(replacementImageItem['caption']);
		this.captionContainer.getElementsBySelector("h3")[0].update(replacementImageItem['title']);*/
		if(this.displayMode=="normal" && typeof(this.captionScrollBar)=='undefined'){
			
			this.captionScrollBar = new ScrollRegion(this.captionContainer.getElementsBySelector("div")[0]);
		}
		
		// update download links: remove current ones, add new ones
		/*this.downloadContainer.getElementsBySelector("span").invoke("remove");*/

		// update list of downloadable images
		$H(replacementImageItem['versions']).keys().reject(function(k){
			return k=='medium' || k=='thumbnail_large' || k=='thumbnail_small' || k=='fullscreen';
		}).each(function(key){
			
			// convert 1111x1111 into 1111 x 1111 and "Full_Size" into Full Size
			var displayedKey = key.split("_").join(" ").split("x").join(" x ");
			var downloadSpan = new Element("span");
			var downloadHref = new Element("a", { 'href':replacementImageItem['versions'][key]} ).update( displayedKey );
			downloadSpan.update( downloadHref );
			var downloadLink = new Insertion.Top(downloadSpan, "&rsaquo; ");
			/*this.downloadContainer.appendChild(downloadLink);*/

		}.bind(this));

		// Update image: create new image, remove old one, append new one to DOM
		this.previousRange = this.currentRange;
		
	},

	hideThumbGrid:function(){
		// TODO use the references to fetched elements from initialize() instead
		this.subDiv = $('sub');
		
		if(!this.subDiv)
		{
			var formElement = $('subDivForm');
			var sub = new Element("div", {'id': "sub"});
			
			formElement.insert(sub);
		}
		
		this.gridContainer.hide();
		if(this.displayMode=='fullscreen'){
			this.container.removeClassName("image_gallery_fullscreen_short");
			this.toolbarContainer.show();
			this.downloadContainer.show();
			this.captionContainer.show();
			this.imageContainer.show();
			this.outsideCaptionContainer.show();
		}
	},

	showThumbGrid:function(){
		//alert('Inside showThumbGrid');
		this.gridContainer.show();
		this.gridContainerClose.style.display="block";
		this.subDiv = $('sub');
		if(this.subDiv)	{this.subDiv.remove();}
		if(this.displayMode=='fullscreen'){
			this.container.addClassName("image_gallery_fullscreen_short");
			this.toolbarContainer.hide();
			this.downloadContainer.hide();
			this.captionContainer.hide();
			this.imageContainer.hide();
			this.outsideCaptionContainer.hide();
		}
		
		// clean out ranges
		this.imageSet.getRange(this.currentRange)['images'][this.imageIndex];
		var browserName  = navigator.appName;
		var rangesContainer = this.gridContainer.getElementsBySelector("#gallery_thumbgrid_ranges")[0];
		
		
		if( !((rangesContainer.childNodes.length == 2) && (this.currentRange.start == 1)  && (browserName == 'Microsoft Internet Explorer' )) || ((browserName == 'Microsoft Internet Explorer' ) && currentIndex==1) )
		{
			/*if(this.currentRange.start  < this.endLabel)
			{*/
	            
				if(browserName == 'Microsoft Internet Explorer')
			     { 
					var secondIndex = 0;
                    secondIndex= eval(this.currentRange.start - 20);
					   if(this.currentRange.start == currentIndex || secondIndex==currentIndex) {
				
								while(rangesContainer.childNodes.length > 0)
								{
									rangesContainer.removeChild(rangesContainer.firstChild);
								}
								// clean out grid
								var grid = this.gridContainer.getElementsBySelector("#gallery_thumbgrid_grid")[0];
								while(grid.childNodes.length > 0)
								{	
									grid.removeChild(grid.firstChild);
								}
								// redraw ranges
								this.imageSet.allRangesInExtent().inGroupsOf(2).each(function(rangeGroup){
									var inRange = false;
									/*alert("rg0 start =" +rangeGroup[0].start + "rg0 end = "+rangeGroup[0].end +" and currentRange  = "+this.currentRange.start);*/
									if(ImageSet.prototype.compareRange(rangeGroup[0],this.currentRange) || ImageSet.prototype.compareRange(rangeGroup[1],this.currentRange)) {
										inRange = true;				
									}
									var rangeLabel = rangeGroup[0]['start'] + " - " + ((rangeGroup[1]!=null)?rangeGroup[1]['end']:rangeGroup[0]['end']);
									this.endLabel = rangeGroup[1]['end'];
									
									if(inRange)
									{
										while( (rangesContainer.childNodes.length -1) > 0)
										{
											rangesContainer.removeChild(rangesContainer.firstChild);
										}
										var rangeSpan = rangesContainer.appendChild(new Element("span",{})).update(rangeLabel);
									} 
									else 
									{
										while( (rangesContainer.childNodes.length -1) > 0)
										{
											rangesContainer.removeChild(rangesContainer.firstChild);
										}
										var rangeLink = rangesContainer.appendChild(new Element("a",{'href':'#'})).update(rangeLabel);
														
										Event.observe(rangeLink,'click',function(ev){
											this.currentRange = rangeGroup[0];
											this.imageIndex = 0;
											this.showThumbGrid();
											ev.stop();
											return false;
										}.bind(this));
										
									}
									
								}.bind(this));
								//alert('Redraw ranges finished');
								var closeBtn = this.gridContainer.getElementsBySelector('#gallery_thumbgrid_close a')[0];
								if(this.observedCloseBtn!=true){
									Event.observe(closeBtn,'click',function(ev){
										this.hideThumbGrid();
										ev.stop();
										return false;
									}.bind(this));
									this.observedCloseBtn = true;
								}
						
								// find the range pair that the current range is inside of, then render them both.
								var rangePair = this.imageSet.allRangesInExtent().inGroupsOf(2).find(function(rangeGroup){
									if(ImageSet.prototype.compareRange(rangeGroup[0],this.currentRange) || ImageSet.prototype.compareRange(rangeGroup[1],this.currentRange)) return true;
									//return false;
								}.bind(this));
						
								var range1 = this.imageSet.getRange(rangePair[0]);
								var range2 = this.imageSet.getRange(rangePair[1]);
								var combinedSet = (range2)?range1['images'].concat(range2['images']):range1['images'];
								combinedSet.each(function(imageItem,i){
									// create deck panel with image and index inside of it
									var imgContainer = new Element("div",{'className':'griditem g'+i});
									// ignore placeholder images
									if(imageItem['placeholder']!=true){
										var img = imgContainer.appendChild(new Element("img",{'src':(this.displayMode=="normal")?imageItem.versions.thumbnail_small:imageItem.versions.thumbnail_large,'alt':'Click here to view gallery image','title':'Click here to view gallery image'}));
										Event.observe(img,'click',function(ev){ // Image's click handler hides the grid and navigates to the image.
											this.hideThumbGrid();
											if(i>9) this.goToRangeAndImage(rangePair[1],i - 10);
											else this.goToRangeAndImage(rangePair[0],i);
											ev.stop();
											return false;
										}.bind(this));
									} else {
										var img = imgContainer.appendChild(new Element("div",{'className':'placeholder_thumbnail'}).update(" "));
									}
									
									grid.appendChild(imgContainer);
								}.bind(this));
							}

			   	   } else {
										while(rangesContainer.childNodes.length > 0)
										{
											rangesContainer.removeChild(rangesContainer.firstChild);
										}
										// clean out grid
										var grid = this.gridContainer.getElementsBySelector("#gallery_thumbgrid_grid")[0];
										while(grid.childNodes.length > 0)
										{	
											grid.removeChild(grid.firstChild);
										}
										// redraw ranges
										this.imageSet.allRangesInExtent().inGroupsOf(2).each(function(rangeGroup){
											var inRange = false;
											/*alert("rg0 start =" +rangeGroup[0].start + "rg0 end = "+rangeGroup[0].end +" and currentRange  = "+this.currentRange.start);*/
											if(ImageSet.prototype.compareRange(rangeGroup[0],this.currentRange) || ImageSet.prototype.compareRange(rangeGroup[1],this.currentRange)) {
												inRange = true;				
											}
											var rangeLabel = rangeGroup[0]['start'] + " - " + ((rangeGroup[1]!=null)?rangeGroup[1]['end']:rangeGroup[0]['end']);
											this.endLabel = rangeGroup[1]['end'];
											
											if(inRange)
											{
												while( (rangesContainer.childNodes.length -1) > 0)
												{
													rangesContainer.removeChild(rangesContainer.firstChild);
												}
												var rangeSpan = rangesContainer.appendChild(new Element("span",{})).update(rangeLabel);
											} 
											else 
											{
												while( (rangesContainer.childNodes.length -1) > 0)
												{
													rangesContainer.removeChild(rangesContainer.firstChild);
												}
												var rangeLink = rangesContainer.appendChild(new Element("a",{'href':'#'})).update(rangeLabel);
																
												Event.observe(rangeLink,'click',function(ev){
													this.currentRange = rangeGroup[0];
													this.imageIndex = 0;
													this.showThumbGrid();
													ev.stop();
													return false;
												}.bind(this));
												
											}
											
										}.bind(this));
										//alert('Redraw ranges finished');
										var closeBtn = this.gridContainer.getElementsBySelector('#gallery_thumbgrid_close a')[0];
										if(this.observedCloseBtn!=true){
											Event.observe(closeBtn,'click',function(ev){
												this.hideThumbGrid();
												ev.stop();
												return false;
											}.bind(this));
											this.observedCloseBtn = true;
										}
								
										// find the range pair that the current range is inside of, then render them both.
										var rangePair = this.imageSet.allRangesInExtent().inGroupsOf(2).find(function(rangeGroup){
											if(ImageSet.prototype.compareRange(rangeGroup[0],this.currentRange) || ImageSet.prototype.compareRange(rangeGroup[1],this.currentRange)) return true;
											//return false;
										}.bind(this));
								
										var range1 = this.imageSet.getRange(rangePair[0]);
										var range2 = this.imageSet.getRange(rangePair[1]);
										var combinedSet = (range2)?range1['images'].concat(range2['images']):range1['images'];
										combinedSet.each(function(imageItem,i){
											// create deck panel with image and index inside of it
											var imgContainer = new Element("div",{'className':'griditem g'+i});
											// ignore placeholder images
											if(imageItem['placeholder']!=true){
												var img = imgContainer.appendChild(new Element("img",{'src':(this.displayMode=="normal")?imageItem.versions.thumbnail_small:imageItem.versions.thumbnail_large,'alt':'Click here to view gallery image','title':'Click here to view gallery image'}));
												Event.observe(img,'click',function(ev){ // Image's click handler hides the grid and navigates to the image.
													this.hideThumbGrid();
													if(i>9) this.goToRangeAndImage(rangePair[1],i - 10);
													else this.goToRangeAndImage(rangePair[0],i);
													ev.stop();
													return false;
												}.bind(this));
											} else {
												var img = imgContainer.appendChild(new Element("div",{'className':'placeholder_thumbnail'}).update(" "));
											}
											
											grid.appendChild(imgContainer);
										}.bind(this));
				 }
			/*}*/
		//alert('Exiting showThumbGrid');
		}
	},

	goFullScreen:function(range,index){ // TODO link to fullscreen
		document.location.href = "#";
	},

	goToRangeAndImage:function(range,index){
		// Ignore movement if we are already at this index and range
		if(index==this.imageIndex && ImageSet.prototype.compareRange(range,this.currentRange)) return;
		// Asynchronously fetch an unloaded range
		var refreshFunc = function(loadedSuccessfully){
			if(loadedSuccessfully){
				if(this.imageSet.isRealImage(range,index)) { // check if this is a real image or just a placeholder in the set
					this.imageIndex = index;
					this.currentRange = range;
					this.refresh();
				}
			} else {
				// TODO present user with error
			}
		}.bind(this);
		
		if(!this.imageSet.rangeLoaded(range)){
			// TODO load a set with XHR before going to it if it's not loaded yet.
			// TODO figure out URL format for ranges
			this.imageSet.loadRangeAsync(range,url,refreshFunc);
		} else {
			refreshFunc(true);
		}
	}
};
}

