// Deshabilita seleccionar texto 
$.fn.disableTextSelect = function() {

    return this.each(function() {
        if ($.browser.mozilla) {//Firefox
            $(this).css('MozUserSelect', 'none');
        } else if ($.browser.msie) {//IE
            $(this).bind('selectstart', function() { return false; });
        } else {//Opera, etc.
            // Buggy on chrome
            //$(this).mousedown(function(){return false;});
        }
    });
}

$.fn.carousel = function(config) {

    return this.each(function() {

        var i;

        var options = {
            autoplay: false,
            timeout: 5000,
            loop: false,
            speed: 500,
            stepCount: 1,
            disableAnimation: false,
            disableStyles: false,
            ease: $.easing["easeInOutSine"] ? "easeInOutSine" : "swing",

            itemHeight: 148,

            /* Contenedores */
            canvasItem: this,
            contentItem: "ul:first-child,ol:first-child",
            listItem: "li",
            controlsItem: this,
            selectedClass: "selected",

            /* Controles */
            firstControl: "",
            leftControl: "<a href='#'>left</a>",
            rightControl: "<a href='#'>right</a>",
            lastControl: "",
            pageControl: "", /* %page% para imprimir el numero de pagina */
            pageSeparator: " | ",

            onChange: null,

            paddingLeft: 0,
            paddingRight: 0
        };

        $.extend(options, config);

        var canvas = $(options.canvasItem);
        var canvasWidth = $(options.canvasItem).width();
        var canvasHeight = options.itemHeight;

        var content = $(options.contentItem, this);
        var list = $(options.listItem, content);

        var loopLeft = [], loopRight = [];

        if (list.size() == 0) return;

        var allControls = [];

        var current = 0;
        var apInterval;

        var createControls = function() {

            var controls = {
                first: options.firstControl ? $(options.firstControl) : null,
                left: options.leftControl ? $(options.leftControl) : null,
                right: options.rightControl ? $(options.rightControl) : null,
                last: options.lastControl ? $(options.lastControl) : null,
                page: []
            }

            /* Crea los controles de acceso a cada pagina */
            if (options.pageControl) {
                for (i = 0; i < list.length; i += options.stepCount) {
                    controls.page.push($(options.pageControl.replace("%page%", i + 1)));
                }
            }

            /* Asignamos accion a los controles */
            if (controls.first) controls.first.click(first);
            if (controls.left) controls.left.click(prev);
            if (controls.right) controls.right.click(next);
            if (controls.last) controls.last.click(last);
            for (i in controls.page) controls.page[i].attr("page", i).click(function(e) { page($(this).attr("page"), e); });

            allControls.push(controls);

            return controls;
        };

        var animate = function(instant, customTarget) {

            reportChange();

            for (var i in allControls) {
                for (var j in allControls[i].page) {
                    if (parseInt(j) == current) allControls[i].page[j].addClass(options.selectedClass);
                    else allControls[i].page[j].removeClass(options.selectedClass);
                }
            }

            if (options.disableAnimation) return;

            if (typeof customTarget == "number") customTarget = $(list[customTarget]);
            var target = customTarget || $(list[current]);

            content.animate({
                marginLeft: -target.offset().left + content.offset().left + options.paddingLeft
            }, instant ? 0 : options.speed, options.ease)

        };

        var reportChange = function() {

            if (typeof (options.onChange) === "function") options.onChange({
                current: current,
                page: Math.floor(current / options.stepCount),
                total: list.length,
                item: list[current],
                playing: options.autoplay
            });

        }

        var autoplay = function(force) {

            if (options.autoplay || force) {
                apInterval = setTimeout(next, options.timeout);
                options.autoplay = true;
            }

        }

        var stopAutoplay = function() {
            options.autoplay = false;
            clearTimeout(apInterval);
        }

        var init = function() {

            var i;

            if (options.autoplay > 0) {
                options.timeout = options.autoplay;
                options.autoplay = true;
            }

            if (!options.disableStyles) {
                if (canvasWidth == null) canvasWidth = $(this).width();
                content.width((canvasWidth + 50) * list.length);

                canvas.css({ overflow: "hidden", height: options.itemHeight });
                content.css({ overflow: "visible" });
                list.css({ "float": "left", overflow: "visible" });
            }

            /* Efecto loop infinito (duplicamos elementos) */
            if (options.loop && list.size() > options.stepCount) {
                var o, c;

                // Anteriores
                c = options.stepCount * 2
                for (i = list.size() - options.stepCount * 2; i < list.size(); i++) {
                    o = list.eq(i % list.length).clone(true).insertBefore(list.eq(0));
                    loopLeft[--c] = o;
                }

                // Posteriores
                c = 0;
                o = list.eq(list.size() - 1);
                for (i = 0; i < options.stepCount * 2; i++) {
                    o = list.eq(i % list.length).clone(true).insertAfter(o);
                    loopRight[c++] = o;
                }

            }

            /* Aņadimos controles */
            if (list.length > options.stepCount) {

                $(options.controlsItem).each(function() {
                    var self = $(this);
                    var controls = createControls();

                    // Clonamos el objeto
                    if (controls.first) self.append(controls.first).append(" ");
                    if (controls.left) self.append(controls.left).append(" ");
                    for (i in controls.page) self.append(controls.page[i]).append(parseInt(i) < list.length - 1 ? options.pageSeparator : " ");
                    if (controls.right) self.append(controls.right).append(" ");
                    if (controls.last) self.append(controls.last).append(" ");
                });

                autoplay();

            }

            canvas.disableTextSelect();

            animate(true);

        };

        var next = function(e) {
            if (e && isNaN(e)) {
                e.preventDefault();
                stopAutoplay();
            }
            current += options.stepCount;
            if (current >= list.length) {
                if (options.loop) {
                    animate(true, loopLeft[Math.abs((current - options.stepCount) - list.length) - 1]);
                    current = current % list.length;
                } else current = list.length - options.stepCount;
            }
            animate();
            autoplay();
        };

        var prev = function(e) {
            if (e) {
                e.preventDefault();
                stopAutoplay();
            }
            current -= options.stepCount;
            if (current < 0) {
                if (options.loop) {
                    animate(true, loopRight[Math.abs(current + options.stepCount)]);
                    current = current + list.length;
                } else current = 0;
            }
            animate();
            autoplay();
        };

        var first = function(e) {
            if (e) e.preventDefault();
            current = 0;
            animate();
        };

        var last = function(e) {
            if (e) e.preventDefault();
            current = list.length - options.stepCount;
            animate();
        };

        var page = function(n, e) {
            if (e) e.preventDefault();
            current = parseInt(n) * options.stepCount;
            animate();
        };

        init();

        // Acceso externo
        this.next = next;
        this.prev = prev;
        this.first = first;
        this.last = last;
        this.page = page;
        this.setTimeout = function(t) { options.timeout = t; }
        this.getTimeout = function() { return options.timeout; }
        this.isPlaying = function() { return options.autoplay; }
        this.start = function() { autoplay(true); reportChange(); }
        this.stop = function() { stopAutoplay(); reportChange(); }
        this.change = reportChange;


    });

}
