/**
 * @author POP webdev [tw]
 * @version 0.3.3
 * @classDescription A Scroller to move a LIst vertically or horizontally.
 * @lastModified 1/9/2009 [tw]
 * @return {Object}	Returns an new instance.
 * This class depends on Prototype v1.6 and Scriptaculous effects.
 */
/*
TO IMPROVE:
	- add optional hooks into the move effect, either through functions or firing custom events. 
	e.g. fnOnBeforeMove and fnOnAfterMove or scroller:move and scroller:stop
*/

 var Scroller = Class.create({
	initialize: function(slideFrame, options) {
		// set options
		this.options = Object.extend({
			initialIndex: 0,
			durationPerSlide: 1,
			orientation: 'horizontal', 	// ['horizontal' | 'vertical']
			restAlignment: 'left', 		// horizontal: [left|center|right], vertical: [top|center|bottom]
			selectOnMove: true, 		// whether or not to "select" a slide when a move or jump method is called.
			selectOnClick: true 		// whether or not to "select" a slide it is clicked.
		}, options || {});

		// construction tasks
		this.slideFrame = $(slideFrame).makePositioned();
		this.slideList = $(slideFrame).down().cleanWhitespace().makePositioned();
		this.slides = this.slideList.childElements().invoke('cleanWhitespace'); // get some clean list items
		
		this.slideFrameDim = this.slideFrame.getDimensions();

		// BEGIN horrible ie6 hack to get appropriate slideFrame height (ie6 added overflown elements to height);
		var IE6 = false/*@cc_on || @_jscript_version < 5.7@*/;
		if (IE6) {
			this.slideList.hide();

			this.slideFrameDim = this.slideFrame.getDimensions();
			this.slideList.show();
		}
		// END horrible ie6 hack

		this.currentSlideIndex = this.options.initialIndex; // resting slide
		this.selectedSlideIndex = -1; // user selected slide
		this.moveEffect = null;
		this.isMoving = false;


		// go to the initial index
		this.jumpTo(this.currentSlideIndex, this.options.selectOnMove);

		// optional event handler
		if(this.options.selectOnClick){
			this.slideList.observe('click', this.__listClick.bindAsEventListener(this));
		}
		

	},
	
	__listClick: function(e){
		var el = e.element();
		
		if(el.nodeName == 'UL'){
			return; // user clicked in padding/margin of ul
		}
		if(el.nodeName != 'LI'){
			el = el.up('LI');
		}
		this.setSelectedSlide(el);
	},
	
	_calculateMoveByX: function(slideIndex) {
		var moveByX = 0;

		var slideListCurrentLeftPos = this.slideList.positionedOffset().left;
		var slideCurrentLeftPos = this.slides[slideIndex].positionedOffset().left;
		var slideFrameWidth = this.slideFrameDim.width;
		var slideWidth = this.slides[slideIndex].getWidth();

		// switch on this.options.restAlignment to determine resting place
		switch (this.options.restAlignment) {
			case 'left':
				moveByX = ((slideFrameWidth - slideListCurrentLeftPos) - (slideCurrentLeftPos)) - slideFrameWidth;
				break;
			case 'right':
				moveByX = ((slideFrameWidth - slideCurrentLeftPos) - slideListCurrentLeftPos) - (slideWidth);
				break;
			case 'center':
			default:
				// center (default)
				moveByX = (((slideFrameWidth / 2) - slideCurrentLeftPos) - slideListCurrentLeftPos) - (slideWidth / 2);
				break;
		}
		return Math.round(moveByX);
	},
	
	_calculateMoveByY: function(slideIndex) {
		var moveByY = 0;

		var slideListCurrentTopPos = this.slideList.positionedOffset().top;
		var slideCurrentTopPos = this.slides[slideIndex].positionedOffset().top;
		var slideFrameHeight = this.slideFrameDim.height;

		var slideHeight = this.slides[slideIndex].getHeight();

		// switch on this.options.restAlignment to determine resting place
		switch (this.options.restAlignment) {
			case 'top':
				moveByY = ((slideFrameHeight - slideListCurrentTopPos) - (slideCurrentTopPos)) - slideFrameHeight;
				break;
			case 'bottom':
				moveByY = ((slideFrameHeight - slideCurrentTopPos) - slideListCurrentTopPos) - (slideHeight);
				break;
			case 'center':
			default:
				// center (default)
				moveByY = (((slideFrameHeight / 2) - slideCurrentTopPos) - slideListCurrentTopPos) - (slideHeight / 2);
				break;
		}
		return Math.round(moveByY);
	},

	// moveToSlide
	moveTo: function(slideIndex) {
		// allow argument to be a slide LI itself
		if(!Object.isNumber(slideIndex) && Object.isElement(slideIndex)){
			slideIndex = this.slides.indexOf(slideIndex);
		}
			
		var slideCount = this.getSlideCount();
		if (slideIndex > (slideCount - 1)) { slideIndex = slideCount - 1; } // make sure we're within bounds

		this.stopMoving(); // A.D.D. protection.
		var seconds = Math.abs(this.currentSlideIndex - slideIndex) * this.options.durationPerSlide;
		this.currentSlideIndex = slideIndex;
		
		if(this.options.selectOnMove){
			this.setSelectedSlide(slideIndex);
		}
		
		var effectOptions = {
				//y: moveByY,
				duration: seconds,
				afterFinish: this.stopMoving.bind(this),
				transition: Effect.Transitions.sinoidal,
				fps: 20
			};
		
		// set the x or y delta in the options depending on orientation
		switch(this.options.orientation){
			case 'horizontal':
				var moveByX = this._calculateMoveByX(slideIndex);
				effectOptions.x = moveByX;
				break;
			case 'vertical':
				var moveByY = this._calculateMoveByY(slideIndex);
				effectOptions.y = moveByY;
				break;
		}
				
		this.isMoving = true;
		// all that for this
		this.moveEffect = new Effect.Move(this.slideList, effectOptions);
	},

	moveToNext: function(){
		var nextIndex = this.currentSlideIndex +1;
		if(nextIndex < this.getSlideCount()){
			this.moveTo(nextIndex);
		}
	},

	moveToPrevious: function(){
		var prevIndex = this.currentSlideIndex -1;
		if(prevIndex >= 0){
			this.moveTo(prevIndex);
		}		
	},
	
	moveToFirst: function(){
		this.moveTo(0);	
	},
	
	moveToLast: function(){
		this.moveTo(this.getSlideCount() -1);	
	},	
	
	stopMoving: function() {
		if (this.isMoving) {
			this.moveEffect.cancel(); // stops animation wherever it is
		}
		this.isMoving = false;
	},

	jumpTo: function(slideIndex) {
		// allow argument to be a slide LI itself
		if(!Object.isNumber(slideIndex) && Object.isElement(slideIndex)){
			slideIndex = this.slides.indexOf(slideIndex);
		}
			
		// stop the animation and go directly to the given index.
		this.currentSlideIndex = slideIndex;
				
		this.stopMoving();
		
		switch(this.options.orientation){
			case 'horizontal':
				this._setLeftPosition(slideIndex);
				break;
			case 'vertical':
				this._setTopPosition(slideIndex);
				break;
		}
		
		// use optional second argument to skip setSelectedSlide
		var allowSelection = (Object.isUndefined(arguments[1])) ? this.options.selectOnMove : arguments[1];
		if(allowSelection){
			this.setSelectedSlide(slideIndex);
		}
	},
	
	_setTopPosition: function(slideIndex){
		var slideListCurrentTopPos = this.slideList.positionedOffset()[1];
		var slideCurrentTopPos = this.slides[slideIndex].positionedOffset()[1];
		var slideFrameHeight = this.slideFrameDim.height;
		var slideHeight = this.slides[slideIndex].getHeight();

		var topPos = 0;
		switch (this.options.restAlignment) {
			case 'top':
				topPos = -slideCurrentTopPos;
				break;
			case 'bottom':
				topPos = (slideFrameHeight - slideHeight) - (slideCurrentTopPos);
				break;
			case 'center':
			default:
				// center
				topPos = (slideFrameHeight / 2 - slideCurrentTopPos) - (slideHeight / 2);
				break;
		}
		this.slideList.setStyle({ top: topPos + 'px' });		
	},
	
	_setLeftPosition: function(slideIndex){
		var slideListCurrentLeftPos = this.slideList.positionedOffset()[0];
		var slideCurrentLeftPos = this.slides[slideIndex].positionedOffset()[0];
		var slideFrameWidth = this.slideFrameDim.width;
		var slideWidth = this.slides[slideIndex].getWidth();

		var leftPos = 0;
		switch (this.options.restAlignment) {
			case 'left':
				leftPos = -slideCurrentLeftPos;
				break;
			case 'right':
				leftPos = (slideFrameWidth - slideWidth) - (slideCurrentLeftPos);
				break;
			case 'center':
			default:
				// center
				leftPos = (slideFrameWidth / 2 - slideCurrentLeftPos) - (slideWidth / 2);
				break;
		}
		this.slideList.setStyle({ left: leftPos + 'px' });		
	},
	

	reset: function() {
		this.currentSlideIndex = this.options.initialIndex;
		this.jumpTo(this.currentSlideIndex);
	},

	addSlide: function(elLi, bAddtoBeginning) {
		// add slide to list
		(bAddtoBeginning) ? this.slideList.insert({ top: elLi }) : this.slideList.insert(elLi);
		
		this.slides = this.slideList.childElements();
		
		if(bAddtoBeginning){
			// adjust list item indexing
			this.currentSlideIndex++;
			this.selectedSlideIndex++;
			this.jumpTo(this.currentSlideIndex, false);
		}
	},

	removeSlide: function(slideIndex) {
		this.slides[slideIndex].remove();
		this.slides = this.slideList.childElements();
		if(this.currentSlideIndex > slideIndex){
			// adjust list item indexing
			this.currentSlideIndex--;
			this.jumpTo(this.currentSlideIndex);
		}
	},
	
	sendSlideToEnd: function(slideIndex){
		this.relocateSlide(slideIndex, this.getSlideCount()-1 );
	},
	
	sendSlideToBeginning: function(slideIndex){
		this.relocateSlide(slideIndex, 0);
	},
	
	// want to be able move from beginning to end, or vice versa
	relocateSlide: function(oldIndex, newIndex) {
		if(newIndex > oldIndex){ 
			// ordering slide farther forward
			Element.insert(this.slides[newIndex], {after: this.slides[oldIndex]});
		}
		else{ 
			// farther back
			Element.insert(this.slides[newIndex], {before: this.slides[oldIndex]});
		}
		
		this.slides = this.slideList.childElements();// reset indexing.
		
		// updated the selected index if it was somewhere in the field of change
		var changeRange = (oldIndex > newIndex) ? $R(newIndex, oldIndex) : $R(oldIndex, newIndex);
		if(changeRange.include(this.selectedSlideIndex)){
			var selSlide = this.findSelectedSlide();
			this.selectedSlideIndex = this.getIndexForSlide(selSlide);
		}
	},	

	getSlideCount: function() {
		return this.slideList.childElements().length;
	},
	
	getIndexForSlide: function(elSlide){
		return this.slides.indexOf(elSlide);
	},
	
	getSlide: function(slideIndex){
		return this.slides[slideIndex];
	},
	
	getSelectedSlide: function(){
		return this.slides[this.selectedSlideIndex];
	},
	
	findSelectedSlide: function(){
		return this.slides.find(function(slide){
			return slide.hasClassName('in');
		});
	},
	
	setSelectedSlide: function(slideIndex){
		// allow argument to be a slide LI itself
		if(!Object.isNumber(slideIndex) && Object.isElement(slideIndex)){
			slideIndex = this.slides.indexOf(slideIndex);
		}
		// set the selected class and fire custom event.
		for (var i = 0, len = this.getSlideCount(); i < len; i++) {
			if (i === slideIndex) {
				this.slides[i].addClassName('in');
				this.selectedSlideIndex = slideIndex;
				this.slideFrame.fire('scroller:slideselected', {slide: this.slides[i], slideIndex: i });
			}
			else {
				this.slides[i].removeClassName('in');
			}
		}
		return slideIndex;// for future reference
	}
});

