/************************************************************************************************
slideBox v1.0.0
/ Elige una de las tres formas de rebobinado:
/ - BackAll, mover al item del inicio invirtiendo el sentido de la marcha
/ - Infinite, la transición es continuada sin cambiar el sentido de la marcha TODO: pendiente de implementación
/ - reverse, se invierte el sentido de la marcha una vez alcanzados los items de los extremos
**************************************************************************************************/
(function ($) {
    $.fn.extend({
        slideBox: function (options) {

            var defaults = {
                AutoMotion: true,
                TimeoutMotion: 10,
                TypeRewinding: 'backall',
                NumberItemsMoved: 1,
                Speed: 'normal'
            };

            var options = $.extend(defaults, options);

            // inicialización 
            return this.each(function () {

                var mask = $(".SlideBox_mask", this);
                var listItems = $(".SlideBox_listItems", mask);
                var items = $(".SlideBox_item", listItems);
                var itemFirst = $(".SlideBox_item:first", listItems);
                var controlPrev = $(".SlideBox_controlPrev:first", this);
                var controlNext = $(".SlideBox_controlNext:first", this);

                var itemWidth = itemFirst.outerWidth();

                var itemMarginLeft = parseInt(itemFirst.css("margin-left"), 10);
                var itemMarginRight = parseInt(itemFirst.css("margin-right"), 10);
                var itemTottalWidth = itemWidth + itemMarginLeft + itemMarginRight;



                var itemHeight = itemFirst.height();
                // calculo del item más alto
                items.each(function () {
                    var item = $(this);
                    var thisItemHeight = item.outerHeight();
                    if (thisItemHeight > itemHeight) {
                        itemHeight = thisItemHeight;
                    }
                });
                var itemMarginTop = parseInt(itemFirst.css("margin-top"), 10);
                var itemMarginBottom = parseInt(itemFirst.css("margin-bottom"), 10);
                var itemTottalHeight = itemHeight + itemMarginTop + itemMarginBottom;

                var posicion = 0;
                var nItems = items.size();
                var nVisibleItems = 0;
                var nCompleteVisibleItems = 0;

                listItems.width((itemTottalWidth * nItems));
                listItems.height(itemTottalHeight);

                // calulo de los items que aparecen visibles
                while ((itemTottalWidth * nVisibleItems) < mask.width() && nVisibleItems < nItems) {
                    nVisibleItems++;
                    nVisibleCompleteItems = nVisibleItems;
                    if (((itemTottalWidth * nVisibleItems) - itemMarginRight) > mask.width()) {
                        nVisibleCompleteItems--;
                    }
                }

                var intervalMotionId = null;
                var intervalMotionId = null;
                var timeoutMotion = options.TimeoutMotion * 1000;
                var descontadorTiempo = 0;
                var reverse = false;
                var actioControl = false;


                // hecmos un clon de todos items
                // los colocamos a continuación
                // reancheamos el listItems
                // pasamos todos los items a position absolute
                if (options.TypeRewinding == "infinite") {
                    options.NumberItemsMoved = 1; // TODO: infinite no es capaz de moverse de varios en varios items
                    listItems.append(items.clone());
                    items = $(".SlideBox_item", listItems);
                    nItems = items.size();
                    listItems.width(itemTottalWidth * nItems);
                    items.each(function (i) {
                        var item = $(this);
                        if (item.is(".SlideBox_cloneItem")) {
                            i += (nItems / 2)
                        }
                        item.css({
                            "top": "0px",
                            "left": (itemTottalWidth * i) + "px",
                            "position": "absolute"
                        });
                        this.posLeft = (itemTottalWidth * i);
                    });
                }

                var indexItem = 0;
                var slideBoxIsHover = false;

                $(this).mouseover(function () {
                    slideBoxIsHover = true;
                }).mouseout(function () {
                    slideBoxIsHover = false;
                });


                function doMotion() {

                    if (!actioControl) {
                        if (options.TypeRewinding == "reverse") {
                            if (posicion >= 0 || posicion - 1 <= -nItems) {
                                reverse = !reverse;
                            }
                            if (reverse) {
                                posicion--;
                            } else {
                                posicion++;
                            }
                        } else if (options.TypeRewinding == "infinite") {
                            posicion--;
                            listItems.width((listItems.width() + itemTottalWidth));
                        } else {
                            if (posicion - 1 > -nItems) {
                                posicion--;
                            } else {
                                posicion = 0;
                            }
                        }
                    } else {
                        actioControl = false;
                    }
                    listItems.animate({ "left": (itemTottalWidth * (posicion * options.NumberItemsMoved)) + "px" }, options.Speed, function () {

                        if (options.TypeRewinding == "infinite") {
                            if (indexItem > (nItems - 1) || indexItem < 0) {
                                indexItem = 0;
                            }
                            var item = $(items[indexItem]);
                            item.css({ "left": item.position().left + (itemTottalWidth * nItems) });
                            indexItem++;
                        }

                        if (options.AutoMotion) {
                          
                            descontadorTiempo = timeoutMotion;
                            
                            intervalMotionId = setInterval(function () {
                                if (descontadorTiempo == 0) {
                                    doMotion();
                                    clearInterval(intervalMotionId);
                                } else {
                                    if (!slideBoxIsHover) {
                                        descontadorTiempo-=100;
                                    }
                                }
                            }, 100);
                            

                        }

                    });
                }

                if (options.AutoMotion) {
                    setTimeout(doMotion, timeoutMotion);
                } else {
                    options.TimeoutMotion = 1;
                    options.TypeRewinding = "reverse";
                }

                // acciones de los controles
                if (controlPrev.size() > 0 && controlNext.size() > 0) {
                    if (options.TypeRewinding != "infinite") {
                        controlPrev.bind("click", function () {
                            if (posicion < 0) {
                                clearInterval(intervalMotionId);
                                intervalMotionId = null;
                                reverse = false;
                                actioControl = true;
                                posicion++;
                                postionAnt = posicion + 1;
                                doMotion();
                            }
                        });
                        controlNext.bind("click", function () {
                            if ((posicion * defaults.NumberItemsMoved) > -(nItems - nVisibleItems)) {
                                clearInterval(intervalMotionId);
                                intervalMotionId = null;
                                reverse = true;
                                actioControl = true;
                                posicion--;
                                postionAnt = posicion - 1;
                                doMotion();
                            }
                        });
                    }
                }
            });
        }
    });
})(jQuery);


