// -----------------------------------------------------------------------------------
//
//	Lighttube v1.01
//	by cead - http://www.fiddling-cead.net/
//	01/02/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
	Global Variables

	Extending Built-in Objects	
	- Object.extend(Element)
	- Array.prototype.removeDuplicates()
	- Array.prototype.empty()

	Lightbox Class Declaration
	- initialize()
	- updateMovieList()
	- start()
	- changeMovie()
	- resizeImageContainer()
	- showMovie()
	- end()
	- overrideClick()
	
	Miscellaneous Functions
	- initLighttube()
	
	Function Calls
	- addLoadEvent(initLighttube)
	
*/
// -----------------------------------------------------------------------------------

//
//	Configuration
//
var safemode = true;	// [true|false] if true, activate workaround code for specific browsers.

// other configurations are set in lightbox.js

// -----------------------------------------------------------------------------------

//
//	Global Variables
//

// use Lightbox's variables as is.

// -----------------------------------------------------------------------------------

//
//	Lightube Class Declaration
//	- initialize()
//	- updateMovieList()
//	- start()
//	- changeMovie()
//	- showMovie()
//	- end()
//	- overrideClick()
//
//	Structuring of code inspired by Lokesh Dhakar - http://www.huddletogether.com
//
var Lighttube = Class.create();

