/**
 * @fileoverview frozSimpleSlider plugin
 * @author Lawrence Natividad
 * @copyright Copyright ( c ) 2010 Frozynart Designs
 * @license Licensed under MIT ( http://www.frozynart.com/license/mit )
 * @version: 1.0 2010-03-05
 */
 
( function( $ ) {
    /**
     * When links are clicked or hovered on ( depending on options selected ), contents slide over accordingly
     * @namespace frozSimpleSlider Plugin Namespace
     * @requires jQuery 1.2.6 and above / jQuery Easing
     * @example jQuery( "#id-of-block-that-contains-links" ).frozSimpleSlider
     * @return {jQuery Object}
     */
    jQuery.fn.frozSimpleSlider = function( options ) {
        var opts                            = jQuery.extend( {}, jQuery.fn.frozSimpleSlider.defaults, options );
        jQuery.fn.frozSimpleSlider.opts     = opts;
        var $this                           = jQuery( this );

        var navMaster =         jQuery( $this ).attr( "id" );
        var navHeadContent =    "#" + opts.navHeadContent;
        var newWrapper =   navMaster + "-" + opts.wrapper;
        var wrapper =      "#" + newWrapper;

        jQuery( $this ).data( "linkNumber", 0 );
        jQuery( $this ).data( "slideNumber", 0 );
        jQuery( $this ).data( "currentPage", unescape( location.pathname ) );
        jQuery( $this ).data( "slideCount", jQuery( navHeadContent + " > div" ).length );
        jQuery( $this ).data( "return", true );
        jQuery( $this ).data( "timer", null );
        
        var idPrefix = navMaster;
        var idPrefixLen = idPrefix.length;

        /**
         * Detects which slide to start in
         *
         * @param void
         * @return void
         * @since 1.0
         */
        var detectStarter = function(){
            jQuery( "a", $this ).each( function(){
                jQuery( this ).attr( {id: idPrefix + ( jQuery( $this ).data( "linkNumber" ) )} );
                jQuery( $this ).data( "linkNumber", ( jQuery( $this ).data( "linkNumber" ) + 1 ) );
                if ( ( true === opts.autoDetectUrl ) ||
                   ( ( false === opts.autoDetectUrl ) && ( jQuery( this ).attr( "id" ) === ( idPrefix + 0 ) ) ) ){
                    if ( ( true === opts.autoDetectUrl ) ){
                        if ( jQuery( $this ).data( "currentPage" ).match( ( jQuery(  this  ).attr( "href" ) ) ) ){
                            setStarter( jQuery( this ).attr( "id" ) );
                            tabHighlight( jQuery( this, $this ), false );
                            tabHighlight( jQuery( this, $this ), true );
                        };
                    } else {
                        if ( jQuery( this ).attr( "id" ) === ( idPrefix + 0 ) ) {
                            setStarter( ( idPrefix + opts.selectedIndex ) );
                            tabHighlight( jQuery( this, $this ), false );
                            tabHighlight( jQuery( this, $this ), true );
                        }
                    };
                } else {
                    if ( jQuery( $this ).data( "currentPage" ).match( ( jQuery(  this  ).attr( "href" ) ) ) ){
                            setStarter( jQuery( this ).attr( "id" ) );
                            tabHighlight( jQuery( this, $this ), false );
                            tabHighlight( jQuery( this, $this ), true );
                    };
                };
            } );
        };

        /**
         * Sets the designated initial slide
         *
         * @param {String} initIndex Contains linkNumber and prependded idPrefix
         * @return void
         * @since 1.0
         */
        var setStarter = function( initIndex ){
            var initNumber = initIndex.substring( idPrefixLen );
            slideObject( initNumber, jQuery( $this ).data( "slideNumber" ) );
            $( navHeadContent ).stop( false, true );
        };

        /**
         * Highlights the presently selected link
         *
         * @param {Anchor} Anchor object of link to be highlighted
         * @return void
         * @since 1.0
         */
        var tabHighlight = function( link, returnTo ){
            jQuery( "a", $this ).each( function(){
                if ( false === returnTo ){
                    jQuery( this, $this ).removeClass( "froz-slider-slide-selected" );
                } else{
                    jQuery( this, $this ).removeClass( "froz-slider-slide-return" );
                };
            } );
            if ( false === returnTo ){
                link.addClass( "froz-slider-slide-selected" );
            } else{
                link.addClass( "froz-slider-slide-return" );
            }
        };

        /**
         * Determines which direction the contents should slide to
         *
         * @param {Int} newNumber Corresponding slideNumber to which the contents must slide to
         * @param {Int} currentNumber slideNumber of slide that is currently displayed
         * @return void
         * @since 1.0
         */
        var slideObject = function( newNumber, currentNumber ){
            if ( newNumber < currentNumber ){
               var difference = currentNumber - newNumber;
               if ( true === opts.slideVertical ){
                   slideUp( difference );
               }
               else{
                   slideBack( difference );
               };
               jQuery( $this ).data( "slideNumber", newNumber );
            }
            else if ( newNumber > currentNumber ){
               var difference = newNumber - currentNumber;
               if ( true === opts.slideVertical ){
                   slideDown( difference );
               }
               else{
                   slideForward( difference );
               };
               jQuery( $this ).data( "slideNumber", newNumber );
            };
        };

        /**
         * Animates the slides to slide backward
         *
         * @param {Int} diff slideNumber difference between current slide and new slide
         * @return void
         * @since 1.0
         */
        var slideBack = function( diff ){
            jQuery( navHeadContent ).animate( {"left": "+=" + ( diff * opts.displayWidth ) + "px"}, opts.slideEasing );
        };

        /**
         * Animates the slides to slide forward
         *
         * @param {Int} diff slideNumber difference between current slide and new slide
         * @return void
         * @since 1.0
        */
        var slideForward = function( diff ){
            jQuery( navHeadContent ).animate( {"left": "-=" + ( diff * opts.displayWidth ) + "px"}, opts.slideEasing );
        };

        /**
         * Animates the slides to slide upward
         *
         * @param {Int} diff slideNumber difference between current slide and new slide
         * @return void
         * @since 1.0
         */
        var slideUp = function( diff ){
            jQuery( navHeadContent ).animate( {"top": "+=" + ( diff * opts.displayHeight ) + "px"}, opts.slideEasing );
        };

        /**
         * Animates the slides to slide downward
         *
         * @param {Int} diff slideNumber difference between current slide and new slide
         * @return void
         * @since 1.0
         */
        var slideDown = function( diff ){
            jQuery( navHeadContent ).animate( {"top": "-=" + ( diff * opts.displayHeight ) + "px"}, opts.slideEasing );
        };
        
        var _globalTimer = null;

        var babyComeBack = function(){
            if ( null !== _globalTimer ) {
                _globalTimer.stop();
            }
            _globalTimer = jQuery.timer( opts.delayTime, function( timer ) {
                if ( opts.queueEffects === false ){
                    jQuery( navHeadContent ).stop( false, true );
                };
                if( jQuery( $this ).data( "return" )  === true ){
                    jQuery( "a", $this ).each( function(){
                        if ( jQuery( this, $this).hasClass( "froz-slider-slide-return" ) ){
                            if ( opts.queueEffects === false ){
                                jQuery( navHeadContent ).stop( false, true );
                            };
                            slideObject( jQuery( this, $this ).attr( "id" ).substring( idPrefixLen ), jQuery( $this ).data( "slideNumber" ) );
                            tabHighlight( jQuery( this, $this ), false );
                        };
                    });
                };
                timer.stop();
            });
            
            

            
        };





        /**
         * Initialization:<br>
         * Runs detectStarter<br>
         * Addition of wrapper block ( which will contain the slides )<br>
         * Specification of default CSS for wrapper block, navHeadContent block and each slide block
         *
         * @param void
         * @return void
         */
        jQuery( navHeadContent ).wrap( "<div id=" + newWrapper + " />" );
        jQuery( wrapper ).css( {position: "absolute",
                                     left: opts.wrapperPosX,
                                     top: opts.wrapperPosY,
                                     width:opts.displayWidth,
                                     height:opts.displayHeight,
                                     overflow:"hidden"} );
        if ( true === opts.slideVertical ){
            jQuery( navHeadContent ).css( {position: "relative",
                                           width:opts.displayWidth,
                                           height:jQuery( $this ).data( "slideCount" ) * opts.displayHeight} );
        } else {
            jQuery( navHeadContent ).css( {position: "relative",
                                           width:jQuery( $this ).data( "slideCount" ) * opts.displayWidth,
                                           height:opts.displayHeight} );
        }
        
        jQuery( navHeadContent + " > div" ).each( function(){
           jQuery( this ).css( {position:"relative", width: opts.displayWidth, height: opts.displayHeight, overflow:"hidden"} );
        } );

        if ( true === opts.slideVertical ){
            jQuery( navHeadContent + " > div" ).each( function(){
                jQuery( this ).css( {float:"top"} );
            } );
        }
        else{
            jQuery( navHeadContent + " > div" ).each( function(){
                jQuery( this ).css( {float:"left"} );
            } );
        }
        
        detectStarter();

        /**
         * Main function:<br>
         * Specifies the slide's behavior during hover and click events
         *
         * @param void
         * @return void
         * @since 1.0
         */

        jQuery( "a", $this ).each( function(){
            jQuery( this, $this ).click( function(){
                    slideObject( jQuery( this, $this ).attr( "id" ).substring( idPrefixLen ), jQuery( $this ).data( "slideNumber" ) );
                    tabHighlight( jQuery( this, $this ), false );
                    tabHighlight( jQuery( this, $this ), true );
                } );
        });

        //jQuery( navHeadContent + " > div" ).each( function(){
            jQuery( wrapper ).hover( function(){
                jQuery( $this ).data( "return", false );
            }, function(){
                jQuery( $this ).data( "return", true );
                babyComeBack();
            });
        //} );

        jQuery( "a", $this ).each( function(){
            if ( opts.hoverFunction === true ) {
                jQuery( this, $this ).hover( function(){
                    jQuery( $this ).data( "return", false );
                    if ( opts.queueEffects === false ){
                        jQuery( navHeadContent ).stop( false, true );
                    };
                    slideObject( jQuery( this, $this ).attr( "id" ).substring( idPrefixLen ), jQuery( $this ).data( "slideNumber" ) );
                    tabHighlight( jQuery( this, $this ), false );
                }, function(){
                    if ( true === opts.returnOnOut ){
                        jQuery( $this ).data( "return", true);
                        babyComeBack();
                    };
                });
            }
            else {
                jQuery( this, $this ).click( function(){
                    if ( opts.queueEffects === false ){
                        jQuery( navHeadContent, $this ).stop( false, true );
                    }
                    slideObject( jQuery( this, $this ).attr( "id" ).substring( idPrefixLen ), jQuery( $this ).data( "slideNumber" ) );
                    tabHighlight( jQuery( this, $this ), false );
                } );
            };
        });
        
        return $this;
    };

    /** 
     * Sends a message to the console
     * @private
     */
    var _debug = function( message ) {
        if ( true === jQuery.fn.frozSimpleSlider.opts.debug ) {
            console.log( message );
        }
    };
    
    /**
     * <pre> 
     * Settings
     *
     * Setting            Default            Description
     * ------------------------------------------------------------------------------------------
     * navHeadContent:    "header-content"   ID of block which contains slide contents
     * autoDetectUrl:     true               Specifies if starting slide is detected by URL
     * selectedIndex:     0                  Specifies default homepage slide
     *                                          ( if autoDetectUrl:false )
     * hoverFunction:     false              Specifies if slider will respond to mouseover event
     * slideVertical:     false              Specifies direction that contents will slide
     * displayWidth:      900                Width of each slide
     * displayHeight:     300                Height of each slide
     * wrapper:           "wrapper"          ID of block which contains slider
     * wrapperPosX:       0                  X-coordinate of wrapper block
     * wrapperPosY:       0                  Y-coordinate of wrapper block
     * slideEasing:       "easeInOutExpo"    Easing method
     * queueEffects:      false              Specifies if slider animations will be queued
     *                                          upon next command
     * returnOnOut:       true               Returns the slider to its original position if the
     *                                          cursor is pointed out of the link and content   
     *                                          ( if hoverFunction:true )
     * delayTime:         1000               Time it takes for the slide to return to its position
     *                                          ( if returnOnOut:true )
     * </pre>
     */
    jQuery.fn.frozSimpleSlider.defaults =   {
        navHeadContent: "header-content",
        autoDetectUrl:  true,
        selectedIndex:  0,
        hoverFunction:  false,
        slideVertical:  false,
        displayWidth:   900,
        displayHeight:  300,
        wrapper:        "wrapper",
        wrapperPosX:    0,
        wrapperPosY:    0,
		slideEasing:    "easeInOutExpo",
        queueEffects:   false,
        returnOnOut:    true,
        delayTime:      1000,
        debug:          false
    };
} )(jQuery);