/**
 * @author POP webdev [tw]
 * @version 0.3.3
 * @classDescription Controls a scroller.
 * @return {Object}	Returns a new object.
 * @projectDescription
 * This class depends on Prototype v1.6, Scriptactulous Effects, and the Scroller class.
 * It extends Scroller and manages pagination for it (prev/next, group number links, next/previous slide links).
 */
 var ScrollerPagingControl = Class.create(Scroller, {
	initialize: function($super, slideFrame, scrollerOptions, controlListContainer, controlListContainerAgain, controlOptions) {
		// set control options
		this.controlOptions = Object.extend({
			itemsPerGroup: 4,
			initialGroupIndex: 0,
			previousSlideTriggerID: 'select_previous_slide',
			nextSlideTriggerID: 'select_next_slide',
			autoGenerate: true
		}, controlOptions || {});
		// construction tasks
		$super(slideFrame, scrollerOptions); // initialize parent class
		var controlListContainer = $(controlListContainer);
		if(!controlListContainer){return;}
		if(this.controlOptions.autoGenerate === true){
			//create new list and append to container
			this.controlList = this._createControlList();
			this.controlListAgain = this._createControlList();
			controlListContainer.insert(this.controlList);
			controlListContainerAgain.insert(this.controlListAgain);
		} else {
			// get existing list
			this.controlList = controlListContainer.down('ul, ol');
		}
		
		if ($$('.group').length/2 <= 1){
			controlListContainer.hide();
			controlListContainerAgain.hide();
		}

		// attach paging control events
		var controlLinks = this.controlList.select('li a');
		var controlLinksAgain = this.controlListAgain.select('li a');
		var allControlLinks = controlLinks.concat(controlLinksAgain);
		allControlLinks.each(function(lnk) {
			// use parent li classname to identify individual event links
			var elLi = lnk.up('li');
			if (elLi.hasClassName('previous')) {
				lnk.observe('click', this.__movePreviousClick.bindAsEventListener(this));
			} else if (elLi.hasClassName('next')) {
				lnk.observe('click', this.__moveNextClick.bindAsEventListener(this));
			} else {
				lnk.observe('click', this.__moveToClick.bindAsEventListener(this));
				elLi.addClassName('group')
			}
		}.bind(this));
		// attach events to optional select next/previous slide links
		if($(this.controlOptions.previousSlideTriggerID)){
			$(this.controlOptions.previousSlideTriggerID).observe('click', this.__selectPreviousSlideClick.bindAsEventListener(this));
		}
		if($(this.controlOptions.nextSlideTriggerID)){
			$(this.controlOptions.nextSlideTriggerID).observe('click', this.__selectNextSlideClick.bindAsEventListener(this));
		}
		this._adjustControlClasses();
		this.jumpToGroup(this.controlOptions.initialGroupIndex);
	},
	// event handlers
	__movePreviousClick: function(e) {
		Event.stop(e);
		this.moveToPreviousGroup();
	},
	__moveNextClick: function(e) {
		Event.stop(e);
		this.moveToNextGroup();
	},
	__moveToClick: function(e) {
		Event.stop(e);
		var elLi = e.element().up('li');
		// get the groupIndex
		var elGroupItems = elLi.up('ul').select('li.group');
		//var elGroupItems = this.controlList.select('li.group');
		var groupNum = elGroupItems.indexOf(elLi);
		this.moveToGroup(groupNum);
	},
	__selectNextSlideClick: function(e){
		Event.stop(e);
		this.selectNextSlide();
	},
	__selectPreviousSlideClick: function(e){
		Event.stop(e);
		this.selectPreviousSlide();
	},
	// methods
	moveToNextGroup: function() {
		if (this.currentGroupIndex < (this.getGroupCount() - 1)) {
			this.moveToGroup(this.currentGroupIndex + 1);
		}
	},
	moveToPreviousGroup: function() {
		if (this.currentGroupIndex > 0) {
			this.moveToGroup(this.currentGroupIndex - 1);
		}		
	},
	moveToFirstGroup: function() {
		this.moveToGroup(0);
	},
	moveToLastGroup: function() {
		this.moveToGroup(this.getGroupCount() - 1);
	},
	moveToGroup: function(groupIndex) {
		if ((groupIndex < this.getGroupCount()) && (groupIndex > -1) && groupIndex != this.currentGroupIndex) {
			this.currentGroupIndex = groupIndex;
			this.moveTo(groupIndex * this.controlOptions.itemsPerGroup);
			this._adjustControlClasses();
		}
	},
	jumpToGroup: function(groupIndex) {
		this.currentGroupIndex = groupIndex;
		this.jumpTo(groupIndex * this.controlOptions.itemsPerGroup);

		this._adjustControlClasses();
	},
	selectNextSlide: function() {
		//if at the end of current group, move to next group
		var nextIndex = this.selectedSlideIndex +1;
		var lastIndexInGroup = this.currentSlideIndex + this.controlOptions.itemsPerGroup;
		if(nextIndex >= lastIndexInGroup){
			this.moveToNextGroup();
		}
		else if(nextIndex < this.getSlideCount()){
			this.setSelectedSlide(nextIndex);
		}
	},
	selectPreviousSlide: function() {
		// if at beginning of group, move to previous group
		var previousIndex = this.selectedSlideIndex - 1;
		if(previousIndex < this.currentSlideIndex && (this.currentGroupIndex > 0)){
			this.moveToPreviousGroup();
			this.setSelectedSlide(previousIndex);
		}
		else if(previousIndex >= 0){
			this.setSelectedSlide(previousIndex);
		}
	},
	// Pass in a slide LI, or the index in the slidelist
	selectSlide: function(slide){
		return this.setSelectedSlide(slide);
	},
	getGroupCount: function() {
		return Math.ceil(this.getSlideCount() / this.controlOptions.itemsPerGroup);
	},
	_adjustControlClasses: function(){
		// adjust disabled class on next/previous 
		var groupCount = this.getGroupCount();
		var elPrevNavItem = this.controlList.down('li.previous');
		var elPrevNavAnchor = elPrevNavItem.down("a");
		
		if(this.currentGroupIndex  > 0){
			elPrevNavItem.removeClassName('disabled')
			elPrevNavAnchor.removeClassName('disabled')
		} else {
			elPrevNavItem.addClassName('disabled')
			elPrevNavAnchor.addClassName('disabled');
		}

		var elNextNavItem = this.controlList.down('li.next');
		var elNextNavAnchor = elNextNavItem.down("a");
		
		if(this.currentGroupIndex < (groupCount-1)){
			elNextNavItem.removeClassName('disabled')
			elNextNavAnchor.removeClassName('disabled')
		} else {
			elNextNavItem.addClassName('disabled');
			elNextNavAnchor.addClassName('disabled');
		}

		// adjust selected classes
		var elNavItems = this.controlList.select('li.group');
		var elNavItemsAgain = this.controlListAgain.select('li.group');
	
		for(var i = 0, len = elNavItems.size(); i < len;i++){
			(i == this.currentGroupIndex) ? elNavItems[i].addClassName('in') : elNavItems[i].removeClassName('in');
		}
		for(var i = 0, len = elNavItemsAgain.size(); i < len;i++){
			(i == this.currentGroupIndex) ? elNavItemsAgain[i].addClassName('in') : elNavItemsAgain[i].removeClassName('in');
		}
	},
	_createControlList: function(){
		/*
		// inserts the following:
			<ul>
				<li class="previous"><a href="#">prev</a></li>
				<li><a href="#">1</a></li>
				<li><a href="#">2</a></li>
				<li><a href="#">3</a></li>
				<li><a href="#">4</a></li>
				<li class="next"><a href="#">next</a></li>
			</ul>	
		*/
		var elUl = new Element('ul', {'class': 'pagination'});
		var elPrev = new Element('li', {'class': 'previous'});
		elPrev.insert(new Element('a', {'href': '#previous'}).update('Previous'));
		elUl.insert(elPrev);
		for(var i=0, len = this.getGroupCount(); i < len; i++){
			var elLi = new Element('li', {'class': 'group'});
			elLi.insert(new Element('a', {'href': '#' + i}).update((i+1)));
			elUl.insert(elLi);
		}
		var elNext = new Element('li', {'class': 'next'});
		elNext.insert(new Element('a', {'href': '#next'}).update('Next'));
		elUl.insert(elNext);
		return elUl;
	}
});