Lighttube.prototype = {
	// 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() {	
		// set properties
		var ua = navigator.userAgent;
		this.Gecko4Mac = (safemode && (/Gecko/.test(ua)  && /Mac/.test(ua) && !/KHTML|Safari|Konqueror/.test(ua)))? true : false;
		this.MSIE = (safemode && /MSIE/.test(ua))? true : false;
		this.initialWidth = 425;		// default width for YouTube movies
		this.initialHeight = 355;		// default height for YouTube movies
		this.initialized = false;		// flag whether initialize completed or not, workaround for IE6.

		this.updateMovieList();

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

	//
	// 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) {
		var objLighttube = document.createElement("div");
		objLighttube.setAttribute('id', 'lighttube');
		objParent.appendChild(objLighttube);

		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) objLighttube.style.background = 'url(' + fileLoadingImage +') no-repeat center';

		// add a obeject element
		var objMovieContainer = document.createElement("object");
		objMovieContainer.setAttribute('id', 'movieContainer');
		objMovieContainer.setAttribute('type', 'application/x-shockwave-flash');
		objLighttube.appendChild(objMovieContainer);

		// add param elements in the obejct element
		var objMovieURI = document.createElement("param");
		objMovieURI.setAttribute('id', 'movieURI');
		objMovieURI.setAttribute('name', 'movie');
		objMovieContainer.appendChild(objMovieURI);

		// Note: Gecko Browsers for Mac can't render transparent player with transparent elements like 'overlay'.
		if (!this.Gecko4Mac) {
			var objMovieMode = document.createElement("param");
			objMovieMode.setAttribute('name', 'wmode');
			objMovieMode.setAttribute('value', 'transparent');
			objMovieContainer.appendChild(objMovieMode);
		}

		this.createEE(objMovieContainer);
		Element.hide('lighttube');
	},

	//
	// 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.
		var objMovieAlt = document.createElement("embed");
		objMovieAlt.setAttribute('id', 'movieAlt');
		objMovieAlt.setAttribute('type', 'application/x-shockwave-flash');

		// Note: Gecko Browsers for Mac can't render transparent player with transparent elements like 'overlay'.
		(!this.Gecko4Mac) ? objMovieAlt.setAttribute('wmode', 'transparent') : objMovieAlt.setAttribute('bgcolor', '#ffffff');
		objParent.appendChild(objMovieAlt);
	},

	//
	// 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() {	
		if (!document.getElementsByTagName){ return; }
		var anchors = document.getElementsByTagName('a');
		var areas = document.getElementsByTagName('area');

		// decide if Lighttube should be deactivate
		// If global variable 'safemode' is true and Gecko Browsers for Mac is detected, then Lighttube is deacivated.

		// loop through all anchor tags
		for (var i=0; i<anchors.length; i++){
			var anchor = anchors[i];
			
			var relAttribute = String(anchor.getAttribute('rel'));
			
			// use the string.match() method to catch 'lighttube' references in the rel attribute
			if (anchor.getAttribute('href') && (relAttribute.toLowerCase().match('lighttube'))){
					anchor.onclick = function () {myLighttube.start(this); return false;}
			}
		}
		// loop through all area tags
		// todo: combine anchor & area tag loops
		for (var i=0; i< areas.length; i++){
			var area = areas[i];
			
			var relAttribute = String(area.getAttribute('rel'));
			
			// use the string.match() method to catch 'lightbox' references in the rel attribute
			if (area.getAttribute('href') && (relAttribute.toLowerCase().match('lighttube'))){
				area.onclick = function () {myLighttube.start(this); return false;}
			}
		}
	},
	
	//
	//	start()
	//	Display overlay and lighttube using lightbox. If a movie is part of a set, add siblings to imageArray.
	//
	start: function(movieLink) {	

		if (!myLighttube.initialized) {
			myLighttube.overrideClick();
			myLighttube.createOE(document.getElementById("imageContainer"), myLighttube.MSIE);
			myLighttube.initialized = true;
		}

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

		hideSelectBoxes();
		hideFlash();

		// stretch overlay to fill page and fade in
		var arrayPageSize = getPageSize();
		Element.setWidth('overlay', arrayPageSize[0]);
		Element.setHeight('overlay', arrayPageSize[1]);

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

		imageArray = [];		// clear global variable
		var movieSize = [0, 0];	// [width, height]
		var movieNum = 0;		
		var relAttr = movieLink.getAttribute('rel');

		// if movie is set for lighttube..
		if (/^lighttube/.test(relAttr)){
			// get the movie size specified in rel attribute, if exists.
			if (relAttr != 'lighttube') movieSize = relAttr.match(/[_[].*/).toString().match(/[0-9]+/g);

			// add single movie to imageArray
			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
				));
		} else return;
		
		// calculate top and left offset for the lightbox 
		var arrayPageScroll = getPageScroll();
		var lightboxTop = arrayPageScroll[1] + (arrayPageSize[3] / 10);
		var lightboxLeft = arrayPageScroll[0];
		Element.setTop('lightbox', lightboxTop);
		Element.setLeft('lightbox', lightboxLeft);
		
		Element.show('lightbox');
		
		this.changeMovie(movieNum);
	},

	//
	//	changeMovie()
	//	Hide most elements and set movie information in preparation for resizing image container.
	//

	changeMovie: function(movieNum) {	
		var objMovieContainer = document.getElementById("movieContainer");
		var objMovieURI = document.getElementById("movieURI");
		var objMovieAlt = document.getElementById("movieAlt");
		
		activeImage = movieNum;	// update global var

		// hide elements during transition
		Element.hide('loading');
		Element.hide('lightboxImage');
		Element.hide('hoverNav');
		Element.hide('prevLink');
		Element.hide('nextLink');
		Element.hide('imageDataContainer');
		Element.hide('numberDisplay');

		if (!myLighttube.MSIE) {
			objMovieContainer.setAttribute('width',imageArray[activeImage][2]);
			objMovieContainer.setAttribute('height',imageArray[activeImage][3]);
			objMovieContainer.setAttribute('data', imageArray[activeImage][0]);
			objMovieURI.setAttribute('value', imageArray[activeImage][0]);
		}

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

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

	//
	//	resizeImageContainer()
	//
	resizeImageContainer: function( imgWidth, imgHeight) {
		// get curren width and height
		this.widthCurrent = Element.getWidth('outerImageContainer');
		this.heightCurrent = Element.getHeight('outerImageContainer');

		// get new width and height
		var widthNew = (imgWidth  + (borderSize * 2));
		var heightNew = (imgHeight  + (borderSize * 2));

		// scalars based on change from old to new
		this.xScale = ( widthNew / this.widthCurrent) * 100;
		this.yScale = ( heightNew / this.heightCurrent) * 100;

		// calculate size difference between new and old image, and resize if necessary
		wDiff = this.widthCurrent - widthNew;
		hDiff = this.heightCurrent - heightNew;

		if(!( hDiff == 0)){ new Effect.Scale('outerImageContainer', this.yScale, {scaleX: false, duration: resizeDuration, queue: 'front'}); }
		if(!( wDiff == 0)){ new Effect.Scale('outerImageContainer', this.xScale, {scaleY: false, delay: resizeDuration, duration: resizeDuration}); }

		// if new and old image are same size and no scaling transition is necessary, 
		// do a quick pause to prevent image flicker.
		if((hDiff == 0) && (wDiff == 0)){
			if (navigator.appVersion.indexOf("MSIE")!=-1){ pause(250); } else { pause(100);} 
		}

		Element.setWidth( 'imageDataContainer', widthNew);

		this.showMovie();
	},
	
	//
	//	showMovie()
	//	Display movie.
	//
	showMovie: function(){
		if (!myLighttube.MSIE) document.getElementById('movieContainer').style.visibility = 'visible';	// cancel hideflash()
		document.getElementById('movieAlt').style.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: resizeDuration, queue: 'end', afterFinish: function(){	myLighttube.updateDetails(); } }) 
	},

	//
	//	updateDetails()
	//	Display caption and bottom nav.
	//
	updateDetails: function() {
	
		// if caption is not null
		if(imageArray[activeImage][1]){
			Element.show('caption');
			Element.setInnerHTML( 'caption', imageArray[activeImage][1]);
		}
		
		new Effect.Parallel(
			[ new Effect.SlideDown( 'imageDataContainer', { sync: true, duration: resizeDuration, from: 0.0, to: 1.0 }), 
			  new Effect.Appear('imageDataContainer', { sync: true, duration: resizeDuration }) ], 
			{ duration: resizeDuration, afterFinish: function() {
				// update overlay size and update nav
				var arrayPageSize = getPageSize();
				Element.setHeight('overlay', arrayPageSize[1]);
				myLighttube.updateNav();
				}
			} 
		)
	},

	//
	//	updateNav()
	//	Display appropriate previous and next hover navigation.
	//
	updateNav: function() {
		this.enableKeyboardNav();
	},

	//
	//	enableKeyboardNav()
	//
	enableKeyboardNav: function() {
		document.onkeydown = this.keyboardAction; 
	},

	//
	//	disableKeyboardNav()
	//
	disableKeyboardNav: function() {
		document.onkeydown = '';
	},

	//
	//	keyboardAction()
	//
	keyboardAction: function(e) {
		if (e == null) { // ie
			keycode = event.keyCode;
			escapeKey = 27;
		} else { // mozilla
			keycode = e.keyCode;
			escapeKey = e.DOM_VK_ESCAPE;
		}

		key = String.fromCharCode(keycode).toLowerCase();
		
		if((key == 'x') || (key == 'o') || (key == 'c') || (keycode == escapeKey)){	// close lightbox
			myLighttube.end();
		} else if((key == 'p') || (keycode == 37)){	// display previous image
			if(activeImage != 0){
				myLighttube.disableKeyboardNav();
				myLighttube.changeImage(activeImage - 1);
			}
		} else if((key == 'n') || (keycode == 39)){	// display next image
			if(activeImage != (imageArray.length - 1)){
				myLighttube.disableKeyboardNav();
				myLighttube.changeImage(activeImage + 1);
			}
		}

	},

	//
	//	end()
	//
	end: function() {
		this.disableKeyboardNav();
		Element.hide('lighttube');
		Element.hide('lightbox');
		new Effect.Fade('overlay', { duration: overlayDuration});
		showSelectBoxes();
		showFlash();

		if (myLighttube.MSIE) Element.remove('movieAlt');
	},

	//
	//	overrideClick()
	//	override onclick event of Lightbox
	//
	overrideClick: function() {
		document.getElementById('overlay').onclick = function() { myLighttube.end(); }
		document.getElementById('lightbox').onclick = function(e) {	// close Lightbox is user clicks shadow overlay
			if (!e) var e = window.event;
			var clickObj = Event.element(e).id;
			if ( clickObj == 'lightbox') {
				myLighttube.end();
			}
		}
		document.getElementById('bottomNavClose').onclick = function() { myLighttube.end(); return false; }
	}
}

// -----------------------------------------------------------------------------------

function initLighttube() { myLighttube = new Lighttube();}
Event.observe(window, 'load', initLighttube, false);
