/*
 * Kaiserkoenig Imagescroller jQuery PlugIn
 *
 * V3.1
 */
(function($){
    var boxes = $();
    var animations = {
        slide : function(n, o, config){
            n.show();
            if(!config.animation.rightOnly && (config.animation.leftOnly || n.index() > o.index()))
            {
                n.css({
                    left : n.outerWidth(true)
                });
                o.animate({
                    left : (n.outerWidth(true) * -1)
                },config.animateTime);
            }
            else
            {
                n.css({
                    left : (n.outerWidth(true) * -1)
                });
                o.animate({
                    left : n.outerWidth(true)
                },config.animateTime);
            }
            n.animate({
                left:0
            },config.animateTime);
            // animate the current elem
        },
        fade : function(n, o, config){
            // animate the new elem
            n.css({opacity:0}).show().animate({
                opacity:1
            },config.animateTime);
            // animate the current elem
            o.animate({
                opacity:0
            },config.animateTime, function(){$(this).hide().css({opacity:1})});
        },
        simple : function(n, o, config)
        {
            n.show();
            o.hide();
        },
        slideFirstOutAndAppend : function(n, o, config)
        {
            var max = boxes.length;
            var newIndex = n.index();
            var oldIndex = o.index();
            var multi = 0;

            if(newIndex > oldIndex)
            {
                multi = newIndex - oldIndex;

                boxes.animate({
                    left : "-=" + (o.outerWidth(true) * multi)
                }, config.animateTime);
            }
            else
            {
                multi = oldIndex - newIndex;

                boxes.animate({
                    left : "+=" + (o.outerWidth(true) * multi)
                }, config.animateTime);
            }

            
        }
    };

    $.addImageScrollerAnimation = function(anim)
    {
        $.extend(true, animations, anim);
    }

    $.fn.ImageScroller = function(opts){

        var imageScroller = $(this);
        imageScroller.css({position:'relative',top:0,left:0});

        var currentIndex = 0;
        var maxIndex = 0;

        /**
         * Init the gloabl working "Config Object"
         */
        var config = {
            animateTime : 800,
            scrollerWidth : $(this).innerWidth(),
            scrollerHeight : $(this).innerHeight(),
            boxSelector : 'div.image_scoller_container',
            stackBoxes : false,
            oneLine : false,
            viewPortSize : 1,
            hideInactiveBoxes : true,
            cntrls : {
                left : false,
                right : false,
                buttonContainer : false,
                buttonClass : 'image_scoller_button',
                buttonActiveClass : 'active',
                buttonShowNum : true,
                leftRightInactiveClass : 'inactive'
            },
            animationClasses : {
                slideClass : 'slide',
                fadeClass : 'fade'
            },
            defaultAnimation : 'simple',
            slideshow : {
                enabled : true,
                startdelay : 4000,
                delay : 3000,
                reenabledelay : false,
                reenable : true
            },
            animation : {} // related on the animtion ....
        };

        /**
         * Merge the opts into the config object
         */
        $.extend(true, config, opts);

        /**
         * Define important private functions
         */
	var showStatus = config.slideshow.enabled;

        /**
         * Cleanup button box
         */
        config.cntrls.buttonContainer.children().remove();

        /**
         * Adds a button to the bottom control panel
         *
         * @param elem The Boxelement the button should represent
         */
        function addBottomButton(index){
            var Btn = $('<a>').attr('href','#'+index).css({display:'inline-block'}).addClass(config.cntrls.buttonClass).click(function(){
                slideToBox(index);
                stopSlideShow();
                return false;
            });
            if(config.cntrls.buttonShowNum) Btn.text(index);
            if(index == 0){
                Btn.addClass(config.cntrls.buttonActiveClass);
            }
            config.cntrls.buttonContainer.append(Btn);
        }

         function slideToBox(index){
             // Ignore negative value
             if(index < 0)return;
             // ignore the call if the element is already selected
             if(currentIndex == index)return;
             // get the element
             var elem = imageScroller.find(config.boxSelector).children().eq(index);
             // ignore not existing elements
             if(elem.length == 0)return;

             var old = imageScroller.find(config.boxSelector).children().eq(currentIndex);

             var animationDone = false;
             for(var c in config.animationClasses)
             {
                var animStr = config.animationClasses[c];
                if(animStr == 'null') continue;
                if(elem.hasClass(c))
                {
                    var fn = animations[animStr];
                    if(typeof fn != 'function') continue;
                    fn(elem, old, config);
                    animationDone = true;
                }
             }
             if(animationDone == false)
             {
                animations[config.defaultAnimation](elem, old, config);
             }

            // Classmanagement for the bottom icons
            var selector = config.cntrls.buttonClass.replace(' ', '.');
            $('a.'+selector).removeClass(config.cntrls.buttonActiveClass);
            $('a.'+selector+'[href=#'+index+']').addClass(config.cntrls.buttonActiveClass);

            // Classmanagement for arrows
            if(config.cntrls.left.length > 0)
            {
                if(index === 0){
                    config.cntrls.left.addClass(config.cntrls.leftRightInactiveClass);
                }else{
                    config.cntrls.left.removeClass(config.cntrls.leftRightInactiveClass);
                }
            }
            if(config.cntrls.right.length > 0)
            {
                if((index + 1) === boxes.length){
                    config.cntrls.right.addClass(config.cntrls.leftRightInactiveClass);
                }else{
                    config.cntrls.right.removeClass(config.cntrls.leftRightInactiveClass);
                }
            }

            currentIndex = index;
         }

         /**
         * Simple Slideshow
         */
        var intervalObj;
        var reEnableTimer;
        function startIntervalAction()
        {
            if(!showStatus)return;
            intervalObj = window.setInterval(function(){
                if(!showStatus){
                    stopSlideShow();
                    return;
                }
                if((currentIndex + config.viewPortSize) < boxes.length)
                {
                    slideToBox((currentIndex + config.viewPortSize));
                }
                else slideToBox(0);
            },parseInt(config.slideshow.delay));
        }

        function reEnable()
        {
            var d = new Date();
            reEnableTimer = d.getTime();
            var tmp_time = d.getTime();
            var reEnDelay = parseInt(config.slideshow.delay * 2);
            window.setTimeout(function(){
                if(tmp_time == reEnableTimer){
                    showStatus = true;
                    startIntervalAction();
                }
            },reEnDelay);
        }

        function stopSlideShow()
        {
            showStatus = false;
            if(intervalObj !== false){
                window.clearInterval(intervalObj);
                if(config.slideshow.reenable){
                    reEnable();
                }
            }
        }

        if(showStatus){
            if(config.slideshow.startdelay){
                window.setTimeout(function(){
                    if(showStatus){
                        slideToBox((currentIndex + config.viewPortSize));
                        startIntervalAction();
                    }
                },parseInt(config.slideshow.startdelay));
            }else startIntervalAction();
        }

        /**
         * End of functionblock
         *
         * Here starts the real Plugin
         */

         /**
          * Find the container box and set some needed css
          */
         imageScroller.find(config.boxSelector).css({
             position:'relative'
         });

        /**
         * Find the boxes to animate later on
         */
        imageScroller.find(config.boxSelector).children().each(function(i){
            boxes = boxes.add($(this));
            var currentBox = $(this);
            if(config.hideInactiveBoxes && i != currentIndex)
            {
                currentBox.hide();
            }
            if(config.stackBoxes)
            {
                currentBox.css({
                    position : 'absolute',
                    left : 0,
                    top : 0
                });
            }
            else if(config.oneLine)
            {
                currentBox.css({
                    position : 'absolute',
                    left : (i * currentBox.outerWidth(true))
                });
            }
        });

        if(currentIndex == 0)
        {
            config.cntrls.left.addClass(config.cntrls.leftRightInactiveClass);
        }

        if((currentIndex + 1) == boxes.length)
        {
            config.cntrls.right.addClass(config.cntrls.leftRightInactiveClass);
        }

        for(var i = 0;i < Math.ceil(boxes.length / config.viewPortSize); i++)
        {
            addBottomButton((i * config.viewPortSize));
        }


        if(boxes.length <= config.viewPortSize)
        {
            config.cntrls.left.css('visibility', 'hidden');
            config.cntrls.right.css('visibility', 'hidden');
            showStatus = false;
        }


        if(config.cntrls.left.length > 0)
        {
            config.cntrls.left.click(function(){
                stopSlideShow();
                slideToBox((currentIndex - config.viewPortSize));
                return false;
            });
        }

        if(config.cntrls.right.length > 0)
        {
            config.cntrls.right.click(function(){
                stopSlideShow();
                slideToBox((currentIndex + config.viewPortSize));
                return false;
            });
        }

        /**
         * Fix bug that max occurs if the css does not set an height for the imagescoller
         * When we set the boxes and stuff to position:absolute this container may get a height of 0 which is pretty bad...
         */
        var tmp_parent;
        var tmp_current = imageScroller;
        while(imageScroller.height() == 0){
            tmp_parent = tmp_current.parent();
            if(tmp_parent.height() != 0){
                imageScroller.height(tmp_parent.height());
                break;
            }
            tmp_current = tmp_parent;
        }
    }
})(jQuery);
