/**
 * @author POP: G.S.
 * @version 1.0
 * @lastmodified 5/15/2009
 * @classDescription An image gallery widget that loads external images and displays them.
 * @return {Object}	Returns a new instance of the class.
 * @projectDescription Forza Motorsport
 * 
 * Dependencies:
 * - Prototype 1.6.0.3+
 * - Scriptaculous 1.8.2+
 */

var ScreenshotWidget = Class.create({
	initialize: function(el,options) {
	
		
		// -----------------------------------------------------------------------------
		// Options:
		// -----------------------------------------------------------------------------	
		
		this.options = Object.extend({
			groupSize:6,
			screenshotWidth:564,
			screenshotHeight:316
		}, options || {});
		
		
		// -----------------------------------------------------------------------------
		// Inserted Elements:
		// -----------------------------------------------------------------------------
		
		// Insert placeholder DIVs for each screenshot to be loaded into:
		
		this.thumbnailImgs = $$('div#thumbslider ul.thumbnails li a img');
		
		for(i=0;i<el.select('ul.thumbnails li').length;i++) {
			$$('div#screenshot_player div.screenshots div.wrapper')[0].insert(
				'<div class="screenshot"><img alt="'+this.thumbnailImgs[i].readAttribute('alt')+'" width="'+this.options.screenshotWidth+'" height="'+this.options.screenshotHeight+'"/></div>',
				{position:top}
			);
		}
		
		
		// -----------------------------------------------------------------------------
		// Element References:
		// -----------------------------------------------------------------------------
		
		this.container = el;
		
		this.btnScreenshotLeft = $$('div#screenshot_player div.nav-left a')[0];
		this.btnScreenshotRight = $$('div#screenshot_player div.nav-right a')[0];
		
		this.btnThumbnailsLeft = el.select('div.nav-left a')[0];
		this.btnThumbnailsRight = el.select('div.nav-right a')[0];
		
		this.thumbnails = el.select('ul.thumbnails li');
		this.thumbnails_ul = el.select('ul.thumbnails')[0];
		
		this.screenshots = $$('div#screenshot_player div.screenshot img');
		this.screenshotsWrapper = $$('div#screenshot_player div.wrapper')[0];
		this.screenshotBackground = $$('div#screenshot_player div.screenshots')[0];
		
		this.metadata = $$('div#videoinfo div.metadata');
		this.metadataWrapper = $('metadataWrapper');

		
		// -----------------------------------------------------------------------------
		// Properties:
		// -----------------------------------------------------------------------------
		
		// Contains the unique IDs of each media item for easily figuring out their index:
		this.mediaIDs = {};
		
		this.metadata.each(function(el,index){
			//console.log(index + " - " + el.select('div.resources ul li')[2].innerHTML);
			this[el.select('div.resources ul li')[1].className] = index;
		},this.mediaIDs);

		this.thumbnailCount = this.thumbnails.length;
		this.visiblePane = 0;
		this.totalPanes = Math.ceil(this.thumbnailCount / this.options.groupSize);
		this.currentScreenshot = this.getHash() || 0;
		this.previousScreenshot = undefined;
		this.pageTitle = document.title;
		
		this.btnScreenshotLeftVisible = true;
		this.btnScreenshotRightVisible = true;
		this.btnThumbnailsLeftVisible = true;
		this.btnThumbnailsRightVisible = true;
				
		// -----------------------------------------------------------------------------
		// Page Setup:
		// -----------------------------------------------------------------------------
		
		this.setHash(this.currentScreenshot);
		
		// Display current and total number of panes on the page:
		
		//this.container.select('div.metadata p.position span.current')[0].update(this.currentScreenshot+1);
		$$('div#videoinfo p.position span.total')[0].update(this.thumbnailCount);
		
		
		this.loadImage(this.currentScreenshot);
		this.slideThumbnailsToPane(Math.floor(this.currentScreenshot / this.options.groupSize));

		
		// -----------------------------------------------------------------------------
		// Event Handlers:
		// -----------------------------------------------------------------------------
		
		this.btnScreenshotLeft.observe('click',this.__btnScreenshotLeftClick.bind(this));
		this.btnScreenshotRight.observe('click',this.__btnScreenshotRightClick.bind(this));
		this.btnThumbnailsLeft.observe('click',this.__btnThumbnailsLeftClick.bind(this));
		this.btnThumbnailsRight.observe('click',this.__btnThumbnailsRightClick.bind(this));
		
		this.thumbnails_ul.select('li a').invoke('observe','click',this.__thumbnailClick.bind(this));
	},
	__btnScreenshotLeftClick: function(e) {
		e.stop();
		
		if(this.currentScreenshot > 0) {
			this.currentScreenshot--;
			
			if(this.currentScreenshot < this.visiblePane * this.options.groupSize) {
				//this.slideThumbnailsLeft();
			}
			
		} else {
			this.currentScreenshot = this.thumbnailCount-1;
			this.slideThumbnailsToPane(this.totalPanes-1);
		}
		
		this.highlightThumbnail(this.currentScreenshot);
		this.loadImage(this.currentScreenshot);
	},
	__btnScreenshotRightClick: function(e) {
		e.stop();
		
		if(this.currentScreenshot < (this.thumbnailCount - 1)) {
			this.currentScreenshot++;
						
			if(this.currentScreenshot > ((this.visiblePane + 1) * this.options.groupSize) - 1) {
				//this.slideThumbnailsRight();
			}
			
		} else {
			this.currentScreenshot = 0;
			this.slideThumbnailsToPane(0);
		}
		
		this.highlightThumbnail(this.currentScreenshot);
		this.loadImage(this.currentScreenshot);
	},
	__btnThumbnailsLeftClick: function(e) {
		e.stop();
		this.slideThumbnailsLeft();
		this.hideAndShowButtons();
	},
	__btnThumbnailsRightClick: function(e) {
		e.stop();
		this.slideThumbnailsRight();
		this.hideAndShowButtons();
	},
	__thumbnailClick: function(e) {
		e.stop();
		this.currentScreenshot = e.element().up().up().previousSiblings().length;
		
		// Don't load an already visible screenshot:
		if(this.currentScreenshot != this.previousScreenshot) 
			this.loadImage(this.currentScreenshot);
	},
	hideAndShowButtons: function() {
		
		// Thumbnail nav btn logic
		
		if(this.visiblePane == 0 && this.btnThumbnailsLeftVisible == true) {
			this.btnThumbnailsLeftVisible = false;
			this.btnThumbnailsLeft.hide();
		} else if(this.visiblePane != 0 && this.btnThumbnailsLeftVisible == false) {
			this.btnThumbnailsLeftVisible = true;
			this.btnThumbnailsLeft.show();
		}
		
		if(this.visiblePane == this.totalPanes - 1 && this.btnThumbnailsRightVisible == true) {
			this.btnThumbnailsRightVisible = false;
			this.btnThumbnailsRight.hide();
		} else if(this.visiblePane != this.totalPanes - 1 && this.btnThumbnailsRightVisible == false) {
			this.btnThumbnailsRightVisible = true;
			this.btnThumbnailsRight.show();
		}
		
		
		// Screenshot nav btn logic
		
		if(this.currentScreenshot == 0 && this.btnScreenshotLeftVisible == true) {
			this.btnScreenshotLeftVisible = false;
			this.btnScreenshotLeft.hide();
		} else if(this.currentScreenshot != 0 && this.btnScreenshotLeftVisible == false) {
			this.btnScreenshotLeftVisible = true;
			this.btnScreenshotLeft.show();
		}
		
		if(this.currentScreenshot == this.thumbnailCount - 1 && this.btnScreenshotRightVisible == true) {
			this.btnScreenshotRightVisible = false;
			this.btnScreenshotRight.hide();
		} else if(this.currentScreenshot != this.thumbnailCount - 1 && this.btnScreenshotRightVisible == false) {
			this.btnScreenshotRightVisible = true;
			this.btnScreenshotRight.show();
		}
	},
	highlightThumbnail: function(index) {
		if(this.previousScreenshot != undefined)
			this.thumbnails[this.previousScreenshot].select('a')[0].removeClassName('in');
		
		this.thumbnails[index].select('a')[0].addClassName('in');
	},
	loadImage: function(index) {
				
		this.imgURL = this.thumbnails[index].select('a')[0].readAttribute('href');
		this.imageLoaded = false;
		this.negativeMargin = (index * -1 * this.options.screenshotWidth) + 'px';
		
		// Only load the image if it hasn't been loaded:
		if(this.screenshots[index].readAttribute('src')) {
			
			//console.log("Image already loaded.");
			
			// Don't show preloader GIF
			this.screenshotBackground.setStyle({visibility:'hidden'});
			
			this.screenshots[index].stopObserving('load');
			
			this.screenshotsWrapper.setStyle({left:this.negativeMargin});
			this.screenshots[index].setStyle({opacity:'0',visibility:'visible'});
			Effect.Fade(this.screenshots[index],{duration:1,from:0,to:1});
			
		} else {
			
			// Show preloader GIF
			this.screenshotBackground.setStyle({visibility:'visible'});
			
			//console.log("Loading image: " + index);
			
			this.screenshots[index].observe('load',function() { 
				
				//console.log("Image loaded.");

				this.screenshotsWrapper.setStyle({left:this.negativeMargin});
				this.screenshots[index].setStyle({opacity:'0',visibility:'visible'});
				Effect.Fade(this.screenshots[index],{duration:1,from:0,to:1});
			}.bind(this));
			
			this.screenshots[index].writeAttribute('src',this.imgURL);
		}
		
		if(this.previousScreenshot != undefined)
			this.screenshots[this.previousScreenshot].setStyle({visibility:'hidden'});
		
		
		this.targetPane = Math.floor(index / this.options.groupSize);
		
		// Slide the pane to show the currently highlighted thumbnail if necessary
		if( this.targetPane != this.visiblePane) {
			this.slideThumbnailsToPane(this.targetPane);			
		}

		this.highlightThumbnail(index);
		this.setHash(index);
		this.showMetadata(index,true);
		this.showCurrentImageNumber();
		this.hideAndShowButtons();
		
		this.previousScreenshot = index;
	},
	slideThumbnailsLeft: function() {
		if(this.visiblePane != 0) {
			this.visiblePane--;
		} else {
			this.visiblePane = this.totalPanes-1;
		}
		
		this.slideThumbnailsToPane(this.visiblePane);
	},
	slideThumbnailsRight: function() {
		if(this.visiblePane < this.totalPanes-1) {
			this.visiblePane++;
		} else {
			this.visiblePane = 0;
		}
			
		this.slideThumbnailsToPane(this.visiblePane);
	},
	slideThumbnailsToPane: function(index) {
		
		this.visiblePane = index;
		
		var negativeMargin = (index * -1 * this.options.paneWidth) + 'px';
		
		new Effect.Morph(this.thumbnails_ul,{
			style:{'left':negativeMargin},
			duration:0.3
		});
	},
	showMetadata: function(index,animate) {
		this.targetMargin = (-359 * index)+'px';
		
		//console.log("Sliding metadata_wrapper to : "+ this.targetMargin);
		
		// Adds the ability to suppress animation for initial page load :
		if(animate) {
			new Effect.Morph(this.metadataWrapper,{
				style:{'margin-left':this.targetMargin},
				duration:0.4
			});
		} else {
			this.metadataWrapper.setStyle({marginLeft:this.targetMargin});
		}
		
	},
	showCurrentImageNumber: function() {
		$$('div#videoinfo p.position span.current')[0].update(this.currentScreenshot+1);
	},
	setHash: function(index) {
		location.hash = '/screenshot/' + this.metadata[index].select('div.resources ul li')[1].className + '/';
		
		// For IE's benefit :
		document.title = this.pageTitle;
	},
	// Gets the current hash (unique media ID) and returns the index of the media
	getHash: function() {
		this.hash = Math.floor(location.hash.split('/')[2]);
		this.index = this.mediaIDs[this.hash];
				
		if(this.index == undefined) {
			//console.log("Referenced media does not exist.");
			return false;
		} else {
			return Math.floor(this.index);	// Prevents a string from being returned
		}
	}
});