/* // JCARRUSEL 050307 // */
jQuery.fn.extend({
    jcarousel: function(o) {
        return this.each(function() {
            new jQuery.jcarousel(this, o);
        });
    }
});

jQuery.extend({
    jcarousel: function(e, o) {
        var publ = this;
       publ.scope = function() { return priv.scope; };
        publ.list = function() { return priv.list; };
        publ.size = function() { return priv.size; };
        publ.init = function(o) { return priv.init(o); };
        publ.get = function(idx) { return priv.get(idx); };
        publ.add = function(idx, html) { return priv.add(idx, html); };
        publ.available = function(first, last) { return last == undefined ? priv.end >= first : priv.end >= last; };
       publ.loaded = function() { priv.loaded(); };
        publ.next = function() { priv.next(); };
        publ.prev = function() { priv.prev(); };
        publ.scroll = function(i) { if (publ.available(i)) { priv.scroll(i); } };
        var priv = {
            o: {
                orientation: "horizontal",
                itemStart: 1,
                itemVisible: 3,
                itemScroll: null,
                scrollAnimation: "slow",
                autoScroll: 0,
                autoScrollStopOnInteract: true,
                autoScrollStopOnMouseover: false,
                autoScrollResumeOnMouseout: false,
                wrap: false,
                wrapPrev: false,
                itemWidth: null,
                itemHeight: null,
                loadItemHandler: null,
                nextButtonStateHandler: null,
                prevButtonStateHandler: null,
                itemFirstInHandler: null,
                itemFirstOutHandler: null,
                itemLastInHandler: null,
                itemLastOutHandler: null,
                itemVisibleInHandler: null,
                itemVisibleOutHandler: null,
                noButtons: false,
                buttonNextHTML: '<img src="images/btns/noti_siguiente2.jpg" title="Ver siguientes" />',
                buttonPrevHTML: '<img src="images/btns/noti_atraz2.jpg" title="Ver anteriores" />'
            },
            scope: null,
            list: null,
            horiz: true,
            top: 0,
            left: 0,
            size: 0,
            end: 0,
            first: 0,
            prevFirst: 0,
            last: 0,
            prevLast: 0,
            inAnimation: false,
            autoTimer: null,
            nextClick: function() { priv.next(); },
            prevClick: function() { priv.prev(); },
            itemFormat: {
                "float":      "left",
                "styleFloat": "left",
                "overflow":   "hidden",
                "listStyle":  "none"
            },
            options: function(o) {
                if (o)
                    jQuery.extend(priv.o, o);

                priv.o.itemStart = Math.max(1, priv.intval(priv.o.itemStart));
                priv.o.itemScroll = priv.o.itemScroll || priv.o.itemVisible;

                if (priv.o.itemWidth)
                    priv.itemFormat.width  = priv.o.itemWidth + "px";

                if (priv.o.itemHeight)
                     priv.itemFormat.height = priv.o.itemHeight + "px";

                priv.horiz = priv.o.orientation == "vertical" ? false : true;
            },
            init: function(o) {
                priv.options(o);
                if (priv.size == 0) {
                    var dummy = priv.format(document.createElement("li"), 1).get(0);
                    priv.list.appendChild(dummy);
                }
                var i = jQuery("li", priv.list).get(0);
                var itemWidth  = i.offsetWidth + priv.margin(i, "marginLeft") + priv.margin(i, "marginRight");
                var itemHeight = i.offsetHeight + priv.margin(i, "marginTop") + priv.margin(i, "marginBottom");
                if (priv.horiz) {
                    priv.dimension = itemWidth;
                    var clipW  = itemWidth * priv.o.itemVisible - priv.margin(i, "marginRight");
                    var clipH  = itemHeight;
                } else {
                    priv.dimension = itemHeight;
                    var clipW  = itemWidth;
                    var clipH  = itemHeight * priv.o.itemVisible - priv.margin(i, "marginBottom");
                }
                jQuery(".jcarousel-clip", priv.scope).css({
                    "zIndex": "2",
                    "padding": 0,
                    "margin": 0,
                    "width":  clipW + "px",
                    "height": clipH + "px",
                    "overflow": "hidden",
                    "position": "relative"
                });
                if (dummy != undefined)
                    priv.list.removeChild(dummy);
                priv.resize();
            },
            prepare: function(e, o) {
                priv.options(o);
                if (e.nodeName == "UL" || e.nodeName == "OL") {
                    priv.list = e;
                    var scope = jQuery(priv.list).parent().get(0);
                    if (jQuery.className.has(scope.className, "jcarousel-clip")) {
                        if (!jQuery.className.has(jQuery(scope).parent().get(0).className, "jcarousel-scope"))
                            scope = jQuery(scope).wrap('<div class="jcarousel-scope"></div>');
                        scope = jQuery(scope).parent().get(0);
                    } else if (!jQuery.className.has(scope.className, "jcarousel-scope"))
                        scope = jQuery(priv.list).wrap('<div class="jcarousel-scope"></div>').parent().get(0);
                    priv.scope = scope;
                } else {
                    priv.scope = e;
                    priv.list = jQuery("ul", priv.scope).get(0) || jQuery("ol", priv.scope).get(0);
                }
                priv.size = priv.end = jQuery("li", priv.list).size();
                if (priv.size > 0) {
                    var idx = 1;
                    jQuery("li", priv.list).each(function() { priv.format(this, idx++); });
                }
                if (!jQuery.className.has(jQuery(priv.list).parent().get(0).className, "jcarousel-clip"))
                    jQuery(priv.list).wrap('<div class="jcarousel-clip"></div>');
                if (!priv.o.noButtons) {
                    if (jQuery(".jcarousel-prev", priv.scope).size() == 0) {
                        var dummy = jQuery(document.createElement("div")).html(priv.o.buttonPrevHTML).get(0);
                        jQuery(".jcarousel-clip", priv.scope).before(jQuery(dummy.firstChild).addClass("jcarousel-prev"));
                    }
                    if (jQuery(".jcarousel-next", priv.scope).size() == 0) {
                        var dummy = jQuery(document.createElement("div")).html(priv.o.buttonNextHTML).get(0);
                        jQuery(".jcarousel-clip", priv.scope).before(jQuery(dummy.firstChild).addClass("jcarousel-next"));
                    }
                    jQuery(".jcarousel-prev", priv.scope).css({"zIndex": "3"});
                    jQuery(".jcarousel-next", priv.scope).css({"zIndex": "3"});
                }
                if (priv.o.autoScrollStopOnMouseover) {
                    if (priv.o.autoScrollResumeOnMouseout) {
                        jQuery(".jcarousel-clip", priv.scope).bind("mouseover", function() { priv.stopAuto(); }).bind("mouseout", function() { priv.startAuto(); });
                    } else {
                        jQuery(".jcarousel-clip", priv.scope).bind("mouseover", function() { priv.disableAuto(); });
                    }
                }
                priv.top  = 0; //priv.intval(jQuery(priv.list).css("top"));
                priv.left = 0; //priv.intval(jQuery(priv.list).css("left"));
                jQuery(priv.list).css({
                    "zIndex": "1",
                    "position": "relative",
                    "top": priv.top + "px",
                    "left": priv.left + "px",
                    "margin": 0,
                    "padding": 0
                }).addClass("jcarousel-list");
                jQuery(priv.scope).addClass("jcarousel-scope").show().find(":hidden").show();
            },
            get: function(idx) {
                return jQuery(".jcarousel-item-" + idx, priv.list);
            },
            add: function(idx, s) {
                var item = priv.get(idx);
                if (item.size() == 0) {
                    var item = priv.format(document.createElement("li"), idx);
                    jQuery(priv.list).append(item);
                    priv.size++;
                    if (priv.size > priv.end)
                        priv.end = priv.size;
                    priv.resize();
                }
                return item.html(s);
            },
            available: function(first, last) {
                if (priv.end >= last)
                    return true;
                priv.end = last;
                return false;
            },
            load: function(first, last) {
                if (priv.o.loadItemHandler == null)
                    return priv.loaded();
                priv.buttons(false, false);
                priv.o.loadItemHandler(publ, first, last, priv.available(first, last));
            },
            loaded: function() {
                if (priv.first > 1 && priv.last < priv.size) {
                    priv.buttons(true, true);
                } else if (priv.first == 1 && priv.last < priv.size) {
                    priv.buttons(true, priv.o.wrapPrev);
                } else if (priv.first > 1 && priv.last >= priv.size) {
                    priv.buttons(priv.o.wrap, true);
                }
            },
            next: function() {
                priv.stopAuto();
                if (priv.o.autoScrollStopOnInteract)
                    priv.disableAuto();
                priv.doNext();
            },
            doNext: function() {
                priv.scroll((priv.o.wrap && priv.last == priv.size) ? 1 : priv.first + priv.o.itemScroll);
                if (priv.o.wrap || priv.last < priv.size)
                    priv.startAuto();
            },
            prev: function() {
                priv.stopAuto();
                if (priv.o.autoScrollStopOnInteract)
                    priv.disableAuto();
                priv.doPrev();
            },
            doPrev: function() {
                priv.scroll((priv.o.wrapPrev && priv.first == 1) ? priv.size - priv.o.itemVisible + 1 : priv.first - priv.o.itemScroll);
                priv.startAuto();
            },
            scroll: function(idx) {
                if (priv.inAnimation)
                    return;
                priv.inAnimation = false;
                priv.prevFirst = priv.first;
                priv.prevLast  = priv.last;
                idx = idx < 1 ? 1 : idx;
                var last = idx + priv.o.itemVisible - 1;
                last = (last > priv.size) ? priv.size : last;
                var first = last - priv.o.itemVisible + 1;
                first = (first < 1) ? 1 : first;
                last = first + priv.o.itemVisible - 1;
                priv.first = first;
                priv.last  = last;
                priv.animate();
            },
            animate: function() {
                var pos = priv.dimension * (priv.first - 1) * -1;

                priv.notify(priv.prevFirst, priv.prevLast, priv.first, priv.last, "onBeforeAnimation");

                if (priv.o.scrollAnimation) {
                    priv.inAnimation = true;
                    jQuery(priv.list).animate(priv.horiz ? {"left": pos} : {"top": pos}, priv.o.scrollAnimation, function() { priv.scrolled(); });
                } else {
                    jQuery(priv.list).css(priv.horiz ? "left" : "top", pos + "px");
                    priv.scrolled();
                }
            },
            scrolled: function() {
                if (priv.first == 1)
                    jQuery(priv.list).css("top", priv.top + "px").css("left", priv.left + "px");
                priv.inAnimation = false;
                priv.notify(priv.prevFirst, priv.prevLast, priv.first, priv.last, "onAfterAnimation");
                priv.load(priv.last + 1, priv.last + priv.o.itemScroll);
            },
            handler: function(handler, evt, state, i1, i2, i3, i4) {
                if (priv.o[handler] == undefined || (typeof priv.o[handler] != 'object' && evt != "onAfterAnimation"))
                    return;
                var handler = typeof priv.o[handler] == 'object' ? priv.o[handler][evt] : priv.o[handler];
                if (typeof handler != 'function')
                    return;
                if (i2 == undefined) {
                    priv.get(i1).each(function() { handler(publ, this, i1, state); });
                    return;
                }
                for (var i = i1; i <= i2; i++) {
                    if (!(i >= i3 && i <= i4))
                        priv.get(i).each(function() { handler(publ, this, i, state); });
                }
            },
            notify: function(prevFirst, prevLast, first, last, evt) {
                var state = prevFirst == 0 ? "init" : (prevFirst < first ? "next" : "prev");
                if (prevFirst != first) {
                    priv.handler("itemFirstOutHandler", evt, state, prevFirst);
                    priv.handler("itemFirstInHandler", evt, state, first);
                }
                if (prevLast != last) {
                    priv.handler("itemLastOutHandler", evt, state, prevLast);
                    priv.handler("itemLastInHandler", evt, state, last);
                }
                priv.handler("itemVisibleInHandler", evt, state, first, last, prevFirst, prevLast);
                priv.handler("itemVisibleOutHandler", evt, state, prevFirst, prevLast, first, last);
            },
            buttons: function(next, prev) {
                if (priv.o.noButtons)
                    return;
                jQuery(".jcarousel-next", priv.scope)[next ? "bind" : "unbind"]("click", priv.nextClick)[next ? "removeClass" : "addClass"]("jcarousel-next-disabled")[next ? "removeAttr" : "attr"]("disabled", true);
                jQuery(".jcarousel-prev", priv.scope)[prev ? "bind" : "unbind"]("click", priv.prevClick)[prev ? "removeClass" : "addClass"]("jcarousel-prev-disabled")[prev ? "removeAttr" : "attr"]("disabled", true);

                if (priv.o.nextButtonStateHandler != null)
                    jQuery(".jcarousel-next", priv.scope).each(function() { priv.o.nextButtonStateHandler(publ, this, next); });

                if (priv.o.prevButtonStateHandler != null)
                    jQuery(".jcarousel-prev", priv.scope).each(function() { priv.o.prevButtonStateHandler(publ, this, prev); });
            },
            startAuto: function() {
                if (priv.o.autoScroll > 0)
                    priv.autoTimer = setTimeout(function() { priv.doNext(); }, priv.o.autoScroll * 1000);
            },
            stopAuto: function() {
                if (priv.autoTimer == null)
                    return;
                clearTimeout(priv.autoTimer);
                priv.autoTimer = null;
            },
            disableAuto: function() {
                priv.stopAuto();
                priv.o.autoScroll = 0;
            },
            resize: function() {
                if (priv.size == 0)
                    return;
                if (priv.horiz)
                    jQuery(priv.list).css("width", priv.size * priv.dimension + 100 + "px");
                else
                    jQuery(priv.list).css("height", priv.size * priv.dimension + 100 + "px");
            },
            format: function(item, idx) {
                return jQuery(item).css(priv.itemFormat).addClass("jcarousel-item-" + idx);
            },
            margin: function(e, p) {
                if (p == "marginRight" && jQuery.browser.safari) {
                    var old = {"display": "block", "float": "none", "width": "auto"}, oWidth, oWidth2;

                    jQuery.swap(e, old, function() { oWidth = e.offsetWidth; });

                    old["marginRight"] = 0;
                    jQuery.swap(e, old, function() { oWidth2 = e.offsetWidth; });

                    return oWidth2 - oWidth;
                }
                return priv.intval(jQuery.css(e, p));
            },
            intval: function(v) {
                v = parseInt(v);
                return isNaN(v) ? 0 : v;
            }
        };
        priv.prepare(e, o);
        priv.init();
        priv.buttons(false, false);
        priv.load(1, priv.o.itemStart + priv.o.itemVisible);
        priv.scroll(priv.o.itemStart);
        priv.startAuto();
    }
});


