/*
	jQuery - siteFeature Plugin
	@copyright Michael Kafka - http://www.makfak.com
	@version 2.2
*/
(function($){

	$.fn.siteFeature = function(options) {
		var opts = $.extend({}, $.fn.siteFeature.defaults, options);

		return this.each(function(i) {
			obj = $(this);
			var settings = {};
				settings.which = i;
			// contains all DOM traversal and manipulation
			createFeature(opts,settings);
			// configures the Feature based on the options
			customizeFeature(opts,settings);
			// binds all associated events
			eventFeature(opts,settings);
		}); 
    }; // end $.fn.siteFeature

	// SiteFeature Customizable Options
	$.fn.siteFeature.defaults = {
		outputElementId: 'siteFeature',			// this is the ID given to the container div generated by siteFeature
		txtBoxIdPrefix: 'txtBox',				// creates the naming convention for the TextBox (ie: txtBoxContainer) 
		imgBgIdPrefix: 'imgBg',					// creates the naming convention for the ImageBackgounds (ie: imgBgContainer)
		tabIdPrefix: 'tab',						// creates the naming convention for the Tabs (ie: tabContainer)
		titleText: 'h3',						// identifies the Title Text for manipulation
		containerWidth: '710px',				// sets the generated Container's width
		containerHeight: '450px',				// sets the generated Container's height
		imgWidth: '430px',						// sets the width of the ImageBox/TextBox section. When subtracted from the Container's width - yields the Tabs width.
		tabsLocation: 'left',					// sets position of the Tabs (relative to the Image Box)
		tabBgImg: 'images/arrow-left.png',		// relative path for Image used as Highlighted Tab background (ie: the arrow)
		tabBgImgIE6: 'images/arrow-left.gif',	// relative path for Image used by IE6 (to prevent PNG alpha issues). Leave blank ('') or set to null to uses the same image (and to teach IE6 users a lesson).
		tabControl: 'click',					// sets the event that activates the tab change: 'click', 'hover'
		tabLock: 6,								// sets the number of tabs before the overflow (int / null)
		txtBoxWidth: '300px',					// sets the width of the Vertical TextBox
		txtBoxHorizontalHeight: '90px',			// sets the height of the Horizontal TextBox
		txtBoxOpacity: 0.9,						// sets the opcaity of the TextBox background (color set in CSS - default is #000000)
		activeTabIsLink: true,					// determines if the the Highlighted Tab is a link to said Tab's default destination (the original href)
		activeWindowIsLink: true,				// determines if the current ImageBackground and TextBox are links to the Tab's default destination (the original href)
		animateInOnLoad: true,					// determines if the Tab, ImageBackground, and TextBox animate In on page load or simply appear
		txtBoxAnimateInType: 'slideLeft',		// sets animation In type for vertical TextBoxes: 'blink', 'fade', 'slideUp', 'slideDown', 'slideLeft', 'slideRight'
		txtBoxAnimateOutType: 'slideRight',		// sets animation Out type for vertical TextBoxes: 'blink', 'fade', 'slideUp', 'slideDown', 'slideLeft', 'slideRight'
		txtBoxAnimateHorzAlt: true,				// allows horizontal txtBoxes to animate in/out differently
		txtBoxAnimateInHorzType: 'slideUp',		// sets animation In type for horizontal TextBoxes: 'blink', 'fade', 'slideUp', 'slideDown', 'slideLeft', 'slideRight'
		txtBoxAnimateOutHorzType: 'slideDown',	// sets animation Out type for horizontal TextBoxes: 'blink', 'fade', 'slideUp', 'slideDown', 'slideLeft', 'slideRight'
		txtBoxAnimateInDuration: 500,			// sets the duration for TextBox In animations (in milliseconds)
		txtBoxAnimateOutDuration: 500,			// sets the duration for TextBox Out animations (in milliseconds)
		txtBoxPauseBetweenInOut: 1000,			// sets the duration for the pause between the current TextBox animating Out and the new TextBox animating In ('0' for no delay) (in milliseconds)
		cols: 10,								// sets the number of columns used in the bgImg transitions
		rows: 5,								// sets the number of rows used in the bgImg transitions
		imgBgsAnimationDuration: 500,			// sets the duration for ImageBackground In animations (in milliseconds)
		imgBgsAnimateOutDuration: 500,			// sets the duration for ImageBackground Out animations (in milliseconds)
		imgBgsAnimationType: 'cycle',			// sets animation type: 'fade', 'wave', 'crash', 'curtain', 'zipper', 'fountain', 'cascade', 'dribble', 'checker', 'enterTheDragon', 'random', 'cycle'
		imgBgsAnimationList: ['fade', 'wave', 'crash', 'curtain', 'zipper', 'fountain', 'cascade', 'dribble', 'checker', 'enterTheDragon'],
		imgBgAnimationDirection: 'random',		// sets the start position of the transition: 'left', 'right', 'random'
		tabsAnimateInDuration: 100,				// sets the duration for Tab In animations (in milliseconds)
		tabsAnimateWidth: '+=20',				// sets the relative pixel width difference to be animated (to reveal the arrow)
		autoPlay: false,						// determines if the tabs cycle automatically
		autoPlayInterval: 5000,					// sets the autoPlay interval
		pauseOnHover: true,						// pause the autoPlay when hovering on siteFeature
		ieEnableFilters: false,					// adds a function to the end of every animation to remove IE filters (re-enables transparency)(boolean - true/false)
		endCreateFunction: null					// creates a userdefined Callback (with access to all plugin Options) that fires after everything has been written to the DOM but before events are bound.
	}; // end $.fn.siteFeature.defaults
	
	// The following 2 jQuery Extensions contain all of the custom In and Out animations for the txtBoxes.  
	$.fn.siteFeatureTxtBoxAnimationsOut = function(opts) {
		
		// checks if the current data is to be displayed Horizontally, whether it should be treated differently, and executes accordingly
		if( $(this).hasClass('horizontal') && opts.txtBoxAnimateHorzAlt ){
			var origAniStorage = opts.txtBoxAnimateOutType;
			opts.txtBoxAnimateOutType = opts.txtBoxAnimateOutHorzType
		}
		
		if(opts.txtBoxAnimateOutType == 'blink'){
			$(this).css({'opacity':'0','display':'none'});
		}
		
		if(opts.txtBoxAnimateOutType == 'fade'){
			$(this).animate({'opacity':'0'},opts.txtBoxAnimateOutDuration, function(){
				$(this).css({'display':'none'});
			});
		}
		
		if(opts.txtBoxAnimateOutType == 'slideUp'){
			if(!$(this).hasClass('horizontal')){
				$(this).stop().animate({'marginTop':'-' + opts.containerHeight},opts.txtBoxAnimateOutDuration, function(){
					$(this).css({'opacity':'0','margin-top':'0','display':'none'})
				});
			} else {
				$(this).css({'opacity':'1'}).slideUp(opts.txtBoxAnimateOutDuration, function(){
					$(this).css({'opacity':'0','display':'none'})
				});
			}
		}
		
		if(opts.txtBoxAnimateOutType == 'slideDown'){	
			$(this).stop().animate({'marginTop':opts.containerHeight},opts.txtBoxAnimateOutDuration, function(){
				$(this).css({'opacity':'0','margin-top':'0','display':'none'})
			});
		
		}
		
		if(opts.txtBoxAnimateOutType == 'slideLeft'){
			if(opts.tabsLocation == 'left'){
				if(!$(this).hasClass('horizontal')){
					$(this).css({'right':'auto','left':(parseInt(opts.imgWidth) - parseInt(opts.txtBoxWidth))})
						.children().each(function(){
							$(this).css({'width':$(this).width()});
						}).end()
						.css({'opacity':'1'}).stop().animate({'width':'0'},opts.txtBoxAnimateOutDuration, function(){
							$(this).css({'opacity':'0','width':opts.txtBoxWidth,'display':'none'});
						})
					;
				} else {
					$(this).children().each(function(){
						$(this).css({'width':$(this).width()});
					}).end()
					.css({'opacity':'1'}).stop().animate({'left':'-' + opts.imgWidth},opts.txtBoxAnimateOutDuration, function(){
						$(this).css({'opacity':'0','left':'0','display':'none'});
					});
				}	
			} else {
				$(this).css({'right':'auto','left':'0'}).stop().animate({'left':'-' + opts.imgWidth},opts.txtBoxAnimateOutDuration, function(){
					$(this).css({'opacity':'0','left':'0','display':'none'});
				});
			}
		}
		
		if(opts.txtBoxAnimateOutType == 'slideRight'){
			if(opts.tabsLocation == 'left'){
				if(!$(this).hasClass('horizontal')){
					$(this).css({'opacity':'1','left':'auto','right':'0'}).stop().animate({'right':'-' + opts.txtBoxWidth},opts.txtBoxAnimateOutDuration, function(){
						$(this).css({'opacity':'0','right':'0','display':'none'});
					});
				} else {
					$(this).css({'opacity':'1','left':'auto'}).stop().animate({'right':'-' + opts.imgWidth},opts.txtBoxAnimateOutDuration, function(){
						$(this).css({'opacity':'0','right':'0','display':'none'});
					});
				}
			} else {
				if(!$(this).hasClass('horizontal')){
					$(this).css({'left':'0px'}).stop().animate({'left':'-' + opts.txtBoxWidth},opts.txtBoxAnimateOutDuration, function(){
						$(this).css({'opacity':'0','display':'none','left':'0px'});
					});
				} else {
					$(this).css({'left':'0px'}).stop().animate({'left':'-' + opts.imgWidth},opts.txtBoxAnimateOutDuration, function(){
						$(this).css({'opacity':'0','display':'none','left':'0px'});
					});
				}
			}
		}
		
		// undoes the tempory Horizontal bindings.
		if( $(this).hasClass('horizontal') && opts.txtBoxAnimateHorzAlt ){
			opts.txtBoxAnimateOutType = origAniStorage;
		}
		return this;
	}; // end $.fn.siteFeatureAnimationsOut


	$.fn.siteFeatureTxtBoxAnimationsIn = function(opts) {
		// checks if the current data is to be displayed Horizontally, whether it should be treated differently, and executes accordingly
		if( $(this).hasClass('horizontal') && opts.txtBoxAnimateHorzAlt ){
			var origAniStorage = opts.txtBoxAnimateInType;
			opts.txtBoxAnimateInType = opts.txtBoxAnimateInHorzType
		}

		if(opts.txtBoxAnimateInType == 'blink'){
			$(this).animate({'opacity':'0'},opts.txtBoxPauseBetweenInOut, function(){
				$(this).css({'opacity':'1','display':'block'});
			});
		}
		
		if(opts.txtBoxAnimateInType == 'fade'){
			$(this).animate({'opacity':'0'},opts.txtBoxPauseBetweenInOut, function(){
				$(this).css({'display':'block'}).animate({'opacity':'1'},opts.txtBoxAnimateInDuration, function(){
					ieStyleFilterCleanup($(this), opts);
				});
			});
		}
		
		if(opts.txtBoxAnimateInType == 'slideUp'){
			$(this).animate({'opacity':'0'},opts.txtBoxPauseBetweenInOut, function(){
				$(this).css({'display':'block','opacity':'1','margin-top':opts.containerHeight}).animate({'marginTop':'0'},opts.txtBoxAnimateInDuration, function(){
					ieStyleFilterCleanup($(this), opts);
				});
			});
		
		}
		
		if(opts.txtBoxAnimateInType == 'slideDown'){
			if(!$(this).hasClass('horizontal')){
				$(this).animate({'opacity':'0'},opts.txtBoxPauseBetweenInOut, function(){
					$(this).css({'display':'block','opacity':'1','margin-top':'-' + opts.containerHeight}).animate({'marginTop':'0'},opts.txtBoxAnimateInDuration, function(){
						ieStyleFilterCleanup($(this), opts);
					});
				});
			} else {
				$(this).animate({'opacity':'0'},opts.txtBoxPauseBetweenInOut, function(){
					$(this).css({'display':'block','opacity':'1'}).slideUp(0).slideDown(opts.txtBoxAnimateInDuration, function(){
						ieStyleFilterCleanup($(this), opts);
					});
				});
			}
		}
		
		if(opts.txtBoxAnimateInType == 'slideLeft'){
			if(opts.tabsLocation == 'left'){
				if(!$(this).hasClass('horizontal')){
					$(this).animate({'opacity':'0'},opts.txtBoxPauseBetweenInOut, function(){
						$(this).css({'display':'block','opacity':'1','right':'-' + opts.txtBoxWidth}).animate({'right':'0'},opts.txtBoxAnimateInDuration, function(){
							ieStyleFilterCleanup($(this), opts);
						});
					});
				} else {
					$(this).animate({'opacity':'0'},opts.txtBoxPauseBetweenInOut, function(){
						$(this).css({'display':'block','opacity':'1','left':'auto','right':'-' + opts.imgWidth}).animate({'right':'0'},opts.txtBoxAnimateInDuration, function(){
							ieStyleFilterCleanup($(this), opts);
						});
					});
				}
			} else {
				if(!$(this).hasClass('horizontal')){
					$(this).animate({'opacity':'0'},opts.txtBoxPauseBetweenInOut, function(){
						$(this).css({'display':'block'}).children().each(function(){
							$(this).css({'width':$(this).width()});
						}).end()
						.css({'display':'block','opacity':'1','width':'0','left':'auto','right': parseInt(opts.imgWidth) - parseInt(opts.txtBoxWidth) })
						.animate({'width':opts.txtBoxWidth});
					});
				} else {
					$(this).animate({'opacity':'0'},opts.txtBoxPauseBetweenInOut, function(){
						$(this).css({'display':'block','opacity':'1','left':'auto','right':'-' + opts.imgWidth}).animate({'right':'0'},opts.txtBoxAnimateInDuration, function(){
							ieStyleFilterCleanup($(this), opts);
						});
					});
				}
			}
		}
		
		if(opts.txtBoxAnimateInType == 'slideRight'){
			if(opts.tabsLocation == 'left'){
				if(!$(this).hasClass('horizontal')){
					$(this).animate({'opacity':'0'},opts.txtBoxPauseBetweenInOut, function(){
						$(this).css({'display':'block','right':'auto','left':(parseInt(opts.imgWidth) - parseInt(opts.txtBoxWidth))})
						.children().each(function(){
							$(this).css({'width':$(this).width()});
						}).end()
						.css({'opacity':'1','width':'0'}).animate({'width':opts.txtBoxWidth},opts.txtBoxAnimateInDuration, function(){
							ieStyleFilterCleanup($(this), opts);
						});
					});
				} else {
					$(this).animate({'opacity':'0'},opts.txtBoxPauseBetweenInOut, function(){
						$(this).css({'display':'block','right':'auto','left':'-' + opts.imgWidth})
							.children().each(function(){
								$(this).css({'width':$(this).width()});
							}).end()
							.css({'opacity':'1'}).animate({'left':'0'},opts.txtBoxAnimateInDuration, function(){
								ieStyleFilterCleanup($(this), opts);
							});
					});
				}
			} else {
				$(this).animate({'opacity':'0'},opts.txtBoxPauseBetweenInOut, function(){
					$(this).css({'display':'block','opacity':'1','left':'-' + opts.imgWidth}).animate({'left':'0'},opts.txtBoxAnimateInDuration, function(){
						ieStyleFilterCleanup($(this), opts);
					});
				});
			}
		}
		
		// undoes the tempory Horizontal bindings.
		if( $(this).hasClass('horizontal') && opts.txtBoxAnimateHorzAlt ){
			opts.txtBoxAnimateInType = origAniStorage;
		}
		
		return this;
	}; // end $.fn.siteFeatureAnimationsIn

	// The following jQuery Extension contains the bgImg animations
	$.fn.siteFeatureImgAnimations = function(opts, settings, hash) {
		settings.imgIsAnimating = true;
		opts.width = parseInt(opts.imgWidth);
		opts.height = parseInt(opts.containerHeight);

		$imgs = $(this);
		if(opts.imgBgsAnimationType == 'random' || opts.animationMemory == 'random'){
			opts.animationMemory = 'random';
			var animationTransitions = opts.imgBgsAnimationList.slice(0);
			animationTransitions.splice(animationTransitions.indexOf(opts.imgBgsAnimationType), 1);
			animationTransitions.sort(function(){return 0.5 - Math.random()});
			opts.imgBgsAnimationType = animationTransitions[0];
		}
		
		if(opts.imgBgsAnimationType == 'cycle' || opts.animationMemory == 'cycle'){
			opts.animationMemory = 'cycle';
			for(i=0; i < opts.imgBgsAnimationList.length; i++){
				if(opts.imgBgsAnimationList[i] == opts.imgBgsAnimationType){
					opts.currentAni = i;
					break;
				} else {
					opts.currentAni = -1;
				}
			}
			//opts.currentAni = opts.imgBgsAnimationList.indexOf(opts.imgBgsAnimationType);
			if(opts.currentAni < 0 || opts.currentAni == opts.imgBgsAnimationList.length - 1){
				opts.currentAni = 0;
			} else {
				opts.currentAni++;
			}
			opts.imgBgsAnimationType = opts.imgBgsAnimationList[opts.currentAni];
		}
		
		if(opts.imgBgsAnimationType == 'enterTheDragon'){
			$target = $(this).filter('.selected');
			$current = $(this).filter(hash);
		} else {
			$target = $(this).filter(hash);
			$current = $(this).filter('.selected');
		}
		$copy = $target.clone();	

		// check animation direction
		if(opts.imgBgAnimationDirection == 'random'){
			opts.directionList = ['left','right'];
			opts.directionMemory = opts.directionList.sort(function(){return 0.5 - Math.random()})[0];
		} else {
			opts.directionMemory = opts.imgBgAnimationDirection;
		}
		
		var reeses = [];
		var pieces = [];
		var order = [];
			
		var colWidth = parseInt(opts.width / opts.cols);
		var rowHeight = parseInt(opts.height / opts.rows);
		var colGap = opts.width - (colWidth * opts.cols);
		var rowGap = opts.height - (rowHeight * opts.rows);
		var colLeft = 0;
		var rowTop = 0;
		var odd = 1;
		var timer = 0; 
		var time = opts.imgBgsAnimationDuration / 8;
		var multiplier = 1;

		// create the cols
		for (i=0; i < opts.cols; i++) {
						
			if(colGap > 0) {
				tcolWidth = colWidth + 1;
				colGap--;
			} else {
				tcolWidth = colWidth;
			}
			
			var eachCol = $target.clone().show().attr({'id':''}).addClass('col-'+i).css({
				'background-position': -colLeft +'px top',
				'width'   : tcolWidth + "px",
				'height'  : opts.height + "px",
				'float'   : 'left',
				'position': 'absolute',
				'left'    : colLeft
			});
			
			// Position the Columns for animating
			if(opts.imgBgsAnimationType == 'wave' || opts.imgBgsAnimationType == 'cascade'){
				eachCol.css({
					'height': 0
				});
			}
			
			if(opts.imgBgsAnimationType == 'fall'){
				eachCol.css({
					'top': opts.height * -1
				});
			}
			
			if(opts.imgBgsAnimationType == 'curtain'){
				eachCol.data('width', eachCol.css('width')).css({
					'width': 0
				});
			}
			
			if(opts.imgBgsAnimationType == 'zipper'){
				if( (i+1) % 2 == 0 ){
					eachCol.css({
						'top': opts.height
					});
				} else {
					eachCol.css({
						'top': opts.height * -1
					});
				}
			}
			
			if(opts.imgBgsAnimationType == 'fountain'){
				eachCol.css({
					'top': opts.height
				});				
			}
			
			if(opts.imgBgsAnimationType == 'crash' || opts.imgBgsAnimationType == 'dribble'){
				eachCol.css({
					'top': opts.height * -1
				});
			}
			
			if(opts.imgBgsAnimationType == 'checker'){
				eachCol.css({
					'background-image': 'none',
					'opacity': 1
				});				
			}
			
			if(opts.imgBgsAnimationType == 'enterTheDragon'){
				$current.css({
					'opacity': '1',
					'display':'block'
				});				
			}
			
			$current.append(eachCol[0]);
			pieces.push(eachCol);
			
			// create the rows
			if(opts.imgBgsAnimationType == 'checker'){
				for (j=0; j < opts.rows; j++) {
					
					if ( rowGap > 0) {
						trowHeight = rowHeight + 1;
						rowGap--;
					} else {
						trowHeight = rowHeight;
					}
					
					var eachRow = $target.clone().show().attr({'id':''}).addClass('row-'+i + '-' + j).css({
						'background-position': -colLeft +'px '+ -rowTop +'px',
						'height': 0,
						'width': 0,
						'float'   : 'left',
						'position': 'absolute',
						'left' : tcolWidth / 2,
						'top' : rowTop + (trowHeight / 2),
						'opacity':1
					}).data('info',{
						width : tcolWidth, 
						height : trowHeight,
						'left'    : 0,
						'top' : rowTop
					});
					
					$('.col-'+i).append(eachRow[0]);
					reeses.push(eachRow[0]);
					rowTop += trowHeight;
				}; // end for
				rowTop = 0;
			} // end if
			colLeft += tcolWidth;
		}; // end for

		// reorder for Checker
		if(opts.imgBgsAnimationType == 'checker'){
			if(opts.directionMemory == 'right'){
				var colPos = opts.cols - 1;
				var rowPos = 0;
				var memorize = opts.cols - 1;
				var offset_modifier = 1;
			} else {
				var colPos = 0;
				var rowPos = 0;
				var memorize = 0;
				var offset_modifier = 1;
			}
			
			for (i=0; i < reeses.length; i++) {
				if(opts.directionMemory == 'right'){
					if(colPos < 0){
						colPos = colPos + offset_modifier; 
						rowPos = rowPos + offset_modifier; 
						offset_modifier ++;
					}
					order[i] = colPos.toString() + '-' + rowPos.toString();
					if(colPos == opts.cols - 1 || rowPos >= opts.rows - 1){
						memorize --; 
						colPos = memorize; 
						rowPos = 0;
					} else {
						colPos ++; 
						rowPos ++;
					}
				} else {
					if(colPos > opts.cols - 1){
						colPos = colPos - offset_modifier; 
						rowPos = rowPos + offset_modifier; 
						offset_modifier ++;
					}
					order[i] = colPos.toString() + '-' + rowPos.toString();
					if(colPos == 0 || rowPos >= opts.rows - 1){
						memorize ++; 
						colPos = memorize; 
						rowPos = 0;
					} else {
						colPos --; 
						rowPos ++;
					}
				}
			};
			pieces = [];
			$.each(order, function(i){
				pieces.push( $(reeses).filter('[class$="-'+this+'"]') );
			});
		}

		// reorder for Fountain, Cascade, and Enter the Dragon
		if(opts.imgBgsAnimationType == 'fountain' || opts.imgBgsAnimationType == 'cascade' || opts.imgBgsAnimationType == 'dribble' || opts.imgBgsAnimationType == 'enterTheDragon'){
			var odd = 1;
			var middle = pieces.length / 2;
			
			for (i=0; i < pieces.length; i++) {
				mafs = middle - (parseInt((i+1)/2)*odd);
				order[i] = mafs;
				if(opts.imgBgsAnimationType == 'enterTheDragon'){
					if(i == 0){
						odd = 0;
					}					
					var $cur = $( pieces[ parseInt(order[i] - 1) ] );
					var offset = ($cur.width() / 2) * odd;
					if(odd < 0){
						$ref = $cur.prev();
					} else if(odd > 0) {
						$ref = $cur.next();	
					} else {
						$ref = $cur;
					}
					bgPos = parseInt( $ref.css('background-position') ) + offset;
					$cur.data('bgPos-o',$cur.css('background-position'))
						.css('background-position',bgPos + 'px 0px')
						.data('bgPos-n',bgPos + 'px 0px');
					if(i == 0){
						odd = 1;
					}					
				}
				odd *= -1;
			};
			order[opts.cols - 1] = 0;
			$.each(pieces,function(){
				$(this).css('background-position', $(this).data('bgPos-o'));
			});
		}		

		// check animation direction
		if(opts.directionMemory == 'right' && opts.imgBgsAnimationType != 'checker'){
			pieces.reverse();
		}
		
		// === Animations ===
		// fade
		if(opts.imgBgsAnimationType == 'fade'){
			$(this).filter('.selected')
				.animate({'opacity':'0'},opts.imgBgsAnimationDuration, function(){
					$(this).css({'display':'none'}).empty();
					settings.imgIsAnimating = false;
				})
				.end().filter(hash)
				.css({'display':'block'}).animate({'opacity':'1'},opts.imgBgsAnimationDuration)				
			;
		}
		
		// wave
		if(opts.imgBgsAnimationType == 'wave'){	
			$.each(pieces, function(i){
				$(this).animate({'letter-spacing':'normal'},timer,function(){
					$(this).animate({'opacity':'1','height':opts.height},opts.imgBgsAnimationDuration,function(){
						if((i + 1) == pieces.length){
							timer = 0;
							$target.css({'opacity':'1'}).show();
							$current.empty().css({'opacity':'0'}).hide();
							settings.imgIsAnimating = false;
						}
					});								 
				});
				timer = (timer * multiplier + time);
			});
		}
		
		// curtain
		if(opts.imgBgsAnimationType == 'curtain'){	
			$.each(pieces, function(i){
				$(this).animate({'letter-spacing':'normal'},timer,function(){
					$(this).animate({'opacity':'1','width':$(this).data('width')},opts.imgBgsAnimationDuration,function(){
						if((i + 1) == pieces.length){
							timer = 0;
							$target.css({'opacity':'1'}).show();
							$current.empty().css({'opacity':'0'}).hide();
							settings.imgIsAnimating = false;
						}
					});								 
				});
				timer = (timer * multiplier + time);
			});
		}

		// zipper & crash
		if(opts.imgBgsAnimationType == 'zipper' || opts.imgBgsAnimationType == 'crash'){	
			$.each(pieces, function(i){
				$(this).animate({'letter-spacing':'normal'},timer,function(){
					$(this).animate({'opacity':'1','top':'0'},opts.imgBgsAnimationDuration,function(){
						if((i + 1) == pieces.length){
							timer = 0;
							$target.css({'opacity':'1'}).show();
							$current.empty().css({'opacity':'0'}).hide();
							settings.imgIsAnimating = false;
						}
					});
				});
				timer = (timer * multiplier + time);
			});
		}

		// fountain & dribble
		if(opts.imgBgsAnimationType == 'fountain' || opts.imgBgsAnimationType == 'dribble'){
			$.each(order, function(i){
				pieces[this].animate({'letter-spacing':'normal'},timer,function(){
					$(this).animate({'opacity':'1','top':'0'},opts.imgBgsAnimationDuration,function(){
						if((i + 1) == pieces.length){
							timer = 0;
							$target.css({'opacity':'1'}).show();
							$current.empty().css({'opacity':'0'}).hide();
							settings.imgIsAnimating = false;
						}
					});								 
				});
				timer = (timer * multiplier + time);
			});
		}

		// cascade
		if(opts.imgBgsAnimationType == 'cascade'){
			$.each(order, function(i){
				pieces[this].animate({'letter-spacing':'normal'},timer,function(){
					$(this).animate({'opacity':'1','height':opts.height},opts.imgBgsAnimationDuration,function(){
						if((i + 1) == pieces.length){
							timer = 0;
							$target.css({'opacity':'1'}).show();
							$current.empty().css({'opacity':'0'}).hide();
							settings.imgIsAnimating = false;
						}
					});								 
				});
				timer = (timer * multiplier + time);
			});
		}

		// checker
		if(opts.imgBgsAnimationType == 'checker'){
			var time = opts.imgBgsAnimationDuration / 25;
			$.each(pieces, function(i){
				$(this).animate({'letter-spacing':'normal'},timer,function(){
					$(this).animate({
						'width' : $(this).data('info').width,
						'height' : $(this).data('info').height,
						'top' : $(this).data('info').top,
						'left' : $(this).data('info').left
					},opts.imgBgsAnimationDuration,function(){
						if((i + 1) == reeses.length){
							timer = 0;
							$target.css({'opacity':'1'}).show();
							$current.empty().css({'opacity':'0'}).hide();
							settings.imgIsAnimating = false;
						}
					});								 
				});
				timer = (timer * multiplier + time);
			});
		}

		// Enter the Dragon
		if(opts.imgBgsAnimationType == 'enterTheDragon'){
			$target.css({'opacity':'0'}).hide();
			$.each(order, function(i){
				pieces[this].animate({'background-position':pieces[this].data('bgPos-n')}, opts.imgBgsAnimationDuration - 100, function(){
					if(i+1 == pieces.length){
						order.sort( function(){return 0.5 - Math.random()} );
						$.each(order, function(j){
							pieces[this].animate({'letter-spacing':'normal'},timer,function(){
								$(this).animate({'top':opts.containerHeight},opts.imgBgsAnimationDuration, function(){
									if(j+1 == pieces.length){
										$current.empty();
										settings.imgIsAnimating = false;
									}
								});
							});
							timer = (timer * multiplier + time);
						});
					}
				});
			});
		}
		return this;
	}; // end $.fn.siteFeatureImgAnimations

	// clean-up IE style filters
	function ieStyleFilterCleanup(iescrub, opts){
		if($.browser.msie && opts.ieEnableFilters){
			iescrub.attr('style',iescrub.attr('style').replace(/filter+[^\;]*./gi, '')).children().each(function(){
				$(this).attr('style',$(this).attr('style').replace(/filter+[^\;]*./gi, ''))
			});
		}
	}

	// simple utility function to replicate jQuery's InnerHTML function but to include the containing Element
    function outerHTML(element) {
		return $('<div>').append( element.eq(0).clone() ).html();
	}

	// This function contains all of the DOM traversal and manipulation.  All part of Progressive Enhancement and Unobtrusive Javascript.
	function createFeature(opts,settings){
		
		// Injecting into the DOM wastes time. Write to memory (create a string) and inject once when finished
		var siteFeature;
		var txtBoxes = "<div id='" + opts.txtBoxIdPrefix + "Container'>";
		var imgBgs = "<div id='" + opts.imgBgIdPrefix + "Container'>";
		var tabs = "<div id='" + opts.tabIdPrefix + "Container'>";
		
		// allows a seperate "Arrow" image to be assigned to IE6 (to prevent transparency issues)
		if($.browser.msie && $.browser.version == 6){
			if(opts.tabBgImgIE6 != null || opts.tabBgImgIE6 != ''){
				opts.tabBgImg = opts.tabBgImgIE6;
			}
		}
		
		// Loop through each Item and create all necessary HTML
		obj.children().each(function(i){
			
			sfcurrent = $(this);
			cloned = sfcurrent.clone()
				.attr({id: opts.tabIdPrefix + i})
				.children('img').remove().end()
				.wrapInner('<div>')
				.prepend('<span></span>')
			;
			
			txtBoxes += outerHTML(cloned);
			imgBgs += '<div id="' + opts.tabIdPrefix + i + '" style="background-image:url(' + sfcurrent.find('img').attr('src') + '); width:' + opts.imgWidth + '; height:' + opts.containerHeight + ';"></div>';
			tabs += '<a href="#' + opts.tabIdPrefix + i + '" id="' + opts.tabIdPrefix + i + '"><span><span></span><img src="' + opts.tabBgImg + '"/></span><h4>' + sfcurrent.find('h3').text() + '</h4><p>' + sfcurrent.find('img').attr('title') + '</p></a>';

		}); // end Each

		txtBoxes += "</div>";
		imgBgs += "</div>";
		tabs += "</div>";
		siteFeature = (imgBgs + txtBoxes + tabs);
		
		// Clear the current HTML and inject the siteFeature HTML
		obj.empty().attr({'id':opts.outputElementId,'class':opts.tabsLocation}).css({'width':opts.containerWidth,'height':opts.containerHeight}).append(siteFeature);
		obj.addClass('SF-' + settings.which);
		
		// Callback for DOM manipulation before event binding
		if($.isFunction(opts.endCreateFunction)){
			opts.endCreateFunction.apply(this, [opts]);
		}
	} // end createFeature()

	// This is the function that customizes the recently inject HTML based on the plugin options
	function customizeFeature(opts,settings){
		var txtBoxes = $('#' + opts.txtBoxIdPrefix + 'Container',obj);
		var imgBgs = $('#' + opts.imgBgIdPrefix + 'Container',obj);
		var tabs = $('#' + opts.tabIdPrefix + 'Container',obj);
		
		// style the Images
		imgBgs.css({'width':opts.imgWidth,'height':opts.containerHeight});
		
		// style the tabs
		if(!opts.tabLock){
			settings.calcdTabHeight = (parseInt(opts.containerHeight) / tabs.children().length) - (1 + (1 / tabs.children().length));
		} else {
			settings.calcdTabHeight = (parseInt(opts.containerHeight) / opts.tabLock) - (1 + (1 / tabs.children().length));
			settings.tabTriggers = obj.after('<div id="' + opts.outputElementId + '-nav"><a href="#" id="SF-n-prev"><i>prev</i></a><a href="#" id="SF-n-next"><i>next</i></a></div>').next().children();
			settings.offsetCount = 0;
	
			settings.tabTriggers.hide().filter('#SF-n-prev').click(function(){
				if(tabs.children().length - opts.tabLock - settings.offsetCount != tabs.children().length - opts.tabLock){
					tabs.animate({'top':'+=' + (settings.calcdTabHeight + 1)},500);
					settings.offsetCount++;
					return false;
				} else {
					return false;	
				}
			}).end().filter('#SF-n-next').click(function(){
				if(tabs.children().length - opts.tabLock + settings.offsetCount != 0){
					tabs.animate({'top':'-=' + (settings.calcdTabHeight + 1)},500);
					settings.offsetCount--;
					return false;
				} else {
					return false;
				}
			}).end().hover(function(){
				settings.overTriggers = true;
			}, function(){
				settings.overTriggers = false;
				$(this).animate({'azimuth':'0'}, 200, function(){
					if(!settings.overTabs){
						settings.tabTriggers.fadeOut(350);
					}
				});
			});
			
			
			settings.tabTriggers.filter('#SF-n-prev').css({
				'top' : obj[0].offsetTop - settings.tabTriggers.filter('#SF-n-prev').height() - 1
			}).end().filter('#SF-n-next').css({
				'top' : obj[0].offsetTop + obj.height()
			});
			
			if(opts.tabsLocation == 'left'){
				settings.tabTriggers.css({
					'left' : obj[0].offsetLeft + ((parseInt(opts.containerWidth) - parseInt(opts.imgWidth)) / 2) - (settings.tabTriggers.filter('#SF-n-prev').width() / 2)
				});
			} else {
				settings.tabTriggers.css({
					'right' : obj[0].offsetLeft + ((parseInt(opts.containerWidth) - parseInt(opts.imgWidth)) / 2) - (settings.tabTriggers.filter('#SF-n-prev').width() / 2)
				});
			}
			
			tabs.hover(function(){
				settings.overTabs = true;
				if(!settings.overTriggers){
					settings.tabTriggers.fadeIn(350);
				}
			}, function(){
				settings.overTabs = false;
				$(this).animate({'azimuth':'0'}, 200, function(){
					if(!settings.overTriggers){
						settings.tabTriggers.fadeOut(350);
					}
				});
			});
			
		}
		
		tabs.children().css({
			'width':(parseInt(opts.containerWidth) - parseInt(opts.imgWidth)),
			'height':settings.calcdTabHeight
		}).children('span').css({
			'width':(parseInt(opts.containerWidth) - parseInt(opts.imgWidth)),
			'height':settings.calcdTabHeight
		}).children('img').css({
			'left':( (opts.tabsLocation == 'left') ? parseInt(opts.containerWidth) - parseInt(opts.imgWidth) : '0' )
		}).prev().css({
			'width':(parseInt(opts.containerWidth) - parseInt(opts.imgWidth))
		});
		
		// style the text boxes
		txtBoxes
			.css({'width':opts.imgWidth,'height':opts.containerHeight})
			.children('div:not(.horizontal)').css({'width':opts.txtBoxWidth,'height':'100%'}).end()
			.children('div.horizontal').css({'width':opts.imgWidth,'height':opts.txtBoxHorizontalHeight,'top':(parseInt(opts.containerHeight) - parseInt(opts.txtBoxHorizontalHeight)),'left':'0px'}).end()
			.find('div span').css({'opacity':opts.txtBoxOpacity}).next().css({'opacity':'1'})
		;
	} // end customizeFeature()
	
	
	// This function binds all associated events
	function eventFeature(opts,settings){
		var siteFeature = obj;
		var txtBoxes = $('#' + opts.txtBoxIdPrefix + 'Container',obj).children();
		var imgBgs = $('#' + opts.imgBgIdPrefix + 'Container',obj).children();
		var tabs = $('#' + opts.tabIdPrefix + 'Container',obj).children();
		
		// to streamline the number of events and conditions... there is only one Click event and it gets called onLoad
		// all methods are chained... we begin with "all txtBoxes / imgBgs / tabs", then we filter to just the 'selected' item, animated it Out, revert back to the
		// "all txtBoxes / imgBgs / tabs" selector, filter to that which matches the clicked Tab, animate it In.
		// FYI: "this.hash" = is a great way to match an href (href="#item") with an element with a matching id (id="item"). It's the foundation for the tabbing used here. 

		tabs.click(function(e){
			// prevent crashing by overloading the queue
			if(settings.imgIsAnimating){
				return false	
			}
			// quick check to determine if this onLoad (the class 'selected' hasn't been set yet - happens onLoad)
			if(!tabs.hasClass('selected')){
				// if onLoad animations are turned on
				if(opts.animateInOnLoad){
					txtBoxes.css({'opacity':'0','display':'none'})
						.filter(this.hash)
						.siteFeatureTxtBoxAnimationsIn(opts)
					;
					
					imgBgs.css({'opacity':'0','display':'none'})
						.filter(this.hash)
						.css({'display':'block'}).animate({'opacity':'1'},opts.imgBgsAnimationDuration,null)
					;
					
					tabs.filter(this.hash).children('span')
						.animate({'width':opts.tabsAnimateWidth},opts.tabsAnimateInDuration,null)
					;
				// if onLoad animations are turned off
				} else {
					txtBoxes.css({'opacity':'0','display':'none'})
						.filter(this.hash)
						.css({'opacity':'1','display':'block'})
					;
					
					imgBgs.css({'opacity':'0','display':'none'})
						.filter(this.hash)
						.css({'opacity':'1','display':'block'})
					;
					
					tabs.filter(this.hash).children('span')
						.animate({'width':opts.tabsAnimateWidth},0,null)
					;
				}
			// the following are called onClick (as opposed to onLoad)
			} else {
				// seperates a click to load a new tab v. a click on the current tab visit the original link
				if(!$(this).hasClass('selected')){
					var hash = this.hash;
					txtBoxes.filter('.selected')
						.siteFeatureTxtBoxAnimationsOut(opts)
						.end().filter(this.hash)
						.siteFeatureTxtBoxAnimationsIn(opts)
					;
					
					imgBgs.siteFeatureImgAnimations(opts, settings, this.hash);
					
					tabs.filter('.selected').children('span').css({
							'width':(parseInt(opts.containerWidth) - parseInt(opts.imgWidth)),
							'display':'none'
						}).end().end()
						.filter(this.hash).children('span').animate({'width':opts.tabsAnimateWidth},opts.tabsAnimateInDuration)
					;

				// the tab clicked is already open - trigger the original link
				} else {
					
					if(opts.activeTabIsLink){
						window.location = txtBoxes.filter(this.hash).find('a').attr('href');
						return false;
					}
					
				}
				
			}
			siteFeature.find('.selected').removeClass('selected');
			siteFeature.find(this.hash).each(function(){
				$(this).addClass('selected');
			});
			return false;
		// the ".filter(':first').click()" is a chaining method for triggering an event onLoad but only after it has been bound.
		// in this case... after the click has been bound to the Tabs, click the first Tab in the selector list. 
		}).filter(':first').click();
		
		if($.browser.msie && $.browser.version == 6){
			if(txtBoxes.filter(':first').hasClass('horizontal')){
				txtBoxes.filter(':first').css({'height':opts.txtBoxHorizontalHeight});
			} else {
				txtBoxes.filter(':first').css({'height':opts.containerHeight});
			}
		}

		
		// binds a click to the ImgBg that calls the original link
		if(opts.activeWindowIsLink){
			$('#' + opts.txtBoxIdPrefix + 'Container').css({'cursor':'pointer'}).click(function(e){
				if(e.target.tagName == 'A'){
					return true;
				} else {
					var hash = tabs.filter('.selected').attr('href');
					var hashMark = hash.lastIndexOf('#');
					hash = hash.substring(hashMark, hash.length);
					window.location = txtBoxes.filter(hash).find('a').attr('href');
					return false;
					
				}
			});
		}
		
		// binds the AutoPlay
		if(opts.autoPlay){
			SiteFeatureAutoPlayInterval['which'+settings.which] = setInterval("siteFeatureAutoPlayer(" + settings.which + ")",opts.autoPlayInterval);
			
			if(opts.pauseOnHover){
				obj.hover(function(){
					clearInterval(SiteFeatureAutoPlayInterval['which'+settings.which]);
				},function(){
					SiteFeatureAutoPlayInterval['which'+settings.which] = setInterval("siteFeatureAutoPlayer(" + settings.which + ")",opts.autoPlayInterval);
				});
			}
			
		}
		
		if(opts.tabControl == 'hover'){
			tabs.mouseover(function(){
									
				if(!$(this).hasClass('selected')){
					var hash = this.hash;
					txtBoxes.filter('.selected')
						.siteFeatureTxtBoxAnimationsOut(opts)
						.end().filter(this.hash)
						.siteFeatureTxtBoxAnimationsIn(opts)
					;
					
					imgBgs.siteFeatureImgAnimations(opts, settings, this.hash);
					
					tabs.filter('.selected').children('span').css({
							'width':(parseInt(opts.containerWidth) - parseInt(opts.imgWidth)),
							'display':'none'
						}).end().end()
						.filter(this.hash).children('span').animate({'width':opts.tabsAnimateWidth},opts.tabsAnimateInDuration)
					;
				}
				
				siteFeature.find('.selected').removeClass('selected');
				siteFeature.find(this.hash).each(function(){
					$(this).addClass('selected');
				});
				
			});
		} // end if HOVER
		
	} // end eventFeature()

/*
	jQuery Background Position Effect Plugin
	http://plugins.jquery.com/project/backgroundPosition-Effect
	http://www.protofunc.com/scripts/jquery/backgroundPosition/
	@author Alexander Farkas
	v. 1.21
	Liscenses: MIT, GPL
*/
	if(!document.defaultView || !document.defaultView.getComputedStyle){ // IE6-IE8
		var oldCurCSS = jQuery.curCSS;
		jQuery.curCSS = function(elem, name, force){
			if(name === 'background-position'){
				name = 'backgroundPosition';
			}
			if(name !== 'backgroundPosition' || !elem.currentStyle || elem.currentStyle[ name ]){
				return oldCurCSS.apply(this, arguments);
			}
			var style = elem.style;
			if ( !force && style && style[ name ] ){
				return style[ name ];
			}
			return oldCurCSS(elem, 'backgroundPositionX', force) +' '+ oldCurCSS(elem, 'backgroundPositionY', force);
		};
	}
	var oldAnim = $.fn.animate;
	$.fn.animate = function(prop){
		if('background-position' in prop){
			prop.backgroundPosition = prop['background-position'];
			delete prop['background-position'];
		}
		if('backgroundPosition' in prop){
			prop.backgroundPosition = '('+ prop.backgroundPosition;
		}
		return oldAnim.apply(this, arguments);
	};
	
	function toArray(strg){
		strg = strg.replace(/left|top/g,'0px');
		strg = strg.replace(/right|bottom/g,'100%');
		strg = strg.replace(/([0-9\.]+)(\s|\)|$)/g,"$1px$2");
		var res = strg.match(/(-?[0-9\.]+)(px|\%|em|pt)\s(-?[0-9\.]+)(px|\%|em|pt)/);
		return [parseFloat(res[1],10),res[2],parseFloat(res[3],10),res[4]];
	}
	
	$.fx.step. backgroundPosition = function(fx) {
		if (!fx.bgPosReady) {
			var start = $.curCSS(fx.elem,'backgroundPosition');
			
			if(!start){//FF2 no inline-style fallback
				start = '0px 0px';
			}
			
			start = toArray(start);
			
			fx.start = [start[0],start[2]];
			
			var end = toArray(fx.options.curAnim.backgroundPosition);
			fx.end = [end[0],end[2]];
			
			fx.unit = [end[1],end[3]];
			fx.bgPosReady = true;
		}
		//return;
		var nowPosX = [];
		nowPosX[0] = ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit[0];
		nowPosX[1] = ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit[1];           
		fx.elem.style.backgroundPosition = nowPosX[0]+' '+nowPosX[1];

	};	
// end Background Position Animation Plugin

})(jQuery);

// this is the AutoPlay function
var SiteFeatureAutoPlayInterval = [];
function siteFeatureAutoPlayer(id){
	var tabs = $('.SF-' + id).find('#' + $.fn.siteFeature.defaults.tabIdPrefix + 'Container').children();
	if( (tabs.length - 1) == tabs.index(tabs.filter('.selected'))){
		tabs.filter(':first').click();
	} else {
		tabs.filter('.selected').next().click();
	}
}

