/*
    jQuery - siteFeature Plugin
    @copyright Michael Kafka - http://codecanyon.net/user/makfak
    @version 2.7.5
*/
(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: '900px',                // sets the generated Container's width
        containerHeight: '265px',                // sets the generated Container's height
        imgWidth: '590px',                        // 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: 4,                                // sets the number of tabs before the overflow (int / null)
        startTab: 1,                            // sets the tab to be displayed onLoad
        txtBoxWidth: '185px',                    // sets the width of the Vertical TextBox
        txtBoxHorizontalHeight: '90px',            // sets the height of the Horizontal TextBox
        txtBoxOpacity: 0.5,                        // 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);
            
            // IE doesn't support array.indexOf so we have to fake it.
            // Otherwise the next 7 lines would be as simple as...
            // animationTransitions.splice(animationTransitions.indexOf(opts.imgBgsAnimationType), 1);
            var found = -1;
            for (var i = 0; i < animationTransitions.length; i++) {
                if (animationTransitions[i] == opts.imgBgsAnimationType) {
                    found = i;
                    break;
                }
            }
            animationTransitions.splice(found, 1);
            // end IE nonsense

            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', tcolWidth + "px").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;
            if(opts.imgBgsAnimationType == 'enterTheDragon'){
                $.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':'0'},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':'0'},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':'0'},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':'0'},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':'0'},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':'0'},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'){
            if($.browser.msie){
                var etdAni = 700;
            } else {
                var etdAni = opts.imgBgsAnimationDuration - 100;
            }

            $target.css({'opacity':'0'}).hide();
            $.each(order, function(i){
                pieces[this].animate({'background-position':pieces[this].data('bgPos-n')}, etdAni, function(){
                    if(i+1 == pieces.length){
                        order.sort( function(){return 0.5 - Math.random()} );
                        $.each(order, function(j){
                            pieces[this].animate({'letter-spacing':'0'},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.find('p').parent().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
        /*
            tabLock logic check: turn off the lock if...
                - the number of tabs is less than the lock -- so the tabs fill the vertical space 
                - the number of tabs is equal too the lock -- to prevent the scroll arrows
        */
        if(tabs.children().length <= opts.tabLock){
            opts.tabLock = 0;
        }
        if(!opts.tabLock){
            settings.calcdTabHeight = Math.round((parseInt(opts.containerHeight) / tabs.children().length) - (1 + (1 / tabs.children().length)));
        } else {
            settings.calcdTabHeight = Math.round((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.tabTriggers.data('offsetCount', 0);
            settings.tabTriggers.data('calcdTabHeight', settings.calcdTabHeight);

            settings.tabTriggers.hide().filter('#SF-n-prev').click(function(){
                if(tabs.children().length - opts.tabLock - settings.tabTriggers.data('offsetCount') != tabs.children().length - opts.tabLock){
                    tabs.animate({'top':'+=' + (settings.calcdTabHeight + 1)},500);
                    settings.tabTriggers.data('offsetCount', settings.tabTriggers.data('offsetCount') + 1);
                    return false;
                } else {
                    return false;    
                }
            }).end().filter('#SF-n-next').click(function(){
                if(tabs.children().length - opts.tabLock + settings.tabTriggers.data('offsetCount') != 0){
                    tabs.animate({'top':'-=' + (settings.calcdTabHeight + 1)},500);
                    settings.tabTriggers.data('offsetCount', settings.tabTriggers.data('offsetCount') - 1);
                    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({
                    'left' : obj[0].offsetLeft + (parseInt(opts.containerWidth) - ((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();
        
        // error check that the specified startTab isn't greater than the number of tabs
        if(opts.startTab > tabs.length || opts.startTab < 1){
            if(window.console && window.console.log){
                console.log('Your startTab value('+ opts.startTab +') isn\'t in range of the number of tabs(1 - '+ tabs.length +'). The first tab has been shown.');
            } else {
                alert('Your startTab value('+ opts.startTab +') isn\'t in range of the number of tabs(1 - '+ tabs.length +'). The first tab has been shown.');
            }
            opts.startTab = 1;
        }
        
        // 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'
                    });
                    tabUpdate(tabs, tabs.filter(hash), opts);
                    tabs.filter(hash).children('span').animate({'width':opts.tabsAnimateWidth}, opts.tabsAnimateInDuration).css({'display':'block'});
                    
                // 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').end().find(this.hash).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(':eq(' + (opts.startTab - 1) + ')').click();
        
        if($.browser.msie && $.browser.version == 6){
            if(txtBoxes.filter(':eq(' + (opts.startTab - 1) + ')').hasClass('horizontal')){
                txtBoxes.filter(':eq(' + (opts.startTab - 1) + ')').css({'height':opts.txtBoxHorizontalHeight});
            } else {
                txtBoxes.filter(':eq(' + (opts.startTab - 1) + ')').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);
                });
            }
            
        }
        
        // binds the events for changing the tabs on hover
        if(opts.tabControl == 'hover'){
            tabs.mouseover(function(){
	            if(settings.imgIsAnimating){
                    return false;
                }
                                    
                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'
                    });
                    tabUpdate(tabs, tabs.filter(hash), opts);
                    tabs.filter(hash).children('span').css({
                        'display':'block'
                    }).animate({
                        'width':opts.tabsAnimateWidth
                    },opts.tabsAnimateInDuration);
                }
                
                siteFeature.find('.selected').removeClass('selected').end().find(this.hash).addClass('selected');
            });
        } // end if HOVER
        
    } // end eventFeature()
    
    // this function allows the tabs to autoscroll during autoplay
    function tabUpdate(tabs, $t, opts){
        var tabTriggers = $('#' + opts.outputElementId + '-nav').children(),
            calcdTabHeight = tabTriggers.data('calcdTabHeight'),
            offsetCount = tabTriggers.data('offsetCount'),
            incomingIndex = tabs.index($t);

        if ( incomingIndex == 0 ) {
            tabs.parent().animate({'top':'0'},500);
            tabTriggers.data('offsetCount', 0);
        } else if ( incomingIndex + offsetCount == opts.tabLock ) {
            tabs.parent().animate({'top':'-=' + (calcdTabHeight + 1)},500);
            tabTriggers.data('offsetCount', offsetCount - 1);
        }
    }

/*
    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 = jQuery('.SF-' + id).find('#' + jQuery.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();
    }
}

