///////////////////////////////////////////////////////////////////////
// imageScroller (1.0), Copyright (C) 2008 Max Kiusso
//
// Autor:           Max Kiusso - kiussoATgmailDOTcom
// Date:            2008 12 01
//
// REQUIRES jQuery 1.2+ <http://jquery.com/>
//
// Features:
//           		This software provide to create a multidirectional image
//		            scroller with mouse events
//
// Configuration:	$( "#div" ).imageScroller( {options} )
//
// Options:         speed (millisecond)
//                  loading (text)
//                  direction (left, right, top, bottom)
///////////////////////////////////////////////////////////////////////

( function( $ ) {
    $.fn.imageScroller = function ( options ) {
        return this.each( function() {
            var $this = $( this );
            var loadImgs = 0;
            var opt = $.extend( 
                { 
                      speed: "2000"
                    , loading: "Loading ..."
                    , direction: "left"
                }
                , options || {}
            );
            
            $this.children().hide();
            $this.append("<div id='loading'>" + opt.loading + "</div>");
            
            $( "img" , $this ).load(
                function () {
                    loadImgs++;
                }
            );
            loadImgs = $("img", $this).length;
            
            var intVal = window.setInterval(
                function () {
                    if (true) { //loadImgs == $( "img" , $this ).length ) {
                        window.clearInterval( intVal );
                        $( "#loading" ).remove();
                        $this.children().show();
                        var totImg = 0;

                        $.each(
                              $this.children( ":not(div)" )
                            , function () {
                                switch ( opt.direction ) {
                                    case 'left':
                                    case 'right':
                                        if ( $( this ).children().length ) {
                                            $( this ).width( $( this ).children( ":eq(0)" ).width() );
                                        }
                                        totImg += $( this ).width();
                                        break;
                                    case 'top':
                                    case 'bottom':
                                        $( this ).css( "display" , "block" );
                                        /* This part removes the spaces for the images (padding, margin)
                                        if ( $( this ).children().length ) {
                                            $( this ).height( $( this ).children( ":eq(0)" ).height() );
                                        }
                                        */
                                        totImg += $( this ).height();
                                        break;
                                }
                                
                                
                                
                                $(this).hover(
                                    function() {
                                        $("div:eq(0)", $this).stop();
                                    },
                                    function() {
                                        scrollStart($("div:eq(0)", $this), opt);
                                    }
                                );
                                
                                $( "div:eq(0)" , $this ).append( $( this ) );
                            }
                        );
                        
                        switch ( opt.direction ) {
                            case 'left':
                                $( "div:eq(0)" , $this ).css( "width" , totImg + "px" );
                                break;
                            
                            case 'right':
                                $( "div:eq(0)" , $this ).css( "width" , totImg + "px" );
                                $( "div:eq(0)" , $this ).css({
                                    "marginLeft" : -( totImg - $this.width() ) + "px"
                                });
                                break;
                                
                            case 'top':
                                $( "div:eq(0)" , $this ).css( "height" , totImg + "px" );
                                break;
                                
                            case 'bottom':
                                $( "div:eq(0)" , $this ).css( "height" , totImg + "px" );
                                $( "div:eq(0)" , $this ).css({
                                    "marginTop" : -( totImg - $this.height() ) + "px"
                                });
                                break;
                        }
                        scrollStart( $( "div:eq(0)" , $this ) , opt );
                    }
                }
                , 100
            );
            
            function scrollStart ( $scroll , opt )
            {
                switch ( opt.direction ) {
                    case 'left':
                        var pos = -( $scroll.children( ":eq(0)" ).width() );
                        // crashes because of Math.abs ( parseInt( $scroll.css( "marginLeft" ) ) ) returns "NaN"
                        //var spd = opt.speed - ( Math.abs ( parseInt( $scroll.css( "marginLeft" ) ) ) * ( opt.speed / $scroll.children( ":eq(0)" ).width() ) );
                        //var spd = opt.speed;
                        break;
                        
                    case 'right':
                        var pos = -( $scroll.width() - $scroll.parents( "div:eq(0)" ).width() ) + $scroll.children( ":last" ).width();
                        //var spd = opt.speed - ( ( $scroll.children( ":last" ).width() - ( Math.abs ( parseInt( $scroll.css( "marginLeft" ) ) ) - Math.abs ( pos ) ) ) * ( opt.speed / $scroll.children( ":last" ).width() ) );
                        break;
                        
                    case 'top':
                        var tos = -( $scroll.children( ":eq(0)" ).height() );
                        // crashes because of Math.abs ( parseInt( $scroll.css( "marginTop" ) ) ) returns "NaN"
                        //var spd = opt.speed - ( Math.abs ( parseInt( $scroll.css( "marginTop" ) ) ) * ( opt.speed / $scroll.children( ":eq(0)" ).height() ) );
                        //var spd = opt.speed;
                        break;
                        
                    case 'bottom':
                        var tos = -( $scroll.height() - $scroll.parents( "div:eq(0)" ).height() ) + $scroll.children( ":last" ).height();
                        //var spd = opt.speed - ( ( $scroll.children( ":last" ).height() - ( Math.abs ( parseInt( $scroll.css( "marginTop" ) ) ) - Math.abs ( tos ) ) ) * ( opt.speed / $scroll.children( ":last" ).height() ) );
                        break;
                }
                
                $scroll.animate(
                    {
                          marginLeft: ( pos || "0" ) + "px"
                        , marginTop: ( tos || "0" ) + "px"
                    }
                    , opt.speed
                    , "linear"
                    , function ()
                      {
                        switch ( opt.direction ) {
                            case 'left':
                                $scroll.append( $( this ).children( ":eq(0)" ) );
                                $scroll.css( "marginLeft" , "0px" );
                                break;
                                
                            case 'right':
                                $scroll.prepend( $( this ).children( ":last" ) );
                                $scroll.css( "marginLeft" , -( $scroll.width() - $scroll.parents( "div:eq(0)" ).width() ) + "px" );
                                break;
                                
                            case 'top':
                                $scroll.append( $( this ).children( ":eq(0)" ) );
                                $scroll.css( "marginTop" , "0px" );
                                break;
                                
                            case 'bottom':
                                $scroll.prepend( $( this ).children( ":last" ) );
                                $scroll.css( "marginTop" , -( $scroll.height() - $scroll.parents( "div:eq(0)" ).height() ) + "px" );
                                break;
                        }
                        
                        scrollStart( $scroll , opt );
                    }
                );
            };
        });
    };
})(jQuery);