/**
 * @author POP.webdev
 * @version 0.2
 * @lastmodified 3/24/2008
 * @classDescription Provides a pairing of list item "tabs" with content elements and allows switching between them.
 * @return {Object}	Returns a new instance of the class.
 * @projectDescription
 * 
 * Dependencies:
 * - prototype v1.6 or later.
 */
var TabSwitcher = Class.create({
	initialize: function(links, items, options) {
		this.options = Object.extend({
			initialTabIndex: 0,
			tabOnClassName: 'selected',
			tabOffClassName: null,
			bodyOnStyles: {display:'block'},
			bodyOffStyles: {display:'none'}
		}, options || {});
		// get dom references for tab and "body" content elements
		this.links = $$(links);
		this.items = $$(items);
		if (this.items.length == 0 || this.links.length == 0) {return;}
		
		// attach event handlers
		this.links.invoke('observe', 'click', this._linkClick.bindAsEventListener(this));

		// show initial item
		this.setItem(this.links[this.options.initialTabIndex]);
	},
	
	_linkClick: function(e) {
		Event.stop(e);  // stop event
		var link = Event.findElement(e, 'a');
		this.setItem(link); // show item
	},

	setItem: function(elLnk) {
		// add/remove selected class on parent LI (tab elements)
		var tabOffClassName = this.options.tabOffClassName;
		var tabOnClassName = this.options.tabOnClassName;
		
		this.links.each(function(lnk){
			if(elLnk === lnk) {
				lnk.up('li').addClassName(tabOnClassName);
				if(tabOffClassName != null){
					lnk.up('li').removeClassName(tabOffClassName);
				}
			} else {
				lnk.up('li').removeClassName(tabOnClassName);
				if(tabOffClassName != null){
					lnk.up('li').addClassName(tabOffClassName);
				}				
			}
		});
		
		// show/hide items ("body" content elements)
		var attHref = elLnk.readAttribute("href").replace(/.*#+/, '');

		this.items.each(function(elBody){
			if(elBody.id == attHref) {
				elBody.show();
				elBody.setStyle(this.options.bodyOnStyles);
			} else {
				elBody.hide();
				elBody.setStyle(this.options.bodyOffStyles);
			}
		}.bind(this));
	}
});

var TabSwitcherNextPrev = Class.create(TabSwitcher,{
	initialize: function($super, links, items, options) {
		this.prevLink = $(options.prevLink);
		this.nextLink = $(options.nextLink);
		this.options = Object.extend({
			initialTabIndex: 0,
			tabOnClassName: 'selected',
			tabOffClassName: null,
			bodyOnStyles: {display:'block'},
			bodyOffStyles: {display:'none'}
		}, options || {});
		// get dom references for tab and "body" content elements
		this.links = $$(links);
		this.items = $$(items);
		if (this.items.length == 0 || this.links.length == 0) {return;}
		
		// attach event handlers
		this.links.invoke('observe', 'click', this._linkClick.bindAsEventListener(this));
		this.readQueryString();
		// show initial item
		this.setItem(this.links[this.options.initialTabIndex]);
		this.prevLink.observe('click', this.__clickPrev.bindAsEventListener(this));
		this.nextLink.observe('click', this.__clickNext.bindAsEventListener(this));
		if(this.options.initialTabIndex == 0) {
			this.prevLink.hide();
		}
	},
	setItem: function($super, elLnk) {
		$super(elLnk);
		this.currentIndex = this.links.indexOf(elLnk);
		this.btnCheck();
		document.fire('tab:opened', {tabIndex:this.links.indexOf(elLnk)});
		if (this.currentIndex == 0) {
			s.pageName='us:microsite:professorlaytondiabolicalbox:extra-goodies:send-to-a-friend:step1';s.t();
		}
		if (this.currentIndex == 1) {
			s.pageName='us:microsite:professorlaytondiabolicalbox:extra-goodies:send-to-a-friend:step2';s.t()
		}
		if (this.currentIndex == 2) {
			s.pageName='us:microsite:professorlaytondiabolicalbox:extra-goodies:send-to-a-friend:step3';s.t()
		}
		if (this.currentIndex == 3) {
			s.pageName='us:microsite:professorlaytondiabolicalbox:extra-goodies:send-to-a-friend:step4';s.t()
		}
	},
	__clickPrev:function(e) {
		e.stop();
		this.currentIndex--;
		this.setItem(this.links[this.currentIndex]);
		this.nextLink.show();
	},
	__clickNext:function(e) {
		e.stop();
		this.currentIndex++;
		this.setItem(this.links[this.currentIndex]);
		this.prevLink.show();
	},
	btnCheck:function(){
		if(this.currentIndex == 0) {
			this.prevLink.hide();
		} else {
			this.prevLink.show();
		}
		if(this.currentIndex == this.links.length -1) {
			this.nextLink.hide();
		} else {
			this.nextLink.show();
		}
	},
	readQueryString: function(){
		var originalDefaultOpenTab = this.options.initialTabIndex;
		this.options.initialTabIndex = window.location.search.toQueryParams()['open-tab'];
		if(typeof(this.items[this.options.initialTabIndex]) == "undefined"){
			this.options.initialTabIndex = originalDefaultOpenTab;
		}
	}
});

var PopUps = Class.create({
	initialize: function (elPopups, hDefaultWinOptions) {
		// create a default options hash
		this.defaultOptions = $H({
			width: 640,
			height: 480,
			//windowPosition: 'center', //['top-left'|'top-center'|'top-right'|'center'|'bottom-left'|'bottom-center'|'bottom-right']
			//left:  #,					// DIY left position of the window
			//top:  #,					// DIY top position of the window
			hOffset: 0,					// Horizontal offset
			vOffset: 0,					// Vertical offset
			location: 'no',
			menubar: 'no',
			status: 'no',		
			toolbar: 'no',
			scrollbars: 'no',
			resizable: 'yes',
			fullscreen: 'no',			// Display the window in theater mode?
			channelmode: 'no',			// Display the browser in full-screen mode? (must also be in theater mode)
			titlebar: 'no',
			windowName: 'popup'
		}).update(hDefaultWinOptions);

		var linkEventHandle = this.__LinkClick.bindAsEventListener(this);
		var elementEventHandle = this.__ElementClick.bindAsEventListener(this);
	
		elPopups.each(function(el){
			el.observe('click', (el.nodeName == 'A') ? linkEventHandle : elementEventHandle);
		});

	},

	__LinkClick: function (e){
		var el = Event.findElement(e, 'a');
 		var url = el.readAttribute('href');
 		var instanceOptions;
 		if(el.readAttribute('rel')){
 			instanceOptions = $H(el.readAttribute('rel').evalJSON());
 		}
		e.preventDefault();
		
		this.openWindow(url, instanceOptions);
	},
	
	__ElementClick: function (e){
		var el = e.element();
		var params = el.readAttribute('_popup').evalJSON();
 		var url = el.readAttribute('_popup');
 		var instanceOptions;
 		if(params.winOptions){
 			instanceOptions = $H(params.winOptions);
 		}
		this.openWindow(params.url, instanceOptions);
	},	
	
	openWindow: function(url, instanceWinOptions){
		// Merge specific options hash set in the rel with default options
		var options = (instanceWinOptions) ? this.defaultOptions.merge($H(instanceWinOptions)) : this.defaultOptions.clone();
		
		// position the window if specified
		if(options.get('windowPosition')){
			var pos = options.unset('windowPosition');	
			var left, top;
			var availHeight = screen.availHeight, availWidth = screen.availWidth;
			var popupHeight = options.get('height'), popupWidth = options.get('width');
			var vOffset = options.get('vOffset'), hOffset = options.get('hOffset');
			switch(pos){
				case 'top-left': 
					top = 0 + vOffset;
					left = 0 + hOffset;
					break;
				case 'top-center': 
					top = 0 + vOffset;
					left = ((availWidth - popupWidth)/2) + hOffset;
					break;
				case 'top-right': 
					top = 0 + vOffset;
					left = availWidth - (popupWidth + hOffset);
					break;
				case 'center': 
					top = ((availHeight - popupHeight)/2) + vOffset;
					left = ((availWidth - popupWidth)/2) + hOffset;
					break;
				case 'bottom-left': 
					top = availHeight - (popupHeight + vOffset);
					left = 0 + hOffset;
					break;
				case 'bottom-center': 
					top = availHeight - (popupHeight + vOffset);
					left = ((availWidth - popupWidth)/2) + hOffset;
					break;
				case 'bottom-right': 
					top = availHeight - (popupHeight + vOffset);
					left = availWidth - (popupWidth + hOffset);
					break;
			}
			options.set('top', top);
			options.set('left', left);
		}

		var win = window.open(url, escape(options.unset('windowName')), options.invoke('join', '=').join(','));
		if (window.focus) {
			win.focus()
		}
	}
});

var VideoSwitcher = Class.create({
	initialize: function(links, videoContainerId, videoId, options) {
		this.options = Object.extend({
			initialVideoIndex: 0,
			tabOnClassName: 'selected',
			tabOffClassName: null
		}, options || {});
		// get dom references for tab and "body" content elements
		this.links = $$(links);
		this.videoId = videoId;
		this.videoContainer = $(videoContainerId);
		if (this.links.length == 0 || !this.videoContainer) {return;}
		// attach event handlers
		this.links.invoke('observe', 'click', this._linkClick.bindAsEventListener(this));
		// show initial item
		this.embedFlash(this.links[this.options.initialVideoIndex].rel.evalJSON());
	},
	
	_linkClick: function(e) {
		Event.stop(e);  // stop event
		var link = Event.findElement(e, 'a');
		this.unembedFlash();
		var videoOptions = link.rel.evalJSON();
		this.embedFlash(videoOptions); // show item
	},
	embedFlash: function(videoOptions) {
		this.videoContainer.previous('h3').update(videoOptions.headerTitle);
		var settings_tr = {
			path: "../../_ui/swf/pl_extragoodies_video.swf",
			width: "619",
			height: "346",
			version: "9.0.0",
			id: this.videoId, // flash replace id
			expressInstall: false
		};
		var flashvars_tr = {
			previewPath: videoOptions.previewPath,
			flvPath: videoOptions.flvPath,
			swfPath: '../../_ui/swf/',
			omnitureTitle: videoOptions.omnitureTitle
		};
		var params = {
			wmode: 'opaque',
			scale: "noscale",
			allowfullscreen: "false"
		};
		var attributes = {};
		if (navigator.platform == "Nintendo Wii") {
			settings_tr.path = "../../_ui/swf/pl_extragoodies_video_wii.swf";
			settings_tr.version = "7.0.0";
			flashvars_tr.flvPath = videoOptions.wiiFlvPath;
		};
		swfobject.embedSWF(settings_tr.path, settings_tr.id, settings_tr.width, settings_tr.height, settings_tr.version, settings_tr.expressInstall, flashvars_tr, params, attributes);
		
	},
	unembedFlash: function(){
		$(this.videoId).remove();
		var newVideo = new Element("div",{ id: this.videoId});
		this.videoContainer.insert({top: newVideo});
	}
});

var previewMessage = Class.create({
	initialize:function(options) {
		this.options = Object.extend({ }, options || {});
		document.observe('tab:opened', this.__getPage.bindAsEventListener(this));
	},
	__getPage: function(e) {
		if (e.memo.tabIndex == 3){
			var params = {
				'background': $$('input[name=background]:checked').first().getValue(),
				'message': $$('input[name=message]:checked').first().getValue(),
				'puzzle': $$('input[name=puzzle]:checked').first().getValue()
			};
			var pageRequest = new Ajax.Updater('preview-frame', 'previewMessage.jsp', {parameters: params});
		}
	}
});


var interstitialOverlay = Class.create({
	initialize: function(options) {
		this.options = Object.extend({
			targetLinkSelector: 'a.target-link',
			targetLinkDestination: '_self',
			cancelLinkSelector: 'a.cancel-link',
			parentContainer: 'parent-overlay'
		}, options || {});
		this._createOverlay();
		this._insertOverlay();
		this.elDiv.hide();
        $$(this.options.targetLinkSelector).invoke('observe', 'click', this.__openClick.bindAsEventListener(this));
        $$(this.options.cancelLinkSelector).invoke('observe', 'click', this.__closeOverlay.bindAsEventListener(this));
	},

	_createOverlay: function() {
		this.elDiv = new Element('div', {'id': this.options.parentContainer});
		var elDivChild = new Element('div', {'id': this.options.parentContainer+'-child'});
		var elUl = new Element('ul');
		var elContinue = new Element('li');
		elContinue.insert(new Element('a', {'class': 'continue'}).writeAttribute('target', this.options.targetLinkDestination).update('<span>Continue</span>'));
		var elCancel = new Element('li');
		elCancel.insert(new Element('a', {'class': 'cancel-link', 'href': '#'}).update('<span>Cancel</span>'));
		this.elDiv.insert(elDivChild);
		elDivChild.insert(elUl);
		elUl.insert(elContinue);
		elUl.insert(elCancel);
	},

	_insertOverlay: function() {
		$('overlay').insert({after: this.elDiv});
	},

	show: function() {
		var viewportHeight = $(document.body).getHeight() + 172 + 'px';
		var viewportWidth = document.viewport.getWidth();
		this.elDiv.show();
		$('overlay').addClassName('interstitial-active').setStyle({
			display: 'block',
			height: viewportHeight
		});
		$(this.options.parentContainer).setStyle({
			left: (viewportWidth - $(this.options.parentContainer).getWidth()) / 2 +'px'
		});
		$('overlay').observe('click', this.__closeOverlay.bindAsEventListener(this));
	},

	hide: function() {
		$('overlay').hide();
		this.elDiv.hide();
	},

    __openClick: function(e) {
    	Event.stop(e);
		var elLink = Event.element(e);
		var siteURL = elLink.readAttribute('href');
		$(this.options.parentContainer).down('a.continue').setAttribute('href', siteURL);
		this.show();
	},
	
	__closeOverlay: function(e) {
		Event.stop(e);
		this.hide();
	}

});

var modalOverlay = Class.create(interstitialOverlay,{
	initialize: function($super, options) {
		$super(options);
		$$('a.close-link').invoke('observe', 'click', this.__closeOverlay.bindAsEventListener(this));
	},

	_createOverlay: function() {
		this.elDiv = new Element('div', {'id': this.options.parentContainer});
		var elDivChild = new Element('div', {'id': this.options.parentContainer+'-child'});
		this.elDiv.insert(elDivChild);
		elDivChild.insert({top: new Element('a', {'class': 'close-link', 'href': '#'}).update('Close')});
	},
	
	__openClick: function(e) {
    	Event.stop(e);
		this.show();
	}

});

var NoJsRemover = {
	initialize: function() {
		$$('body.nojs').invoke('removeClassName', 'nojs');
	}
}

function wiiBehavior() {
	if (navigator.platform == "Nintendo Wii") {
		$$('.wii-remove').invoke('hide');
		$$('.popup-puzzle').invoke('removeAttribute', 'href');
		$$('.popup-puzzle').invoke('removeClassName', 'popup-puzzle');
	} else {
		$$('.wii-add').invoke('removeClassName', 'wii-add');
	}
}

document.observe('dom:loaded', function(){
	popUps = new PopUps($$('.popup-puzzle'), {windowName: 'defaultWindowName', windowPosition: 'center', height: '627', width: '880'});
	NoJsRemover.initialize();
});