/*
 * Moving Boxes v2.0.4
 * by Chris Coyier
 * http://css-tricks.com/moving-boxes/
 */

(function($){
    $.movingBoxes = function(el, options){
        // To avoid scope issues, use 'base' instead of 'this'
        // to reference this class from internal events and functions.
        var base = this;
		var stopSlide = false;

        // Access to jQuery and DOM versions of element
        base.$el = $(el).addClass('mb-slider');
        base.el = el;

        // Add a reverse reference to the DOM object
        base.$el.data('movingBoxes', base);

        base.init = function(){
            base.options = $.extend({}, $.movingBoxes.defaultOptions, options);

            // Setup formatting (to reduce the amount of initial HTML)
            base.$el.wrap('<div class="movingBoxes mb-wrapper"><div class="mb-scroll" /></div>');

            // defaults
            base.$window = base.$el.parent();
            base.$wrap = base.$window.parent()
            .css({
                width : base.options.width
            }) // override css width
            .prepend('<a class="mb-scrollButtons mb-left"></a>')
            .append('<a class="mb-scrollButtons mb-right"></a><div class="mb-left-shadow"></div><div class="mb-right-shadow"></div>');
            base.$panels = base.$el.find(base.options.panelType).addClass('mb-panel');
            base.runTime = $('.mb-slider').index(base.$el) + 1; // Get index (run time) of this slider on the page
            base.regex = new RegExp('slider' + base.runTime + '=(\\d+)', 'i'); // hash tag regex

            base.initialized = false;
            base.currentlyMoving = false;
            base.curPanel = 1;

            // code to run to update MovingBoxes when the number of panels change
            base.update();

            // Set up click on left/right arrows
            base.$wrap.find('.mb-right').click(function(){
                base.goForward();
                $(".current").prev().css({
                    opacity: 0.5
                });
                $(".current").next().css({
                    opacity: 0.5
                });
                $(".current").css({
                    opacity: 1
                });
                return false;
            }).end().find('.mb-left').click(function(){
                base.goBack();
                $(".current").prev().css({
                    opacity: 0.5
                });
                $(".current").next().css({
                    opacity: 0.5
                });
                $(".current").css({
                    opacity: 1
                });
                return false;
            });
			
			 base.$wrap.mouseover(function(){
				base.stopSlider(true);
			 });
			 
			  base.$wrap.mouseout(function(){
				base.stopSlider(false);
			 });

            // go to clicked panel
            base.$el.delegate('.mb-panel', 'click', function(){
                base.change( base.$panels.index($(this)) + 1 );
            });

            // Activate moving box on click or when an internal link obtains focus
            base.$wrap.click(function(){
                base.active();
            });
            base.$panels.delegate('a', 'focus' ,function(){
                // focused link centered in moving box
                var loc = base.$panels.index($(this).closest('.mb-panel')) + 1;
                if (loc !== base.curPanel){
                    base.change( base.$panels.index($(this).closest('.mb-panel')) + 1, {}, false );
                }
            });

            // Add keyboard navigation
            $(document).keyup(function(e){
                // ignore arrow/space keys if inside a form element
                if (e.target.tagName.match('TEXTAREA|INPUT|SELECT')) {
                    return;
                }
                switch (e.which) {
                    case 39: case 32: // right arrow & space
                        if (base.$wrap.is('.mb-active-slider')){
                            base.goForward();
                        }
                        break;
                    case 37: // left arrow
                        if (base.$wrap.is('.mb-active-slider')){
                            base.goBack();
                        }
                        break;
                }
            });

            // Set up "Current" panel
            var startPanel = (base.options.hashTags) ?  base.getHash() || base.options.startPanel : base.options.startPanel;

            // animate to chosen start panel - starting from the first panel makes it look better
            setTimeout(function(){
                base.change(startPanel, function(){

                    // Bind Events
                    $.each('initialized.movingBoxes initChange.movingBoxes beforeAnimation.movingBoxes completed.movingBoxes'.split(' '), function(i,o){
                        var evt = o.split('.')[0];
                        if ($.isFunction(base.options[evt])){
                    //base.$el.bind(o, base.options[evt]);
                    }
                    });

                    base.initialized = true;
                //base.$el.trigger( 'initialized.movingBoxes', [ base, startPanel ] );
                });
            }, base.options.speed );
            
            
            
            
            
        };
        
      
          

        base.update = function(){
            var t;
            // Set up panes & content sizes; default: panelWidth = 50% of entire width
            base.$panels = base.$el.find(base.options.panelType)
            .addClass('mb-panel')
            .css({
                width : 160
            })
            // inner wrap of each panel
            .each(function(){
                if ($(this).find('.mb-inside').length === 0) {
                    $(this).wrapInner('<div class="mb-inside" />');
                }
            });
            base.totalPanels = base.$panels.length;

            // save 'cur' numbers (current larger panel size), use stored sizes if they exist
            t = base.$panels.eq(base.curPanel - 1);
            base.curWidth = base.curWidth || t.outerWidth();
            base.curImgWidth = base.$panels.eq(base.curPanel).find('img').width();
            base.curImgHeight = base.$panels.eq(base.curPanel).find('img').height(); // set images fit a 4:3 ratio

            // save 'reg' (reduced size) numbers
            base.regWidth = base.curWidth * base.options.reducedSize;
            base.regImgWidth = base.curImgWidth * base.options.reducedSize ;
            base.regImgHeight = base.curImgHeight * base.options.reducedSize ;

            // set image heights so base container height is correctly set
            base.$panels
            .css({
                width:100, 
                fontSize: '1em'
            }) // make all panels big
            

            // save each panel height... script will resize container as needed
            base.heights = base.$panels.map(function(i,e){
                return $(e).outerHeight(true);
            }).get();

            base.returnToNormal(base.curPanel, true); // resize new panel
            base.growBigger(base.curPanel, true);

            // make base container wide enough to contain all the panels
            base.$el.css({
                position : 'absolute',
                // add a bit more width to each box (100px should cover margin/padding, etc; then add 1/2 overall width in case only one panel exists
                width    : (base.curWidth + 100 ) * base.totalPanels + (base.options.width - base.curWidth) / 2,
                height   : Math.max.apply( this, base.heights ) + 40
            });
            base.$window.css({
                height : "100px"
            });//(base.options.fixedHeight) ? Math.max.apply( this, base.heights ) : base.heights[base.curPanel-1]
            // add padding so scrollLeft = 0 centers the left-most panel (needed because scrollLeft cannot be < 0)
            //base.$panels.eq(0).css({ 'margin-left' : (base.options.width - base.curWidth) / 3 });
            base.$panels.eq(base.curPanel-1).css('opacity','0.5');
            base.$panels.eq(base.curPanel+1).css('opacity','0.5');
            //base.buildNav();
			

            //base.change(base.curPanel, {}, false); // initialize from first panel... then scroll to start panel
			
			var isrunningback = false;
            setInterval(function(){
				if(!stopSlide){
					if(base.curPanel < base.totalPanels && !isrunningback){
						base.goForward();
					}else{
						base.goBack(); 
						isrunningback = base.curPanel < 2 ? false :true;
					}
				}
			},2000); 
			
        };

        
		base.stopSlider = function(val){
			stopSlide=val;
		}
		
		
		// Resize panels to normal
        base.returnToNormal = function(num, quick){
            // wi=  alert(base.options.currentPanel);
            base.$panels.not(':eq(' + (num-1) + ')')
            .removeClass(base.options.currentPanel)
            .animate({
                width: base.regWidth, 
                fontSize: base.options.reducedSize + 'em'
            }, (quick) ? 0 : base.options.speed)
            .find('img').attr('style','');

        // alert( base.$panels.not(':eq(' + (num-1) + ')').find('.styler').attr('style')); 
        };

        // Zoom in on selected panel
        
        base.growBigger = function(num, quick){
            base.$panels.eq(num-1)
            .addClass(base.options.currentPanel)
            .animate({
                width: base.curWidth, 
                fontSize: '1.2em'
            }, (quick) ? 0 : base.options.speed)
            .find('img').animate({
                width: '+=10px', 
                height: '+=10px'
            }, (quick) ? 0 : base.options.speed, function(){
                // completed event trigger
                // even though animation is not queued, trigger is here because it is the last animation to complete
                if (base.initialized) {
                    base.$el.trigger( 'completed.movingBoxes', [ base, num ] );
                }
            });
        };

        // go forward/back
        base.goForward = function(){
            base.change(base.curPanel + 1);
        };

        base.goBack = function(){
            base.change(base.curPanel - 1);
        };

        // Change view to display selected panel
        base.change = function(curPanel, callback, flag){

            // make sure it's a number and not a string
            curPanel = parseInt(curPanel, 10);

            if (base.initialized) {
                // make this moving box active
                base.active();
                // initChange event - has extra parameter with targeted panel (not cleaned)
                base.$el.trigger( 'initChange.movingBoxes', [ base, curPanel ] );
            }

            // psuedo wrap - it's a pain to clone the first & last panel then resize them correctly while wrapping AND make it look good
            if ( base.options.wrap ) {
                if ( curPanel < 1 ) {
                    curPanel = base.totalPanels;
                }
                if ( curPanel > base.totalPanels ) {
                    curPanel = 1;
                }
            } else {
                if ( curPanel < 1 ) {
                    curPanel = 1;
                }
                if ( curPanel > base.totalPanels ) {
                    curPanel = base.totalPanels;
                }
            }

            // don't do anything if it's the same panel
            if (base.initialized && base.curPanel == curPanel && !flag) {
                return false;
            }

            // abort if panel is already animating
            if (!base.currentlyMoving) {
                base.currentlyMoving = true;

                // center panel in scroll window
                var ani, leftValue = base.$panels.eq(curPanel-1).position().left - (base.options.width - base.curWidth) / 2;
                // when scrolling right, add the difference of the larger current panel width
                if (curPanel > base.curPanel) {
                    leftValue -= ( base.curWidth - base.regWidth );
                }

                ani = (base.options.fixedHeight) ? {
                    scrollLeft : leftValue
                } : {
                    scrollLeft: leftValue, 
                    height: base.heights[curPanel - 1]
                };

                // before animation trigger
                if (base.initialized) {
                    base.$el.trigger( 'beforeAnimation.movingBoxes', [ base, curPanel ] );
                }

                // animate the panels
                base.$window.animate( ani,
                {
                    queue    : false,
                    duration : base.options.speed,
                    easing   : base.options.easing,
                    complete : function(){
                        base.curPanel = curPanel;
                        if (base.initialized) {
                            //								base.$panels.eq(curPanel - 1).find('a').focus();
                            base.$window.scrollTop(0); // Opera fix - otherwise, it moves the focus link to the middle of the viewport
                        }
                        base.currentlyMoving = false;
                        if (typeof(callback) === 'function') {
                            callback(base);
                        }
                        
                        $('.current').prev().css('opacity','0.5');
                        $('.current').css('opacity','1');
                        $('.current').next().css('opacity','0.5');
                    }
                }
                );

                base.returnToNormal(curPanel);
                base.growBigger(curPanel);
                if (base.options.hashTags && base.initialized) {
                    base.setHash(curPanel);
                }
            }
            base.$wrap.find('.mb-controls a')
            .removeClass(base.options.currentPanel)
            .eq(curPanel - 1).addClass(base.options.currentPanel);
            
        };

        // get & set hash tags
        base.getHash = function(){
            var n = window.location.hash.match(base.regex);
            return (n===null) ? '' : parseInt(n[1],10);
        };

        base.setHash = function(n){
            var s = 'slider' + base.runTime + "=",
            h = window.location.hash;
            if ( typeof h !== 'undefined' ) {
                window.location.hash = (h.indexOf(s) > 0) ? h.replace(base.regex, s + n) : h + "&" + s + n;
            }
        };

        // Make moving box active (for keyboard navigation)
        base.active = function(el){
            $('.mb-active-slider').removeClass('mb-active-slider');
            base.$wrap.addClass('mb-active-slider');
        };

        // get: var currentPanel = $('.slider').data('movingBoxes').currentPanel();  // returns # of currently selected/enlarged panel
        // set: var currentPanel = $('.slider').data('movingBoxes').currentPanel(2, function(){ alert('done!'); }); // returns and scrolls to 2nd panel
        base.currentPanel = function(panel, callback){
            if (typeof(panel) !== 'undefined') {
                base.change(panel, callback); // parse in case someone sends a string
            }
            return base.curPanel;
        };

        // Run initializer
        base.init();
        
       
        
    };

    $.movingBoxes.defaultOptions = {
        // Appearance
        startPanel   : 1,         // start with this panel
        width        : 800,       // overall width of movingBoxes
        panelWidth   : 0.5,       // current panel width adjusted to 50% of overall width
        reducedSize  : 0.8,       // non-current panel size: 80% of panel size
        imageRatio   : 4/3,       // Image ratio set to 4:3
        fixedHeight  : false,     // if true, slider height set to max panel height; if false, slider height will auto adjust.

        // Behaviour
        speed        : 500,       // animation time in milliseconds
        hashTags     : true,      // if true, hash tags are enabled
        wrap         : false,     // if true, the panel will "wrap" (it really rewinds/fast forwards) at the ends
        buildNav     : false,     // if true, navigation links will be added
        navFormatter : null,      // function which returns the navigation text for each panel
        easing       : 'swing',   // anything other than "linear" or "swing" requires the easing plugin

        // Selectors & classes
        currentPanel : 'current', // current panel class
        tooltipClass : 'tooltip', // added to the navigation, but the title attribute is blank unless the link text-indent is negative
        panelType    : '> div',   // selector to find the immediate (">") children "div" of the movingBoxes object)

        // Callbacks
        initialized     : null,   // callback when MovingBoxes has completed initialization
        initChange      : null,   // callback upon change panel initialization
        beforeAnimation : null,   // callback before any animation occurs
        completed       : null    // callback after animation completes
    };

    $.fn.movingBoxes = function(options, callback){
        var num, mb = this.data('movingBoxes');
        return this.each(function(){
            // initialize the slider but prevent multiple initializations
            if ((typeof(options)).match('object|undefined')){
                if (mb) {
                    mb.update();
                } else {
                    (new $.movingBoxes(this, options));
                }
            } else if (/\d/.test(options) && !isNaN(options) && mb) {
                num = (typeof(options) === "number") ? options : parseInt($.trim(options),10); // accepts "  4  "
                // ignore out of bound panels
                if ( num >= 1 && num <= mb.totalPanels ) {
                    mb.change(num, callback); // page #, autoplay, one time callback
                }
            }
        });
    };

    // Return the movingBoxes object
    $.fn.getMovingBoxes = function(){
        return this.data('movingBoxes');
    };

})(jQuery);
