/**
 * jquery.simpleSlides-1.0.1.js
 * @description - Offers an easy way to turn a collection of `.slides` into a
 * `.slide` show (`.simple-slide-show `) which either scrolls
 * ['vertical', 'horizontal'], or fades in and out 
 * @todo make scrollable area scroll to 0 on init
 * @todo add getters/setters for properties that effect component in realtime
 * @dependencies jquery.edom-1.0.1.js
 */
(function($) {
    $.fn.simpleSlides = function(settings)
    {
        // Configuration for our simpleCarousel
        var config = {
            // Autoplay namespace
            autoPlay: {
                elm: null,
                sel: null,
                html: '<a href="#" class="autoPlay_btn"><span>Turn Autoplay'+
                '</span> <span class="ind tbld">Off</span></a>',
                showBln: true,
                // Is active/turned on
                active: true,
                // The delay before the autoPlay functionality takes place
                delay: 2000,
                // The autoplay interval
                interval: 0
            },
            // Animation namespace
            animation: {
                // The speed of all the animation within our plugin
                speed: 300,
                effect: {
                    scrollToSlide: false,
                    fadeToSlide: false
                }
            },
            // Controls namespace
            controls: {
                elm: null,
                // Selector for our controls if already declared somewhere
                sel: null,
                // HTML for our controls for those who prefer to instantiate
                // them through javascript/jquery
                html: '<div class="cb controls">'+
                '<a href="#" class="prev_btn"><span>&lt;&lt;Prev</span></a>'+
                '<a href="#" class="next_btn"><span>Next&gt;&gt;</span></a>'+
                '</div>',
                // `Previous` btn selector
                prev_btn_sel: '> a.prev_btn',
                // `Next` btn selector
                next_btn_sel: '> a.next_btn',
                // positions to place our controls if showBln is true
                displayAtPositions: ['top','bottom'],
                // Whether to show our controls or not
                showBln: true,
                // Whether or not to show our page numbers for our carousel
                showSlideNumLinks: true,
                // Show the previous and next buttons
                showPrevNextLinks: true
            },
            // Scrollable area of the simpleCarousel
            scrollable_area: {
                elm: null,
                // Direction of the scrolling
                scrollDirection: 'vertical',
                // Either sel
                sel: '> div.body',
                // Or define html for our body element
                html: '',
                // Should we show the scrollbar
                showScrollBarsBln: false
            },
            // Our slide settings will be
            // stored within this object
            slides: {
                // The width and height of our slides
                slide: {
                    width: 960,
                    height: 200,
                    sel: '> .slide'
                },
                elm: null,
                length: 0,
                previousPointer: 0,
                pointer: 0,
                direction: 0
            },
            // Bypass slides calculation (length, width, height, position etc)
            // and calculate
            // from the outside
            bypassSlidesCalc: false,
            debug_output: '',
            debug: false
        };
	
        // Extend config with settings if available
        if (settings) {
            config = $.edom.extendObject(config, settings);
        //$.extend(config, settings);
        }
    
        //\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
        // Run script on each item
        //\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
        this.each(function()
        {
            /*******************************************************************
             * CONFIG
             ******************************************************************/
            var o = this, i = 0,
            C = config;
            /*******************************************************************
             * SLIDES
             ******************************************************************/
            o.init_slides = function() {
                // If bypass is set to false calculate slides length etc
                if (!C.bypassSlidesCalc) {
                    C.slides.elm =
                        $(C.scrollable_area.sel +' '+ C.slides.slide.sel, o);
                    C.slides.length = C.slides.elm.length;
                    if(C.animation.effect.scrollToSlide) {
                        if(C.scrollable_area.scrollDirection != 'vertical'){
                            i = 0; // Set to zero for loop
                            C.slides.elm.each(function(){
                                $(this).css({
                                    position: 'absolute',
                                    left: i * C.slides.slide.width
                                });
                                i += 1;
                            });
                        }
                    }
                    else if (C.animation.effect.fadeToSlide) {
                        i = 0; // Set to zero for loop                        
                        C.slides.elm.each(function(){
                            $(this).css({
                                position: 'absolute',
                                display: 'none',
                                //cssFloat: 'left',
                                margin: 0,
                                padding: 0
                            });
                        });
                        C.slides.elm.eq(0).fadeIn('slow');
                        $(C.scrollable_area.sel).
                        css({
                            //cssFloat: 'left',
                            display: 'block'
                        });
                    }
                } // end if !C.bypassSlidesCalc
                
                C.debug_output += '\n- Slides initialization complete.  ' +
                'Slides.length = '+ C.slides.length;
            };
            /*******************************************************************
             * SCROLLABLE_AREA
             ******************************************************************/
            o.init_scrollable_area = function()
            {
                // Get the scrollable area
                if (C.scrollable_area.sel) {
                    C.scrollable_area.elm = $(C.scrollable_area.sel, o);                    
                }
                // Show the scrollable area scrollbars
                if (C.scrollable_area.showScrollBarsBln) {
                    C.scrollable_area.elm.css('overflow', 'auto');
                }
                else {
                    C.scrollable_area.elm.css('overflow', 'hidden');
                }
                C.debug_output +=
                '\n- Scrollable area initialization complete.\n' +
                '  Scrollable_area.height = ' + C.scrollable_area.elm.height();
            };

            /*******************************************************************
             * CONTROLS
             ******************************************************************/
            o.init_controls = function()
            {
                C.debug_output += '\n- Initializing controls.';
                // Parse controls data
                if (C.controls.sel != null) {
                    // Get controls
                    C.controls.elm = $(C.controls.sel, o);
                }
                else {
                    // Make controls elm
                    C.controls.elm = $(C.controls.html);
                    if(C.controls.showBln) {
                        $(o).append(C.controls.elm);
                    }
                }
                C.debug_output += '\n- Got controls.';
                
                // Show prev and next btns
                if (C.controls.showPrevNextLinks) {
                    C.debug_output += '\n- Adding listeners to prev_btn.';
                    // Bind the prevSlide function to our previous slide btn
                    $(C.controls.prev_btn_sel, C.controls.elm).
                    mouseup(function(e){
                        e.preventDefault();
                        o.prevSlide();
                    });
                    C.debug_output += 'Done.\n- Adding listeners to next_btn.';
                    // Bind the nextSlide function to our next slide btn
                    $(C.controls.next_btn_sel, C.controls.elm).
                    click(function(e){
                        e.preventDefault();
                        o.nextSlide();
                    });
                    C.debug_output +=
                    '\n- Done adding listeners to prev and next.';
                }

                // Show slide number links
                if (C.controls.showSlideNumLinks) {
                    for (i = 0; i < C.slides.length; i += 1) {
                        a = $('<a href="javascript: void(0);"><span>' + (1+i) +
                            '</span></a>');
                        a.attr('pointer', i);
                        a.click(function(e){
                            e.preventDefault();
                            C.slides.direction =
                                $(this).attr('pointer') > C.slides.pointer ?
                                    3 : 2;
                            if(C.slides.pointer != $(this).attr('pointer')){
                                C.slides.previousPointer = C.slides.pointer;
                                o.gotoSlide($(this).attr('pointer'));
                            }
                        });
                        C.controls.elm.append(a);
                    }
                }

                // Show autoplay btn if necessary
                if(C.autoPlay.showBln) {
                    if (C.autoPlay.sel != null) {
                        // Get controls
                        C.autoPlay.elm = $(C.autoPlay.sel, o);
                    }
                    else {
                        // Make controls elm
                        C.autoPlay.elm = $(C.autoPlay.html);
                        if(C.autoPlay.showBln) {
                            C.controls.elm.append(C.autoPlay.elm);
                        }
                    }
                    C.autoPlay.elm.click(function(e){
                        e.preventDefault();
                        o.toggleAutoPlay()
                    });
                }
                C.debug_output += '\n- Controls initialization complete.';
            };

            /*******************************************************************
             * METHODS
             ******************************************************************/
            /**
             * Goes to the next slide
             */
            o.nextSlide = function(){
                C.slides.previousPointer = C.slides.pointer;
                C.slides.pointer = (C.slides.pointer < C.slides.length-1) ?
                C.slides.pointer + 1 : 0;                
                if (C.slides.pointer <= C.slides.length-1
                    && C.slides.pointer != 0) {
                    C.slides.direction = 1;
                    o.gotoSlide(C.slides.pointer, 1);
                }
                else {
                    // 0 = left || down; 1 = up || right;
                    // 2 = last slide goto 0; 3 = first slide goto last
                    C.slides.direction = 3;
                    o.gotoSlide(0);
                }
            //alert('Moved to slide number ' + C.slides.pointer);
            };
            /**
         * Goes to the prev slide
         */
            o.prevSlide = function(){
                C.slides.previousPointer = C.slides.pointer;
                C.slides.pointer = (C.slides.pointer > 0) ?
                C.slides.pointer - 1 : C.slides.length-1;
                if (C.slides.pointer != C.slides.length-1
                    && C.slides.pointer >= 0) {
                    // Direction left
                    C.slides.direction = 0;
                    o.gotoSlide(C.slides.pointer);
                }
                else {
                    // at first slide goto last
                    C.slides.direction = 2;
                    o.gotoSlide(C.slides.length-1);
                }
            //alert('Moved to slide number ' + C.slides.pointer);
            };

            /**
             * Goes to the indicated slide
             */
            o.gotoSlide = function(slideNum)
            {
                C.slides.pointer = slideNum;
                // Find out whether we scroll to slide or fade to slide
                if(C.animation.effect.scrollToSlide) {
                    o.scrollToSlide();
                }
                else if (C.animation.effect.fadeToSlide) {
                    o.fadeToSlide();
                }
            };

            /**
             * Scroll to slide either vertically or horizontally depending
             * on C.scrollable_area.scrollDirection ['vertical', 'horizontal']
             */
            o.scrollToSlide = function()
            {
                var opacity = C.slides.direction == 0 ||
                    C.slides.direction == 1 ? 0.6 : 0.2;
                C.scrollable_area.elm.fadeTo(C.animation.speed,
                    opacity, function()
                {
                    var c;
                    if (C.scrollable_area.scrollDirection == 'vertical') {
                        c = {
                            scrollTop: C.slides.pointer * C.slides.slide.height
                        };
                    }
                    else {
                        c = {
                            scrollLeft: C.slides.pointer * C.slides.slide.width
                        };
                    }
                    C.scrollable_area.elm.animate(
                        c,
                        // Callback
                        C.animation.speed, null, function(){
                            C.scrollable_area.elm.fadeTo(C.animation.speed, 1);
                        });
                });
            } // end func o.scrollToSlide

            o.fadeToSlide = function()
            {
                C.slides.elm.eq(C.slides.pointer).
                    fadeIn(C.animation.speed, function(){
                    C.slides.elm.eq(C.slides.previousPointer).
                        fadeOut(C.animation.speed);
                });
            } // end func o.fadeToOverlaySlide

            /**
             * Toggles the simpleCarousel autoPlay feature
             */
            o.toggleAutoPlay = function ()
            {
                if (C.autoPlay.interval) {
                    clearInterval(C.autoPlay.interval);
                    C.autoPlay.interval = 0;
                    if(C.autoPlay.elm != null){
                        $('.ind', C.autoPlay.elm).html('On');
                    }
                }
                else {
                    C.autoPlay.interval = setInterval(o.nextSlide,
                        C.autoPlay.delay);
                    if(C.autoPlay.elm != null){
                        $('.ind', C.autoPlay.elm).html('Off');
                    }
                }
            };

            // Returns the controls of our simpleCarousel
            o.getControls = function() {
                alert('getting controls');
            //return C.controls.elm;
            };

            /*******************************************************************
             * END OF PLUGIN CODE
             ******************************************************************/
            o.init = function() {
                //alert('Starting initialization');
                o.init_slides();
                o.init_scrollable_area();
                o.init_controls();
                if(C.autoPlay.active){
                    o.toggleAutoPlay();
                }
                if( C.debug ){
                    alert( C.debug_output );
                }
            //alert('Initialization complete!');
            };

            // Initialize
            o.init();
		
        });// end of plugin code
        return this;
    };
})(jQuery);
