/*
 This plugin assumes this html structure:
 
 <div class="to-flips">
     <div class="content">
         <div class="block">
             PAGE 1
         </div>
         <div class="block">
             PAGE 2
         </div>
         <div class="block">
             PAGE 3
         </div>
     </div>
     <div class="navigation"></div>
 </div>
 
 and call it this way:
    $('.to-flips').flips(options)
    
 options:
    speed: 
      time of switch between 2 blocks, default 500ms
    
    autorun: 
      if more than 0, then blocks autmaticaly changes
      in this interval. Any interaction using navigation arrows
      stops autorun if stop_autorun set to true.
      
    stop_autorun:
      if set to true (default) then autorun is stopped after click
      on arrows. if false, then autorun is restarted a continue auto
      rotating.
      
    autorun_delay: 
      delay the start of autorun, default 0, allows to "cascade" more
      flips
      
    left_arrow: 
      html code to place inside navigation div for left arrow
      default is "&laquo;" - double left arrow
      
    right_arrow: 
      html code to place inside navigation div for left arrow
      default is "&raquo;" - double right arrow
      
    direction: 
      direction frow where new slide come from
      (default is 'right')
      
    items: 
      how man items to show together? default 1, take care of .block 
      size to exactly fit into .content container
 
*/

(function($){
    $.fn.flips = function(options) {
        
        // support multiple elements
        if (this.length > 1){
            this.each(function() { $(this).flips(options) });
            return this;
        }
        
        var defaults = {
            speed: 500,
            autorun: 5000,
            autorun_delay: 0,
            stop_autorun: false,
            left_arrow: '&laquo;',
            right_arrow: '&raquo;',
            direction: 'right',
            items: 1
        };

        // shortcut to call local functions
        var self = this;
        
        // instance variables
        var options = $.extend(defaults, options);
        var content, nav, offset, count, interval, itemStack=[], lock=false;
        
        this.initBlocks = function() {
            content = $('.content',self)
            $('.block',self).css('display','block')
            
            offset = -1;
            count = $('.block',content).length;
            
            page = 0
            
            $('.block',content).each( function() {
                $(this).wrapInner('<div class="in"></div')
                
                $(this).css('left','0px')
                $(this).css('top','0px')

                switch ( options.direction ) {
                    case 'left':
                        $(this).css('left', content.width() - $(this).width()*(page+1));
                        break;
                    case 'right':
                        $(this).css('left', $(this).width()*page);
                        break;
                    case 'top':
                        $(this).css('top',  content.height() - $(this).height()*(page+1));
                        break;
                    case 'bottom':
                        $(this).css('top',  $(this).height()*page);
                        break;
                }
                
                $(this).addClass('page'+(page++));
            });
            
            var childs = $('.block',content);
            
            for (var i=0; i<options.items; i++) {
                var c = childs[i];
                itemStack.push( c );
                $(c).show();
                offset++;
            }
            
            nav = $('.navigation',self)
        };
    
        this.prepareNavigation = function() {
            nav.append('<div class="btn-left"></div>')
            nav.append('<div class="btn-left-dis"></div>')
            nav.append('<div class="btn-right"></div>')
            nav.append('<div class="btn-right-dis"></div>')
            
            if (options.left_arrow!='') {
                $('.btn-left',nav).html( options.left_arrow );
                $('.btn-left-dis',nav).html( options.left_arrow );
            }

            if (options.right_arrow!='') {
                $('.btn-right',nav).html( options.right_arrow );
                $('.btn-right-dis',nav).html( options.right_arrow );
            }
            
            $('.btn-right',nav).click( function() { 
                self.stopAutorun();
                self.clickRight();
            });
            $('.btn-left',nav).click( function() {
                self.stopAutorun();
                self.clickLeft();
            });
        };

        this.clickRight = function(noClear) {
            if (lock) return;
            
            if ( offset>=count-1 ) {
                var next = $('.page0', content)
            } else {
                var next = $('.page'+(offset+1), content)   
            }

            var toMoveAnim = {};
            var nextAnim = {};
            
            for (var i=0; i<itemStack.length; i++) {
                var toMove = $(itemStack[i]);
                
                var pos = toMove.position();
                
                switch ( options.direction ) {
                    case 'left':
                        toMoveAnim = { left: pos.left + toMove.width() }
                        break;
                    case 'right':
                        toMoveAnim = { left: pos.left - toMove.width() }
                        break;
                    case 'top':
                        toMoveAnim = { top: pos.top + toMove.height() }
                        break;
                    case 'bottom':
                        toMoveAnim = { top: pos.top - toMove.height() }
                        break;
                }
                toMove.animate(toMoveAnim, options.speed, 'swing');
            }
            
            switch ( options.direction ) {
                case 'left':
                    next.css('left', -next.width())
                    nextAnim = { left: 0 }
                    break;
                case 'right':
                    next.css('left', content.width())
                    nextAnim = { left: next.position().left - next.width() }
                    break;
                case 'top':
                    next.css('top', -next.height())
                    nextAnim = { top: 0 }
                    break;
                case 'bottom':
                    next.css('top', content.height())
                    nextAnim = { top: next.position().top - next.height() }
                    break;
            }
            next.animate(nextAnim, options.speed, 'swing');
            
            itemStack.shift();
            itemStack.push(next);
                        
            if ( offset>=count-1 ) {
                offset = 0;
            } else {
                offset++;
            }
            
            self.lockClick();
            self.processArrows();
        };
        
        this.clickLeft = function() {
            if (lock) return;

            if ( offset-options.items < 0 ) {
                var next = $('.page' + (count + (offset-options.items) ), content);
            } else {
                var next = $('.page' + (offset - options.items), content);
            }

            var toMoveAnim = {};
            var nextAnim = {};
            
            for (var i=0; i<itemStack.length; i++) {
                var toMove = $(itemStack[i]);
                
                var pos = toMove.position();
                
                switch ( options.direction ) {
                    case 'left':
                        toMoveAnim = { left: pos.left - toMove.width() }
                        break;
                    case 'right':
                        toMoveAnim = { left: pos.left + toMove.width() }
                        break;
                    case 'top':
                        toMoveAnim = { top: pos.top - toMove.height() }
                        break;
                    case 'bottom':
                        toMoveAnim = { top: pos.top + toMove.height() }
                        break;
                }
                toMove.animate(toMoveAnim, options.speed, 'swing');
            }
            
            switch ( options.direction ) {
                case 'left':
                    next.css('left', content.width())
                    nextAnim = { left: next.position().left - next.width() }
                    break;
                case 'right':
                    next.css('left', -next.width())
                    nextAnim = { left: 0 }
                    break;
                case 'top':
                    next.css('top', content.height())
                    nextAnim = { top: next.position().top - next.height() }
                    break;
                case 'bottom':
                    next.css('top', -next.height())
                    nextAnim = { top: 0 }
                    break;
            }
            next.animate(nextAnim, options.speed, 'swing');
            
            itemStack.unshift(next);
            itemStack.pop();
            
            if ( offset==0 ) {
                offset = count-1;
            } else {
                offset--;
            }
            
            self.lockClick();
            self.processArrows();
        };
        
        this.processArrows = function() {
            if (options.items > 1) {
                $('.btn-left',nav).css('display','block');
                $('.btn-left-dis',nav).css('display','none');
                $('.btn-right',nav).css('display','block');
                $('.btn-right-dis',nav).css('display','none');
            } else {
                $('.btn-left',nav).css('display',       offset>0        ? 'block':'none');
                $('.btn-left-dis',nav).css('display',   offset==0       ? 'block':'none');
                $('.btn-right',nav).css('display',      offset<count-1  ? 'block':'none');
                $('.btn-right-dis',nav).css('display',  offset==count-1 ? 'block':'none');
            }
        };
        
        this.startAutorun = function() {
            interval = setInterval( self.clickRight, options.autorun);
        };

        this.stopAutorun = function() {
            clearInterval(interval); 
            if (!options.stop_autorun) {
                self.startAutorun();
            } 
        };

        this.lockClick = function() {
            lock = true;
            setTimeout( self.unlockClick, options.speed+50);
        };

        this.unlockClick = function() {
            lock = false;
        }
        
        this.initBlocks();
        this.prepareNavigation();
        this.processArrows();

        if (options.autorun > 0) {
            if (options.autorun_delay>0) {
                setTimeout( this.startAutorun, options.autorun_delay );
            } else {
                this.startAutorun();
            }
        }
    };
})(jQuery);