/**
 * Component: Oakley PromoShow
 * com.oakley
 *
 * (c) Copyright 2008 Oakley, Inc.
 *
 * @version 1.0.0, 06/25/2008
 * @author James Thomas <jmthomas@oakley.com>
 * @requires /js/mootools/mootools-1.2-core*.js
 * @requires /js/mootools/mootools-1.2-more*.js
 *
 */
var PromoShow = new Class({

	/**
	 * Creates an instance of the PromoShow class and initializes required properties
	 *
	 * @param strHtmlId String The HTML ID of the promo show instance
	 * @param fnAfterInit Function OPTIONAL - Call this function after initializing the simple zoomer
	 *
	 */
	initialize: function( strHtmlId, bUseTabs, fnAfterInit )
	{
		// Copy the values into this object
		this.strHtmlId = strHtmlId;

		if( bUseTabs == false )
		{
			this.bUseTabs = bUseTabs;
		}
		else
		{
			this.bUseTabs = true;
		}

		this.objData = new Object();
		this.objData.aryPromos = new Array();

		// Settings object
		this.objSettings = new Object();

		// Time, in seconds, to show each promo before auto advancing
		this.objSettings.intTimer = 5;

		// Time, in seconds, to keep a "clicked promo" up before auto advancing
		this.objSettings.intClickTimer = 10;

		// If set to true, the hovers will "fade" in and out
		this.objSettings.bHoverFade = false;

		// Create an effect for our "tabs border"
		if( this.bUseTabs )
		{
			tmpTabBorder = $( 'promo-tabs' );
			this.objData.objTabBorderEffect = new Fx.Morph( tmpTabBorder, { transition: Fx.Transitions.Sine.easeOut, link: 'chain' } );

			// Default the current tab to 0
			this.intCurrentTab = 0;
		}

		// The timer id
		this.intIntervalId = 0;

		this.intCurrentTab = 0;

		// If there was an "AfterInit" function passed, call it
		if( $chk( fnAfterInit ))
		{
			// Call the "AfterInit" function
			fnAfterInit();
		}
	},

	/**
	 * Adds a promo to the promo array
	 *
	 * @param strPromoIdAppend String The "second half" of the ID referencing this promo. ie, For promo-tab_02, you would give 02 as this value.
	 * @param strPromoBorderColor String The color of the border that surrounds the promo
	 *
	 * @param strColorDefaultBG String The color of the tab background in it's default state
	 * @param strColorDefaultBorder String The color of the tab border in it's default state
	 * @param strColorDefaultText String The color of the tab text in it's default state
	 *
	 * @param strColorHoverBG String The color of the tab background in it's hover state
	 * @param strColorHoverBorder String The color of the tab border in it's hover state
	 * @param strColorHoverText String The color of the tab text in it's hover state
	 *
	 * @param strColorSelectedBG String The color of the tab background in it's selected state
	 * @param strColorSelectedBorder String The color of the tab border in it's selected state
	 * @param strColorSelectedText String The color of the tab text in it's selected state
	 *
	 */
	addPromo: function( strPromoIdAppend, strPromoBorderColor, strColorDefaultBG, strColorDefaultBorder, strColorDefaultText, strColorHoverBG, strColorHoverBorder, strColorHoverText, strColorSelectedBG, strColorSelectedBorder, strColorSelectedText )
	{
		// Create the promo object
		objPromo = new Object();
		objPromo.strPromoIdAppend = strPromoIdAppend;
		objPromo.intZIndex = 4998 - this.objData.aryPromos.length;

		if( this.bUseTabs )
		{
			objPromo.strPromoBorderColor = strPromoBorderColor;

			// Default Tab Colors
			objPromo.strColorDefaultBG = strColorDefaultBG;
			objPromo.strColorDefaultBorder = strColorDefaultBorder;
			objPromo.strColorDefaultText = strColorDefaultText;

			// Hover Tab Colors
			objPromo.strColorHoverBG = strColorHoverBG;
			objPromo.strColorHoverBorder = strColorHoverBorder;
			objPromo.strColorHoverText = strColorHoverText;

			// Selected Tab Colors
			objPromo.strColorSelectedBG = strColorSelectedBG;
			objPromo.strColorSelectedBorder = strColorSelectedBorder;
			objPromo.strColorSelectedText = strColorSelectedText;

			// Create the effects for this tab
			objPromoTab = $( 'promo-tab_' + objPromo.strPromoIdAppend );
			objPromoTabLink = objPromoTab.getElement( 'a' );
			objPromo.objTabEffect = new Fx.Morph( objPromoTabLink, { duration: 'short', link: 'cancel' } );
		}

		// Create the effects for this tab
		objPromoImage = $( 'promo-main_' + objPromo.strPromoIdAppend );
		if( !this.bUseTabs )
		{
			objPromo.objImageEffect = new Fx.Morph( objPromoImage, { duration: 1, link: 'chain' } );
		}
		else
		{
			objPromo.objImageEffect = new Fx.Morph( objPromoImage, { link: 'chain' } );
		}

		// Add the promo to the data object
		this.objData.aryPromos.push( objPromo );
	},

	/**
	 * Starts the periodical timer to advance to the next promo
	 *
	 */
	startTimer: function()
	{
		this.intIntervalId = this.advancePromo.periodical( this.objSettings.intTimer * 1000, this );
	},

	/**
	 * Stops the periodical timer
	 *
	 */
	stopTimer: function()
	{
		this.intIntervalId = $clear( this.intIntervalId );
	},

	/**
	 * Puts a delay into the periodical timer
	 *
	 */
	clickTimer: function()
	{
		this.stopTimer();
		this.intIntervalId = this.startTimer.delay( ( this.objSettings.intClickTimer - this.objSettings.intTimer ) * 1000 , this )
	},

	/**
	 * Advances the PromoShow to the next tab
	 *
	 */
	advancePromo: function()
	{
		// Calculate the next tab
		intNextTab = this.intCurrentTab + 1;

		// If we're past the end...
		if( intNextTab >= this.objData.aryPromos.length )
		{
			// Then start at the beginning
			intNextTab = 0;
		}

		// Set the current tab/promo
		this.intCurrentTab = intNextTab;

		// Then refresh the PromoShow
		this.attach();
	},

	/**
	 * Chooses and displays a random tab
	 *
	 */
	randomPromo: function()
	{
		// Choose a random tab
		this.intCurrentTab = Math.floor( Math.random() * this.objData.aryPromos.length );

		// Fire it off
		this.attach();
	},

	/**
	 * Refreshes the tab actions and styles
	 *
	 */
	attach: function()
	{
		this.clearTabs();
		this.refreshTabActions();
		this.refreshTabStyles();
	},

	/**
	 * Replaces the select class with an internal variable
	 *
	 */
	clearTabs: function()
	{
		if( this.bUseTabs )
		{
			// Loop the promo data
			for( var i=0, intLen = this.objData.aryPromos.length; i < intLen; i++ )
			{
				// Grab the promo element
				objPromoData = this.objData.aryPromos[ i ];

				objPromoTab = $( 'promo-tab_' + objPromoData.strPromoIdAppend );

				// Remove the click events
				objPromoTab.removeEvents( 'mouseover' );
				objPromoTab.removeEvents( 'mouseout' );
				objPromoTab.removeEvents( 'click' );

				if( objPromoTab.hasClass( 'selected' ))
				{
					objPromoTab.removeClass( 'selected' );
					this.intCurrentTab = i;
				}
			}
		}
	},

	/**
	 * Removes all tab events, attaches appropriate new ones
	 *
	 */
	refreshTabActions: function()
	{
		if( this.bUseTabs )
		{
			// Loop the promo data
			for( var i=0, intLen = this.objData.aryPromos.length; i < intLen; i++ )
			{
				// Grab the promo element
				objPromoData = this.objData.aryPromos[ i ];

				objPromoTab = $( 'promo-tab_' + objPromoData.strPromoIdAppend );

				// Remove the click events
				objPromoTab.removeEvents( 'mouseover' );
				objPromoTab.removeEvents( 'mouseout' );
				objPromoTab.removeEvents( 'click' );

				if( this.intCurrentTab != i)
				{
					// Hover
					objPromoTab.addEvent( 'mouseover', this.handle_tabMouseToggle.bindWithEvent( this ));

					// Return to the "default" style
					objPromoTab.addEvent( 'mouseout', this.handle_tabMouseToggle.bindWithEvent( this ));

					// Add the click handler
					objPromoTab.addEvent( 'click', this.handle_tabClick.bindWithEvent( this ));
				}
			}
		}
	},

	/**
	 * Refreshes the look of the tabs
	 *
	 */
	refreshTabStyles: function()
	{
		// Loop the promo data
		for( var i=0, intLen = this.objData.aryPromos.length; i < intLen; i++ )
		{
			// Grab the promo element
			objPromoData = this.objData.aryPromos[ i ];
			objPromoImage = $( 'promo-main_' + objPromoData.strPromoIdAppend );

			if( this.bUseTabs )
			{
				objPromoTab = $( 'promo-tab_' + objPromoData.strPromoIdAppend );
				objPromoTabLink = objPromoTab.getElement( 'a' );
			}

			if( this.intCurrentTab == i)
			{
				// The tab is selected

				if( this.bUseTabs )
				{				
					// Morph the tab colors to the selected values for the current tab
					objPromoData.objTabEffect.start({
						'border-color': this.objData.aryPromos[ this.intCurrentTab ].strColorSelectedBorder,
						'color': this.objData.aryPromos[ this.intCurrentTab ].strColorSelectedText,
						'background-color': this.objData.aryPromos[ this.intCurrentTab ].strColorSelectedBG
					});

					// Morph the tab borders to the color for the current tab
					this.objData.objTabBorderEffect.start({
						'background-color': this.objData.aryPromos[ this.intCurrentTab ].strPromoBorderColor
					});
				}

				// Move the image to the top of the stack
				objPromoImage.setStyle( 'z-index', '4999' );

				// Fade the image in
				objPromoData.objImageEffect.start({
					'opacity': 1
				});
			}
			else
			{
				// The tab isn't selected

				if( this.bUseTabs )
				{
					// Morph the tab colors to the default values for the current tab
					objPromoData.objTabEffect.start({
						'border-color': this.objData.aryPromos[ this.intCurrentTab ].strColorDefaultBorder,
						'color': this.objData.aryPromos[ this.intCurrentTab ].strColorDefaultText,
						'background-color': this.objData.aryPromos[ this.intCurrentTab ].strColorDefaultBG
					});
				}

				// Move the image to it's starting position the stack
				objPromoImage.setStyle( 'z-index', objPromoData.intZIndex.toString() );

				// Fade the image out
				objPromoData.objImageEffect.start({
					'opacity': 0
				});
			}
		}
	},

	/**
	 * Handles mouseover / mouseout functions for the tabs
	 *
	 */
	handle_tabMouseToggle: function( objEvent )
	{
		objEvent = new Event( objEvent );

		// Pull the parent elem into a var
		objParent = objEvent.target.getParent();

		// Did we get an li element?
		if( objParent.get( "tag" ) == "li" )
		{
			// We did lets rename it
			objPromoTab = objParent;

			// Snag the tab link element
			objPromoTabLink = objPromoTab.getElement( 'a' );

			// Using the ID of the promo tab, we can get the "appended id" value
			strTabIdAppend = objPromoTab.id.split( "_" )[ 1 ];

			if( this.objSettings.bHoverFade )
			{
				// Find the moused over tab
				for( var i=0, intLen = this.objData.aryPromos.length; i < intLen; i++ )
				{
					// Does it match the appended id we found?
					if( this.objData.aryPromos[ i ].strPromoIdAppend == strTabIdAppend )
					{
						// It does, so assign it and break out of the loop
						intHoverTab = i;
						break;
					}
				}
			}

			if( objEvent.type == "mouseover" )
			{
				// Mouseover colors
				if( this.objSettings.bHoverFade && typeof( intHoverTab ) != 'undefined' )
				{
					this.objData.aryPromos[ intHoverTab ].objTabEffect.start({
						'border-color': this.objData.aryPromos[ this.intCurrentTab ].strColorHoverBorder,
						'color': this.objData.aryPromos[ this.intCurrentTab ].strColorHoverText,
						'background-color': this.objData.aryPromos[ this.intCurrentTab ].strColorHoverBG
					});
				}
				else
				{
					objPromoTabLink.setStyle( 'border-color', this.objData.aryPromos[ this.intCurrentTab ].strColorHoverBorder );
					objPromoTabLink.setStyle( 'color', this.objData.aryPromos[ this.intCurrentTab ].strColorHoverText );
					objPromoTabLink.setStyle( 'background-color', this.objData.aryPromos[ this.intCurrentTab ].strColorHoverBG );
				}

			}
			else
			{
				// Mouseout / default colors
				if( this.objSettings.bHoverFade && typeof( intHoverTab ) != 'undefined' )
				{
					this.objData.aryPromos[ intHoverTab ].objTabEffect.start({
						'border-color': this.objData.aryPromos[ this.intCurrentTab ].strColorDefaultBorder,
						'color': this.objData.aryPromos[ this.intCurrentTab ].strColorDefaultText,
						'background-color': this.objData.aryPromos[ this.intCurrentTab ].strColorDefaultBG
					});
				}
				else
				{
					objPromoTabLink.setStyle( 'border-color', this.objData.aryPromos[ this.intCurrentTab ].strColorDefaultBorder );
					objPromoTabLink.setStyle( 'color', this.objData.aryPromos[ this.intCurrentTab ].strColorDefaultText );
					objPromoTabLink.setStyle( 'background-color', this.objData.aryPromos[ this.intCurrentTab ].strColorDefaultBG );
				}
			}
		}
	},

	/**
	 * Handles the tab click which changes the selected tab and starts a timer
	 *
	 */
	handle_tabClick: function( objEvent )
	{
		// Stop the link from being followed
		objEvent = new Event( objEvent ).stop();

		// Stop the event from bubbling
		objEvent.stopPropagation();

		// Pull the parent elem into a var
		objParent = objEvent.target.getParent();

		// Did we get an li element?
		if( objParent.get( "tag" ) == "li" )
		{
			// We did lets rename it
			objClickedTab = objParent;

			// Snag the tab link element
			objClickedTabLink = objClickedTab.getElement( 'a' );

			// Using the ID of the promo tab, we can get the "appended id" value
			strTabIdAppend = objClickedTab.id.split( "_" )[ 1 ];

			// Find the data elements
			for( var i=0, intLen = this.objData.aryPromos.length; i < intLen; i++ )
			{
				// Does it match the appended id we found?
				if( this.objData.aryPromos[ i ].strPromoIdAppend == strTabIdAppend )
				{
					// It does, so assign it and break out of the loop
					this.intCurrentTab = i;
					break;
				}
			}

			this.attach();
			this.clickTimer();
		}

	}

});