/**
 * @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: {},
			bodyOffStyles: {},
			lazyLoadImages: false,
			callback: function(){}
		}, options || {});

		// get dom references for tab and "body" content elements
		this.winHash = window.location.hash.replace('#','') || false;
		this.links = $$(links);
		this.items = $$(items);

		if(this.items.length == 0 || this.links.length == 0) {return;}

		var initialTabIndex = this.options.initialTabIndex,
			hashItem = $(this.winHash);

		this.items.each(function(elBody, index){
			if(elBody.id == this.winHash){
				initialTabIndex = index;
			}
		}.bind(this));

		// show initial item
		this.setItem(this.links[initialTabIndex]);
		this.items[initialTabIndex].addClassName('tab-on');
		
		this._eventHandlers();
	},
	_eventHandlers: function(){
		this.links.invoke('observe', 'click', this._linkClick.bindAsEventListener(this));
	},
	_linkClick: function(e){
		Event.stop(e);  // stop event
		var link = Event.findElement(e, 'a');

		link.fire('tab:tabOpen');
		this.setItem(link); // show item
		this.options.callback();
	},
	setItem: function(elLnk){
		// add/remove selected class on parent LI (tab elements)
		var tabOffClassName = this.options.tabOffClassName,
			tabOnClassName = this.options.tabOnClassName,
			elLink = this.links,
			elTab = this.items;

		for(var i=0; i<elLink.length; i++){
			if(elLnk === elLink[i]){
				elLink[i].up('li').addClassName(tabOnClassName);
				if(tabOffClassName != null){
					elLink[i].up('li').removeClassName(tabOffClassName);
				}
			}else{
				elLink[i].up('li').removeClassName(tabOnClassName);
				if(tabOffClassName != null){
					elLink[i].up('li').addClassName(tabOffClassName);
				}				
			}
		}
		
		// show/hide items ("body" content elements)
		var attHref = elLnk.readAttribute("href").replace(/.*#+/, '');

		for(var i=0; i<elTab.length; i++){
			if(elTab[i].id == attHref){
				elTab[i].addClassName('tab-on');
				if(this.options.lazyLoadImages){
					this.lazyLoad(elTab[i]);
				}
			}else{
				elTab[i].removeClassName('tab-on');
			}
		}
	},
	lazyLoad: function(elTab){
		var elImage = elTab.select('img');

		if(elImage){
			for(var e=0; e<elImage.length; e++){
				if(elImage[e].readAttribute('src') == ''){
					var imageSrc = elImage[e].readAttribute('data-src'),
						imageMedia = elImage[e].readAttribute('data-media');

					elImage[e].hide();

					if(!imageMedia){
						elImage[e].observe('load', function(e){
							this.effects = new Effect.Appear(this,{
								duration: 0.3
							});
						});
					}

					elImage[e].setAttribute('src', imageSrc);
				}
			}
		}
	}
});

var MediaTabSwitcher = Class.create(TabSwitcher,{
	initialize: function($super, links, items, options, mediaOptions){
		this.mediaOptions = Object.extend({
			elTabWrapper: '',
			imageClass: '',
			audioVideoClass: '',
			flashTargetID: '',
			flashPlaceholderClass: '',
			flashSettings: {},
			flashVars: {},
			flashParams: {},
			flashAttributes: {}
		}, mediaOptions || {});

		$super(links, items, options);

		this.elFlashTarget = new Element('div', { 'id' : this.mediaOptions.flashTargetID }).update('Flash is required for this feature.');

		if(this.items[this.options.initialTabIndex].hasClassName(this.mediaOptions.audioVideoClass)){
			this.embedFlashPlayer(this.items[this.options.initialTabIndex]);
		}
	},
	_eventHandlers: function(){
		document.observe('tab:tabOpen', function(e){
			var elTab = e.target.hash;

			this.updateFlashPlayer(elTab);
		}.bind(this));

		this.links.invoke('observe', 'click', this._mediaLinkClick.bindAsEventListener(this));
	},
	_mediaLinkClick: function(e){
		Event.stop(e);
		var link = Event.findElement(e, 'a');

		this.setItem(link);
		this.detectMedia(link);
		this.options.callback();
	},
	embedFlashPlayer: function(elTarget){
		var settings = this.mediaOptions.flashSettings,
			flashTarget = this.mediaOptions.flashTargetID,
			flashvars = this.mediaOptions.flashVars,
			params = this.mediaOptions.flashParams,
			attributes = this.mediaOptions.flashAttributes,
			flashPlaceholder = elTarget.down('img.' + this.mediaOptions.flashPlaceholderClass),
			flashContentURL = flashPlaceholder.readAttribute('data-media'),
			flashPosterURL = flashPlaceholder.readAttribute('src'),
			flashVersion = swfobject.getFlashPlayerVersion();

		flashvars.urlPath = flashContentURL;
		flashvars.imgPath = flashPosterURL;

		if(flashVersion.major >= settings.version.split('.', 1)){
			flashPlaceholder.hide();
			elTarget.insert({ top:this.elFlashTarget });
	
			swfobject.embedSWF(settings.path, flashTarget, settings.width, settings.height, settings.version, settings.expressInstall, flashvars, params, attributes);
		}
	},
	detectMedia: function(elLnk){
		var targetTab = elLnk.readAttribute("href").replace(/.*#+/, ''),
			elTab = this.items;

		if($(this.mediaOptions.flashTargetID)){
			$(this.mediaOptions.flashTargetID).remove();
		}

		for(var i=0; i<elTab.length; i++){
			if(elTab[i].id == targetTab){
				var elTarget = $(elTab[i].id);
			}
		}

		if(elTarget.hasClassName(this.mediaOptions.audioVideoClass)){
			this.embedFlashPlayer(elTarget);
		}
	},
	updateFlashPlayer: function(elTab){
		var elTarget,
			elTabTarget = $$(elTab)[0];

		if($(this.mediaOptions.flashTargetID)){
			$(this.mediaOptions.flashTargetID).remove();
		}

		if(this.mediaOptions.elTabWrapper == elTabTarget){
			var elTabTarget = this.items;

			for(var i=0; i<elTabTarget.length; i++){
				if(elTabTarget[i].hasClassName('tab-on')){
					elTarget = elTabTarget[i];
				}
			}

			if(elTarget.hasClassName(this.mediaOptions.audioVideoClass)){
				this.embedFlashPlayer(elTarget);
			}
		}
	}
});
