// -----------------------------------------------------------------------------------
//
//	Lighttube v1.02
//	by cead - http://www.fiddling-cead.net/
//	05/04/08
//
//	based on Lightbox 2 by Lokesh Dhakar - http://huddletogether.com/projects/lightbox2/
//
//	Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
//
//
// -----------------------------------------------------------------------------------
/*

	Table of Contents
	-----------------
	Configuration

	Lighttube Class Declaration
	- initialize()
	- updateMovieList()
	- start()
	- changeMovie()
	- showImage()
	- end()

	Function Calls
	- document.observe()
	
*/
// -----------------------------------------------------------------------------------

//
//	Configuration
//
LighttubeOptions = Object.extend({
	safemode: true	// [true|false] if true, activate workaround code for specific browsers.
}, window.LighttubeOptions || {});

// other configurations are set in lightbox.js
//-----------------------------------------------------------------------------------

//
//	Lightube Class Declaration
//	- initialize()
//	- updateMovieList()
//	- start()
//	- changeMovie()
//	- showImage()
//	- end()
//
//	Structuring of code inspired by Lokesh Dhakar - http://www.huddletogether.com
//
var Lighttube = Class.create();
Lighttube.prototype = {
	imageArray: [],
	activeImage: undefined,

	// initialize()
	// Constructor runs on completion of the DOM loading. Calls updateMovieList and then
	// the function inserts html in the Lightbox's image container which is used to display the the movie container.
	//
	initialize: function() {
		this.resizeDuration = LightboxOptions.animate ? ((11 - LightboxOptions.resizeSpeed) * 0.15) : 0;
		this.overlayDuration = LightboxOptions.animate ? 0.2 : 0;  // shadow fade in/out duration

		// set properties
		var ua = navigator.userAgent;
		this.Gecko4Mac = (LighttubeOptions.safemode && (Prototype.Browser.Gecko  && /Mac/.test(ua)))? true : false;
		this.MSIE = (LighttubeOptions.safemode && Prototype.Browser.IE)? true : false;
		this.initialWidth = 800;		// default width for YouTube movies
		this.initialHeight = 480;		// default height for YouTube movies
		this.initialized = false;		// flag whether initialize completed or not, workaround for IE6.

		this.updateMovieList();

		this.keyboardAction = this.keyboardAction.bindAsEventListener(this);
		this.copyLightboxObjects();

		// IE6 seems to be incapable to handle 'bottomNavClose' at this moment. So, check and suspend override click event if necessary.
		if ($('overlay') &&
			$('lightbox') &&
			$('bottomNavClose'))
		{
			this.createOE($("imageContainer"), this.MSIE);
			this.initialized = true;
		} else {
			return false;
		}
	},

	//
	// copyLightboxObjects()
	// for easy access to objects created by Lightbox
	//
	copyLightboxObjects: function(){
		var th = this;
		(function(){
			var ids = 
				'overlay lightbox outerImageContainer imageContainer lightboxImage hoverNav prevLink nextLink loading loadingLink ' + 
				'imageDataContainer imageData imageDetails caption numberDisplay bottomNav bottomNavClose';   
			$w(ids).each(function(id){ th[id] = $(id); });
		}).defer();
	},

	//
	// createOE()
	// Code inserts html in the Lightbox's image container that looks similar to this:
	// *movie src and size are set ondemand
	//
	//	<div id="lighttube">
	//		<object id="movieContainer" type="application/x-shockwave-flash">
	//			<param name="wmode" value="transparent">
	//			<param id="movieURI" name="movie">
	//		</object>
	//	</div>
	//
	createOE: function(objParent, MSIE) {
		objParent.appendChild(Builder.node('div',{id:'lighttube'}));

		if (MSIE) return;	// MSIE don't support object element for flash movie.

		// Gecko Browsers for Mac can't handle animation-gif as background of flash contents.
		if (!this.Gecko4Mac && LightboxOptions.animate) $('lighttube').setStyle({background: 'url(' + LightboxOptions.fileLoadingImage +') no-repeat center'});

		// add a obeject element
		$('lighttube').appendChild(
			Builder.node('object',{id:'movieContainer', type:'application/x-shockwave-flash'},[
				Builder.node('param',{id:'movieURI', name:'movie'})
		]));

		// Note: Gecko Browsers for Mac can't render transparent player with transparent elements like 'overlay'.
		if (!this.Gecko4Mac) {
			$('movieContainer').appendChild(Builder.node('param',{name:'wmode', value:'transparent'}));
		}

		this.createEE($('movieContainer'));
		$('lighttube').hide();
	},

	//
	// createEE()
	// Inserts alternative code, for browsers which don't support object element, that looks similar to this:
	//	<embed id="movieAlt" type="application/x-shockwave-flash" wmode="transparent">
	//
	createEE: function(objParent){
		// for browsers which can't handle the object element.
		objParent.appendChild(Builder.node('embed',{id:'movieAlt',type:'application/x-shockwave-flash',bgcolor:$('outerImageContainer').getStyle('background-color')}));

	},

	//
	// updateMovieList()
	// Loops through anchor tags looking for 'lighttube' references and applies onclick
	// events to appropriate links. You can rerun after dynamically adding images w/ajax.
	//
	updateMovieList: function() {	
		this.updateMovieList = Prototype.emptyFunction;

		document.observe('click', (function(event){
			var target = event.findElement('a[rel^=lighttube]') || event.findElement('area[rel^=lighttube]');
			if (target) {
				event.stop();
				this.start(target);
			}
		}).bind(this));
	},
	
	//
	//	start()
	//	Display overlay and lighttube using lightbox.
	//
	start: function(movieLink) {	

		if (!this.initialized) {
			this.createOE($('imageContainer'), this.MSIE);
			this.initialized = true;
		}

		// MSIE can't switch embed element's src attribute on demand, so needs recreation at each time.
		if (this.MSIE) this.createEE($('lighttube'));

		$$('select', 'object', 'embed').each(function(node){ node.style.visibility = 'hidden' });

		// stretch overlay to fill page and fade in
		var arrayPageSize = this.getPageSize();
		this.overlay.setStyle({ width: arrayPageSize[0] + 'px', height: arrayPageSize[1] + 'px' });

		new Effect.Appear(this.overlay, { duration: this.overlayDuration, from: 0.0, to: LightboxOptions.overlayOpacity })

		this.imageArray = [];
		var movieNum = 0;		

		var relAttr = movieLink.getAttribute('rel');

		// get the movie size [width, height] specified in rel attribute, if exists.
		var movieSize = (relAttr == 'lighttube') ? [0,0] : relAttr.match(/[_[].*/).toString().match(/[0-9]+/g);

		// add single movie to imageArray
		this.imageArray.push(new Array(
			movieLink.getAttribute('href').replace('/watch?v=','/v/'), 
			movieLink.getAttribute('title'),
			(movieSize[0]) ? eval(movieSize[0]) : this.initialWidth,
			(movieSize[1]) ? eval(movieSize[1]) : this.initialHeight
				));
		
		// calculate top and left offset for the lightbox 
		var arrayPageScroll = document.viewport.getScrollOffsets();
		var lightboxTop = arrayPageScroll[1] + (document.viewport.getHeight() / 10);
		var lightboxLeft = arrayPageScroll[0];
		this.lightbox.setStyle({ top: lightboxTop + 'px', left: lightboxLeft + 'px' }).show();
		
		this.changeMovie(movieNum);
	},

	//
	//	changeMovie()
	//	Hide most elements and set movie information in preparation for resizing image container.
	//
	changeMovie: function(movieNum) {	
		this.activeImage = movieNum;	// update global var

		// hide elements during transition
		this.loading.hide();
		this.lightboxImage.hide();
		this.hoverNav.hide();
		this.prevLink.hide();
		this.nextLink.hide();

		// HACK: Opera9 does not currently support scriptaculous opacity and appear fx
		this.imageDataContainer.setStyle({opacity: .0001});
		this.numberDisplay.hide();

		if (!this.MSIE) {
			$('movieContainer').setAttribute('width',this.imageArray[this.activeImage][2]);
			$('movieContainer').setAttribute('height',this.imageArray[this.activeImage][3]);
			$('movieContainer').setAttribute('data', this.imageArray[this.activeImage][0]);
			$('movieURI').setAttribute('value', this.imageArray[this.activeImage][0]);
		}

		$('movieAlt').setAttribute('width',this.imageArray[this.activeImage][2]);
		$('movieAlt').setAttribute('height',this.imageArray[this.activeImage][3]);
		$('movieAlt').setAttribute('src', this.imageArray[this.activeImage][0]);

		this.resizeImageContainer(this.imageArray[this.activeImage][2], this.imageArray[this.activeImage][3]);
	},

	//
	//	showImage()
	//	Display movie.
	//
	showImage: function(){
		if (!this.MSIE) $('movieContainer').setStyle({visibility: 'visible'});	// cancel hideflash()
		$('movieAlt').setStyle({visibility: 'visible'});			// cancel hideflash()
		// Fade in effect doesn't seem to work with flash object,
		// but it works as the trriger to appear proper time.
		new Effect.Appear($('lighttube'), {
			duration: this.resizeDuration,
			queue: 'end',
			afterFinish: (function(){ this.updateDetails(); }).bind(this)
		});
	},

	//
	//	updateNav()
	//	Enabling keyboard navigation.
	//
	updateNav: function() {
		this.enableKeyboardNav();
	},

	//
	//	end()
	//
	end: function() {
		this.disableKeyboardNav();
		if ($('lighttube')) $('lighttube').hide();
		this.lightbox.hide();
		new Effect.Fade(this.overlay, { duration: this.overlayDuration});
		$$('select', 'object', 'embed').each(function(node){ node.style.visibility = 'visible' });

		// MSIE can't switch embed element's src attribute on demand, so needs recreation at each time.
		if (this.MSIE) Element.remove('movieAlt');
	}
}

// -----------------------------------------------------------------------------------
// Inherit Lightbox's methods
Lighttube.prototype.getPageSize = Lightbox.prototype.getPageSize;
Lighttube.prototype.keyboardAction = Lightbox.prototype.keyboardAction;
Lighttube.prototype.enableKeyboardNav = Lightbox.prototype.enableKeyboardNav;
Lighttube.prototype.disableKeyboardNav = Lightbox.prototype.disableKeyboardNav;
Lighttube.prototype.updateDetails = Lightbox.prototype.updateDetails;
Lighttube.prototype.resizeImageContainer = Lightbox.prototype.resizeImageContainer;

// Override Lightbox's end function
Lightbox.prototype.end = Lighttube.prototype.end;

// -----------------------------------------------------------------------------------
document.observe('dom:loaded', function () { new Lighttube(); });
