/*
Copyright (C) 2010 Sébastien Méric, sebastien-meric.com

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program.  If not, see http://www.gnu.org/licenses/.
*/

( function( $ ) { // Compliant with jquery.noConflict()
    $.fn.jFeaturesSlideshow = function( o ) {
        o=$.extend({
            titleTag: 'h3',
            easing: null,
            pause: 100,
            transitionSpeed: 100,
            transition: 'scrollh',   // scrollh, scrollv, fade
            callback: null,
            // nav
            nav: true,
            prevNext: false,
            prev: '',
            next: '',
            navType: 'bullets', // bullets (needs images on/off), numbers, thumbs
            navId: 'jFeaturesSlideshowNav',
            navBtsId: 'jFeaturesSlideshowBts',
            // for navType: numbers
            navSelectedColor: '#f00',
            // for navType: bullets
            navImg: null,
            navImgHover: null,
            navImgIn: null,
            // for navType: thumbs
            navThumbWidth: null, // utilise la grande image avec cette largeur
            navThumbHeight: null, // utilise la grande image avec cette hauteur
            navThumbSuffixe: '' // si la grande image s'appelle image.jpg, le thumb doit s'appeler image-[suffixe].jpg
        }, o || {});
        return this.each( function() { // Returns the element collection. Chainable.
            var running = false;
            var curr = 0;
            var currentSlide = 1;
            var container = $( this );
            var ul = $( 'ul', container );
            var tmpLi = $( 'li', ul );
            var tmpLiLength = tmpLi.size();
            
            ul.append( tmpLi.slice( 0, 1 ).clone() );
            
            var li = $( 'li', ul );
            var liLength = li.size();
            var img = $( 'img', ul );
            var imgHeight = img.height();
            //var title = $( o.titleTag, ul );
            
            // en mode fade, la transition est verticale et instantanée
            // la valeur de la durée de transition est utilisée pour détérminer la vitesse du fade
            if ( o.transition == 'fade' ) {
                o.transitionDuration = o.transitionSpeed;
                o.transitionSpeed = 0;
            }
            
            if ( o.prevNext ) {
                // append prev / next
                container.after( '<div class="jFeaturesSlideshowNext">'+o.prev+'</div>' );
                container.after( '<div class="jFeaturesSlideshowPrev">'+o.next+'</div>' );
                $('.jFeaturesSlideshowPrev').unbind().click(function(){
                    go(liLength-2);
                });
                $('.jFeaturesSlideshowNext').unbind().click(function(){
                    go(1);
                });
            }
            
            if ( o.nav ) {
                // append nav
                container.after( '<div id="' + o.navId + '"></div>' );
                var nav = $( '#' + o.navId );
                var btNav = '';
                if ( o.nav ) {
                    btNav = '<ul id="' + o.navBtsId + '">';
                }
                for ( var i = 1; i < liLength; i++ ) {
                    if ( o.navType == 'bullets' && o.navImg ) {
                        btNav += '<li id="bt-' + i + '"><img src="' + o.navImg + '" alt="slide ' + i + '" /></li>';
                    }
                    else if ( o.navType == 'thumbs' ) {
                        if ( o.navThumbWidth && o.navThumbHeight ) {
                            btNav += '<li id="bt-' + i + '"><img src="' + img.get(i-1).src + '" alt="vignette ' + i + '" width="' + navThumbWidth + '" height="' + navThumbHeight + '" /></li>';
                        }
                        else if ( o.navThumbSuffixe ) {
                            if ( img.get(i-1).src.indexOf( '.jpg' ) )
                                var thumbnail = img.get(i-1).src.replace( '\.jpg', '-' + o.navThumbSuffixe + '.jpg' );
                            else if ( img.get(i-1).src.indexOf( '.gif' ) )
                                var thumbnail = img.get(i-1).src.replace( '\.gif', '-' + o.navThumbSuffixe + '.gif' );
                            else if ( img.get(i-1).src.indexOf( '.png' ) )
                                var thumbnail = img.get(i-1).src.replace( '\.png', '-' + o.navThumbSuffixe + '.png' );
                            btNav += '<li id="bt-' + i + '"><img src="' + thumbnail + '" alt="vignette ' + i + '" /></li>';
                        }
                        else
                            btNav += '<li id="bt-' + i + '"><img src="' + img.get(i-1).src + '" alt="vignette ' + i + '" height="' + parseInt( imgHeight/liLength ) + '" /></li>';
                    }
                    else {
                        btNav += '<li id="bt-' + i + '">' + i + '</li>';
                    }
                }
                if ( o.nav ) {
                    btNav += '</ul>';
                }
                nav.append( btNav );
                if ( o.nav ) {
                    var btsNav = $( '#' + o.navBtsId, nav );
                }
            }

            // styles
            container.css({
                'overflow':'hidden',
                'position':'relative'
            });
            ul.css({
                'overflow':'hidden',
                'margin':'0',
                'padding':'0',
                'position':'relative'
            });
            li.each( function( i ) {
                $( this ).css({
                    'margin':'0',
                    'padding':'0',
                    'list-style':'none',
                    'position':'relative'
                });
            });
            if ( o.transition == 'scrollh' )
                li.each( function( i ) {
                    $( this ).css({
                        'float':'left'
                    });
                });
            img.each( function( i ) {
                $( this ).css( 'border', '0' );
            });
            /*title.each(function(i){
                $(this).css({'display': 'block', 'margin': '0 10px 0 10px', 'padding': '0 5px', 'position': 'absolute', 'bottom': '30px', 'background-color': '#fff'});
            });*/

            // widths
            if ( o.transition == 'scrollh' ) {
                var liSize = li.width();
                var ulSize = liSize * liLength;
                var containerSize = liSize;
                li.css({ 'width': li.width() + 'px', 'height': li.height() + 'px' });
                ul.css( 'width', ulSize + 'px').css( 'left', -( curr*liSize ) + 'px' );
                container.css( 'width', containerSize + 'px' );
            }
            else if ( o.transition == 'scrollv' || o.transition == 'fade' ) {
                var liSize = li.height();
                var ulSize = liSize * liLength;
                var containerSize = liSize;
                li.css({ 'width': li.width() + 'px', 'height': li.height() + 'px' });
                ul.css( 'height', ulSize + 'px' ).css( 'top', -( curr*liSize ) + 'px' );
                container.css( 'height', containerSize + 'px' );
            }

            // select the first nav elt
            if ( o.nav ) {
                if ( o.navImg ) {
                    $( '#bt-1 img', btsNav ).attr( 'src', o.navImgIn );
                }
                else{
                    $( '#bt-1', nav ).addClass( 'selected' );
                }
            }

            // for the slideshow to appear already styled
            // the css file must contain : #slideshowId{ visibility: hidden }
            container.css( 'visibility', 'visible' );

            this.goslide = setInterval( function() {
                go( curr+1 );
            }, o.pause );

            // stop sliding on hover, start again on out
            container.parent().hover( function() {
                clearInterval( $(this).find('div').get(0).goslide );
            }, function() {
                $(this).find('div').get(0).goslide = setInterval( function() {
                    go( curr+1 );
                }, o.pause );
            });

            if ( o.nav ) {
                $( '#bt-1', nav ).addClass( 'selected' );
                for ( var i = 2; i < liLength; i++ ) {
                    if ( o.navImg ){
                        var elt = $( '#bt-' + i + ' img', nav );
                        elt.attr( 'src', o.navImg );
                    }
                    else{
                        var elt = $( '#bt-' + i, nav );
                    }
                    elt.css( 'cursor', 'pointer' ).bind( 'click', { index: i }, function( e ) {
                        var ind = e.data.index;
                        go( ind-1 );
                        return false;
                    });
                }
            }

            function vis() {
                return li.slice( curr ).slice( 0, 1 );
            };

            // unselect all nav elts and attach click events to them
            function reinitNav() {
                for ( var i = 1; i < liLength; i++ ) {
                    if ( o.navImg ){
                        var elt = $( '#bt-' + i + ' img', nav );
                        elt.attr( 'src', o.navImg );
                    }
                    else{
                        var elt = $( '#bt-' + i, nav );
                    }
                    elt.removeClass( 'selected' )
                    elt.unbind().css( 'cursor', 'pointer' ).bind( 'click', { index: i }, function( e ) {
                        var ind = e.data.index;
                        go( ind-1 );
                        return false;
                    });
                }
            };

            // show the selected nav elt
            function initNavBt( ind ) {
                if ( o.navImg ) {
                    var elt = $( '#bt-' + ind + ' img', nav );
                    elt.attr( 'src', o.navImgIn );
                }
                else{
                    var elt = $( '#bt-' + ind, nav );
                }
                elt.addClass( 'selected' );
                elt.unbind().css( 'cursor', 'default' );
            };
            
            function initNextPrev( ind ) {
                //alert( ind );
                var max = liLength - 1;
                var prev;
                if ( curr == 1 )
                    prev = max;
                /* else if ( curr == max )
                    prev = 1; */
                else
                    prev = curr-1;
                $('.jFeaturesSlideshowPrev').unbind().click(function(){
                    go(prev);
                    //alert(prev);
                });
                
                var next;
                if ( curr < max )
                    next = curr+1;
                else
                    next = 1;
                $('.jFeaturesSlideshowNext').unbind().click(function(){
                    go(next);
                    //alert(next);
                });
                //alert('curr: '+curr+', length: '+max+', prev: '+prev+', next: '+next);
            }

            // function to slide one image to the next
            function go( to ) {
                var current = to;
                if ( current == liLength-1 )
                    current = 1;
                else if ( current == liLength )
                    current = 2;
                else
                    current = to+1;
                
                if ( o.callback )
                    o.callback(current-1);
                
                if ( o.beforeStart )
                    o.beforeStart.call( this, vis() );

                if ( o.nav )
                    reinitNav();

                if ( !running ) {
                    if ( to >= liLength ) { // If last, then goto first
                        if ( o.transition == 'scrollh' )
                            ul.css( 'left', '0' );
                        else if ( o.transition == 'scrollv' || o.transition == 'fade' )
                            ul.css( 'top', '0' );
                        curr = 1;
                    }
                    else {
                        curr = to;
                    }

                    running = true;

                    if ( o.transition == 'scrollh' ) {
                        ul.animate({ 'left': -( curr*liSize ) + 'px' }, o.transitionSpeed, o.easing, function() {
                            if ( o.afterEnd ) {
                                o.afterEnd.call( this, vis() );
                            }
                            if ( to == 1 || to == liLength ) {
                                currentSlide = 1;
                            }
                            else {
                                currentSlide = to;
                            }
                            if ( currentSlide >= liLength-1 ) {
                                currentSlide = 1;
                            }
                            else {
                                currentSlide++;
                            }
                            if ( o.nav )
                                initNavBt( currentSlide );
                            if ( o.prevNext )
                                initNextPrev( currentSlide );
                            running = false;
                        });
                    }
                    else if ( o.transition == 'scrollv' || o.transition == 'fade' ) {
                        if ( o.transition == 'fade' ) {
                            ul.fadeOut( o.transitionDuration );
                        }
                        ul.animate({ 'top': -( curr*liSize ) + 'px' }, o.transitionSpeed, o.easing,
                            function() {
                                if ( o.afterEnd ) {
                                    o.afterEnd.call( this, vis() );
                                }
                                if ( to == 1 || to == liLength ) {
                                    currentSlide = 1;
                                }
                                else{
                                    currentSlide = to;
                                }
                                if ( currentSlide >= liLength-1 ) {
                                    currentSlide = 1;
                                }
                                else {
                                    currentSlide++;
                                }
                                if ( o.nav )
                                    initNavBt( currentSlide );
                                if ( o.prevNext )
                                    initNextPrev( currentSlide );
                                running = false;
                            }
                        );
                        if ( o.transition == 'fade' ) {
                            ul.fadeIn( o.transitionDuration );
                        }
                    }
                }
                return false;
            };
        });
    };
})( jQuery );


