/**
 * jQuery Multiple Elements Cycle Plugin.
 *
 * Provides a simple preview scrolling panel. Shows the given range of li items from the middle and
 * allows scrolling left and right within the list. Does not handle automatic scrolling / time based
 * or wrapping items around. 
 *
 * Note $.multipleElementsCycle needs to be called on a div containing a ul rather then the actual ul
 *
 * Copyright 2011, Will Rossiter <will.rossiter@gmail.com>
 * Released under the BSD License.
 *
 * Version: 1.0
 */
(function($) {

    var show = $.fn.show, hide = $.fn.hide;

    $.fn.showw = function() {
        //if ( window.console ) //console.log('visi')
        this.css('visibility', 'visible');
    }

    $.fn.hidee = function() {
        //if ( window.console ) //console.log('hide')
        this.css('visibility', 'hidden');
    }

    $.fn.multipleElementsCycle = function(opts){


        //if ( window.console ) console.log('invoked!!@@@')
        
        /**
         * Setup default configuration options. To override any of these
         * options pass in the object to the multipleElementsCycle call
         * 
         * $("#container").multipleElementsCycle({
         *              show: 5,
         *              container: ".test"
         * });
         */
        var defaults = {
            container: '#cycle',        // Selector for element (ul) container (selector)
            prev: '#cycle-prev',        // Selector to scroll previous (selector)
            next: '#cycle-next',        // Selector to scroll next (selector)
            speed: 500,                         // Speed to scroll elements (int)
            containerSize: false,       // Override default size (int, px)
            show: 4,                            // Items to show from the list (int)
            start: false,                       // Override the start with a defined value (int)
            jumpTo: false,                      // Selectors to use as jump list
            vertical: false,            // Whether Scroll is for vertical
            scrollCount: 1,                     // How many elements to scroll when clicking next / prev,
            element: "li",                      // Element which is cycled. Update this and parent (selector)
            parent: "ul",                        // Parent element which contains the elements (selector)
            event: 'initial'
        };
        
        var opts = $.extend(defaults, opts);
                
        return this.each(function() {

            var self = $(this), maxIndex, lowerIndex, upperIndex, size, margin, elements;

            function actions() {

                //if ( window.console ) //console.log('actions invoked')
            
                elements = self.find(opts.element);

                //alert( self.find )
                //alert( opts.element )
                //alert( elements )

                //alert( typeof self.find )
                //alert( self.find )

                //alert( opts.element )

                window.goku = self;

                window.els = elements;

                //alert( elements.length-1 )
                maxIndex = elements.length - 1;
                window.max = maxIndex;

                //alert( 'calc is ' + self.find(opts.element).length -1 )
                //alert( 'maxIndex is ' + maxIndex )
                
                // Calculate the start index. It will either work it out automatically based
                // on the length of the list or use the provided opts.start value
                lowerIndex = (opts.start === false) ? Math.floor((maxIndex - opts.show + 1) / 2) : opts.start;
                upperIndex = lowerIndex + opts.show;
                window.upp = upperIndex;
                window.opts = opts;
                size = (opts.vertical === false) ? elements.outerWidth(true) : elements.outerHeight(true);
                margin = ((lowerIndex) * size) * -1;

                // Hide the arrows if we are at the bounds
                if(upperIndex >= elements.length) {
                    $(opts.next).hidee()
                } else {
                    $(opts.next).showw()
                    $(opts.next).trigger('click')
                }

                if(lowerIndex <= 0) {
                    $(opts.prev).hidee()
                } else {
                    $(opts.prev).showw();
                }
                
                if(opts.vertical === false) {

                    //alert( $(this).find(opts.container).length )

                    $(this).find(opts.container).css({
                        width: (opts.containerSize) ? opts.containerSize : size * opts.show,
                        overflow: 'hidden'
                    });

                    //alert( 'opts.show is ' + opts.show )
                    //alert( 'elements.length is ' + elements.length );
                    //alert( 'size is ' + size );
                    
                    $(this).find(opts.parent).css({
                        width: (elements.length) * size,
                        padding: '0'
                    });
                    
                    if ( elements.length >= opts.show  ) {
                        $(opts.parent, self).animate({
                            marginLeft: margin
                        }, opts.speed);
                    }
                }
                else {

                    $(this).find(opts.container).css({
                        height: (opts.containerSize) ? opts.containerSize : size * opts.show,
                        overflow: 'hidden'
                    });
                    
                    $(this).find(opts.parent).css({
                        height: (elements.length) * size,
                        padding: '0'
                    });
                    
                    $(opts.parent, self).animate({
                        marginTop: margin
                    }, opts.speed);
                }

                window.kaka = maxIndex;
        
                //(function(upperIndex,maxIndex) {
                    //(upperIndex,maxIndex)
                    var cycle = {
                        next: function() {

                                //alert('iz' + maxIndex);
                            //alert( upperIndex )
                            //alert( maxIndex )
                            window.up = upperIndex;

                            if(upperIndex <= maxIndex) {
                                //alert('if')
                                $(opts.prev).showw();

                                var count = ((upperIndex+opts.scrollCount) > maxIndex) ? elements.length-upperIndex : opts.scrollCount;
                    
                                margin = margin - (size * count);
                                upperIndex = upperIndex + count;
                                lowerIndex = lowerIndex + count;
                                
                                if(opts.vertical === false) {
                                    $(opts.parent, self).animate({
                                        marginLeft: margin
                                    },opts.speed);
                                }
                                else {
                                    //alert('animate')
                                    //alert( $(opts.parent,self).length );
                                    $(opts.parent, self).animate({
                                        marginTop: margin
                                    },opts.speed);
                                }
                                
                                if(upperIndex > maxIndex) {
                                    $(opts.next).hidee();
                                } else {
                                    $(opts.prev).showw();
                                }
                            }
                        },
                        prev: function() {
                            if(lowerIndex >= 0) {
                                $(opts.next).showw();    
                                
                                var count = ((lowerIndex-opts.scrollCount) < 0) ? lowerIndex : opts.scrollCount;
                                
                                upperIndex = upperIndex - count;
                                lowerIndex = lowerIndex - count;
                                margin = margin + (size * count);
                                
                                if(opts.vertical === false) {
                                    $(opts.parent, self).animate({
                                        marginLeft: margin
                                    }, opts.speed);
                                }
                                else {
                                    $(opts.parent, self).animate({
                                        marginTop: margin
                                    }, opts.speed);
                                }
                                if((lowerIndex-1) < 0) {
                                    $(opts.prev).hidee();
                                } else {
                                    $(opts.prev).showw();
                                }
                            }
                        },
                        toPoint: function(pos) {
                            var oldUpper = upperIndex;
                            
                            if(pos == 0) {
                                // jump to end
                                upperIndex = maxIndex + 1;
                                lowerIndex = upperIndex - opts.show;
                            }
                            else if(pos < 0) {
                                // offset from end
                                upperIndex = maxIndex + parseInt(pos);
                                lowerIndex = lowerIndex + parseInt(pos);
                            }
                            else {
                                // offset from start
                                lowerIndex = pos - 1;
                                upperIndex = lowerIndex + opts.show;
                            }
                            // if the upper index is 
                            margin = margin + (size * (oldUpper-upperIndex));
                            
                            if(opts.vertical === false) {
                                $(opts.parent, self).animate({
                                    marginLeft: margin
                                },opts.speed);
                            }
                            else { 
                                $(opts.parent, self).animate({
                                    marginTop: margin
                                }, opts.speed);
                            }
                            
                            if(upperIndex >= maxIndex) $(opts.next).hidee();
                            else $(opts.next).showw();
                            
                            if(lowerIndex == 0) $(opts.prev).hidee();
                            else $(opts.prev).showw();
                        }
                    };

                    if ( !$(opts.next).data('bound') ) {
                        //alert('binding!')
                        $(opts.next).live('click', function(e) { 
                            //alert( cycle.next )
                            cycle.next();
                            
                            e.preventDefault();
                        });
                        $(opts.next).data('bound',1)
                    }
                    
                    if ( !$(opts.prev).data('bound' ) ) {
                        //alert('binding2!')
                        $(opts.prev).live('click', function(e) { 
                            cycle.prev(); 
                            
                            e.preventDefault();
                        });
                        $(opts.prev).data('bound',1)
                    }

                    if(opts.jumpTo) {
                        $(opts.jumpTo).live('click', function(e) { 
                            cycle.toPoint($(this).data('position')); 
                            
                            e.preventDefault();
                        });
                    }
                //})(upperIndex,maxIndex);
                
            }

            $(this).bind('added', actions);
            $(this).bind('removed', actions);

            actions();

        });

        $.fn.show = show;
        $.fn.hide = hide;

    }

})(jQuery);


