(function (a) {
    a.widget("ui.rcarousel", { _create: function () {
        var c = this, d = c.options, e = a(this.element), b;
        d.structure = c._createStructureObject();
        b = d.structure;
        c._checkOptionsValidity(c.options);
        if (a(e).children("div.wrapper").length === 1) { if (a(e).children("div.wrapper").find("ul > li").length < 1) { throw new Error("Inside DIV.wrapper you should have placed UL element with at least one LI element") } else { c._configure(true) } } else { if (a(e).children("div.wrapper").length > 1) { throw new Error("You are not allowed to use more than one div.wrapper in carousel's container!") } else { if (a(e).children("div.wrapper").length < 1) { c._configure(false) } } } c._trigger("start", null, null)
    }, _autoMode: function (e) {
        var c = this, d = c.options, b = d.structure;
        if (e === "next") { b.autoModeInterval = setInterval(function () { c.next() }, d.auto.interval) } else { b.autoModeInterval = setInterval(function () { c.prev() }, d.auto.interval) }
    }, _checkOptionsValidity: function (d) {
        var c = this, g = "", f, b, e;
        for (f in d) {
            b = d[f];
            switch (f) {
                case "visible": if (typeof b !== "number" || b <= 0 || (Math.ceil(b) - b > 0)) { throw new Error("visible should be defined as a positive integer number!") } break;
                case "step": if (b && typeof b !== "number" || b <= 0) { throw new Error("step should be a positive number") } else {
                        if (b < 1 || b > d.visible) {
                            for (e = 1; e <= Math.floor(d.visible); e++) { g += (e < Math.floor(b)) ? e + ", " : e } throw new Error("Only following mode.step values are correct: " + g)
                        }
                    } break;
                case "width": if (b && (isNaN(b) || typeof b !== "number" || b <= 0 || (Math.ceil(b) - b > 0))) { throw new Error("width should be a positive integer number!") } break;
                case "height": if (b && (isNaN(b) || typeof b !== "number" || b <= 0 || (Math.ceil(b) - b > 0))) { throw new Error("height should be a positive number!") } break;
                case "speed": if (!b && b !== 0) { throw new Error("speed should be defined as a number or a string") } if (typeof b === "number" && b < 0) { throw new Error("speed should be a positive number") } else { if (typeof b === "string" && !(b === "slow" || b === "normal" || b === "fast")) { throw new Error('Only "slow", "normal" and "fast" values are valid') } } break;
                case "remote": if (!b || !(typeof b === "object")) { throw new Error("remote should be defined as object with path and format properties in it!") } if (!(typeof b.path === "string")) { throw new Error("remote.path should be defined as string!") } if (!(typeof b.format === "string")) { throw new Error("remote.format should be defined as a string!") } else { if (!(b.format === "json" || b.format === "xml")) { throw new Error("remote.format: '" + b.format + "' is not valid. Only remote.format: 'json' and remote.format: 'xml' are valid!") } } break;
                case "navigation": if (!b || typeof b !== "object") { throw new Error("navigation should be defined as object with at least one of the properties: 'prev' or 'next' in it!") } if (b.prev && typeof b.prev !== "string") { throw new Error("navigation.prev should be defined as a string and points to '.class' or '#id' of an element") } if (b.next && typeof b.next !== "string") { throw new Error("navigation.next should be defined as a string and points to '.class' or '#id' of an element") } break;
                case "auto": if (typeof b.direction !== "string") { throw new Error("direction should be defined as a string") } if (!(b.direction === "next" || b.direction === "prev")) { throw new Error("direction: only 'right' and 'left' values are valid") } if (isNaN(b.interval) || typeof b.interval !== "number" || b.interval < 0 || (Math.ceil(b.interval) - b.interval > 0)) { throw new Error("interval should be a positive number!") } break;
                case "margin": if (isNaN(b) || typeof b !== "number" || b < 0 || (Math.ceil(b) - b > 0)) { throw new Error("margin should be a positive number!") } break
            }
        }
    }, _configure: function (c) {
        var d = this, e = d.options, b = e.structure;
        if (c) {
            d._setStructure();
            d._loadElements();
            b.hardcoded = true
        } else {
            d._createStructure();
            d.load();
            b.hardcoded = false
        } d._setCarouselWidth();
        d._setCarouselHeight();
        d._setEventHandlers("next");
        d._setEventHandlers("prev");
        d._setStep();
        if (e.auto.enabled) { d._autoMode(e.auto.direction) }
    }, _createNewElement: function (g, e) {
        var c = this, d = c.options, b = d.structure, f = a("<li></li>");
        a(f).width(d.width).height(d.height).addClass("ui-rcarousel-loader");
        if (d.orientation === "horizontal") {
            a(f).css("marginRight", d.margin)

        } else { a(f).css({ marginBottom: d.margin, "float": "none" }) } c._loadElement(g, function (h) { a(f).removeClass("ui-rcarousel-loader").append(h) });
        if (e === "prev") { a(b.list).prepend(f) } else {
            a(f).appendTo(b.list)

        }
    }, _createStructure: function () {
        var c = this, d = c.options, b = d.structure, g = a(this.element), f, e;

        f = a("<div class='wrapper'></div>").appendTo(g);
        b.wrapper = f;
        e = a("<ul></ul>").appendTo(f);
        b.list = e

    }, _createStructureObject: function () {
        var b = this;
        b.carousels[b.carousels.length] = { paths: [], pathsLen: 0, pages: [], firstPage: [], oldPageIndex: 0, pageIndex: 0, navigation: {}, animated: false };
        return b.carousels[b.carousels.length - 1]
    }, _generatePages: function () {
        var c = this, d = c.options, b = d.structure;
        function g() {
            var j;
            b.pages = [];
            b.firstPage = [];
            b.pageIndex = d.startAtPage;
            b.pages[0] = [];
            for (j = 0; j < d.visible; j++) {
                b.pages[0][b.pages[0].length] = b.paths[j];
                b.firstPage[j] = b.paths[j]
            }
        } function f(l) {
            var j = false, k;
            for (k = 0;
                                                               k < b.firstPage.length;
                                                                k++) {
                if (b.firstPage[k] === l[k]) { j = true } else {
                    j = false;
                    break
                }
            } return j
        } function e(n, j, l) {
            var m = l || b.pages.length, k;
            if (!l) { b.pages[m] = [] } for (k = n; k < j; k++) { b.pages[m].push(b.paths[k]) } return m
        } function h() {
            var i = b.paths.length, o = true, l = false, k = d.step, j, n, m; while (!f(b.pages[b.pages.length - 1]) || o) {
                o = false; j = k + d.visible;
                if (j > i) { j = i } if (j - k < d.visible) { l = true } else { l = false } if (l) {
                    n = e(k, j); e(0, d.visible - (j - k), n);
                    m = false;
                    if (k + d.step >= i) {
                        k = 0 - (j - k) + d.step;
                        m = true
                    }
                } else {
                    e(k, j);
                    m = false;
                    if (k + d.step >= i) {
                        k = 0;
                        m = true
                    }
                } if (!m) {
                    k += d.step;
                    m = false
                }
            } b.pages.length -= 1;
            if (d.startAtPage <= 0) { d.startAtPage = b.oldPageIndex = b.pageIndex = 0 } else { if (d.startAtPage > b.pages.length - 1) { d.startAtPage = b.oldPageIndex = b.pageIndex = b.pages.length - 1 } else { b.oldPageIndex = b.pageIndex = d.startAtPage } }
        } g();
        h()
    }, getTotalPages: function () {
        var c = this, d = c.options, b = d.structure;
        return b.pages.length
    }, goToPage: function (f) {
        var d = this, e = d.options, b = e.structure, c;
        if (!b.animated && f !== b.pageIndex) {
            b.animated = true;
            if (f > b.pages.length - 1) { f = b.pages.length - 1 } else { if (f < 0) { f = 0 } } b.pageIndex = f;
            c = f - b.oldPageIndex;
            if (c >= 0) { d._goToNextPage(c) } else { d._goToPrevPage(c) } b.oldPageIndex = f
        }
    }, load: function (i) {
        var d = this, e = d.options, c = e.structure, g, f, b, h;
        if (i) { d._checkOptionsValidity({ remote: i }) } g = i || {};
        f = g.path || e.remote.path;
        b = g.format || e.remote.format;
        a(c.list).empty();
        c.paths.length = 0;
        c.hardcoded = false;
        if (b === "json") {
            a.getJSON(f, function (j) {
                a.each(j.paths, function (k, l) { c.paths.push(l) });
                if (c.paths.length < e.visible) { throw new Error("At least " + e.visible + " elements are required") } d._generatePages();
                d._loadElements()
            })
        } else {
            if (b === "xml") {
                a.get(f, function (j) {
                    h = a(j).find("path");
                    a.each(h, function (k, l) { c.paths.push(a(l).text()) });
                    if (c.paths.length < e.visible) { throw new Error("At least " + e.visible + " elements are required") } d._generatePages();
                    d._loadElements()
                })
            }
        }
    }, _loadElement: function (e, f) {
        var c = new Image(), d;
        var i_srs = e.split('~');
        c.src = i_srs[0];
        var nav = i_srs[1] + ".html";
        c.setAttribute("onclick", "window.open('" + nav + "','_self',false);", true);
        c.setAttribute("style", "cursor:pointer",true);
        function b() {
            if (c.complete) {
                clearInterval(d);
                if (f) { f(c) }
            }
        } d = setInterval(b, 100)
    }, _loadElements: function (b, h) {
        var j = this, l = j.options, d = l.structure, f = h || "next", k = b || d.pages[l.startAtPage], c = 0, g = k.length, e = 0;
        if (f === "next") { for (e = c; e < g; e++) { j._createNewElement(k[e], f) } } else { for (e = g - 1; e >= c; e--) { j._createNewElement(k[e], f) } }
    }, _goToPrevPage: function (h) {
        var n = this, o = n.options, b = o.structure, c, g, e, f, k, d, j, l, m;
        k = b.oldPageIndex + h;
        c = b.pages[k].slice(0);
        g = b.pages[b.oldPageIndex];
        j = c[c.length - 1];
        for (f = g.length - 1; f >= 0; f--) {
            if (j === g[f]) {
                l = false;
                m = f;
                break
            } else { l = true }
        } if (!l) { while (m >= 0) { if (c[c.length - 1] === g[m]) { c.pop() } --m } } n._loadElements(c, "prev");
        e = o.width * c.length + (o.margin * c.length);
        if (o.orientation === "horizontal") {
            d = { scrollLeft: 0 };
            a(b.wrapper).scrollLeft(e)
        } else {
            d = { scrollTop: 0 };
            a(b.wrapper).scrollTop(e)
        } a(b.wrapper).animate(d, o.speed, function () {
            n._removeOldElements("last", c.length);
            b.animated = false;
            if (o.auto.enabled) {
                clearInterval(b.autoModeInterval);
                n._autoMode(o.auto.direction)
            } n._trigger("pageLoaded", null, { page: k })
        })
    }, _goToNextPage: function (j) {
        var n = this, o = n.options, c = o.structure, d, h, f, g, k, e, b, l, m;
        k = c.oldPageIndex + j;
        d = c.pages[k].slice(0);
        h = c.pages[c.oldPageIndex];
        b = d[0];
        for (g = 0; g < d.length; g++) {
            if (b === h[g]) {
                l = false;
                m = g;
                break
            } else { l = true }
        } if (!l) { while (m < h.length) { if (d[0] === h[m]) { d.shift() } ++m } } n._loadElements(d, "next");
        f = o.width * d.length + (o.margin * d.length);
        e = o.orientation === "horizontal" ? { scrollLeft: "+=" + f} : { scrollTop: "+=" + f };
        a(c.wrapper).animate(e, o.speed, function () {
            n._removeOldElements("first", d.length);
            if (o.orientation === "horizontal") { a(c.wrapper).scrollLeft(0) } else { a(c.wrapper).scrollTop(0) } c.animated = false;
            if (o.auto.enabled) {
                clearInterval(c.autoModeInterval);
                n._autoMode(o.auto.direction)
            } n._trigger("pageLoaded", null, { page: k })
        })
    }, next: function () {
        var c = this, d = c.options, b = d.structure;
        if (!b.animated) {
            b.animated = true;
            ++b.pageIndex;
            if (b.pageIndex > b.pages.length - 1) { b.pageIndex = 0 } c._goToNextPage(b.pageIndex - b.oldPageIndex);
            b.oldPageIndex = b.pageIndex
        }
    }, prev: function () {
        var c = this, d = c.options, b = d.structure;
        if (!b.animated) {
            b.animated = true;
            --b.pageIndex;
            if (b.pageIndex < 0) { b.pageIndex = b.pages.length - 1 } c._goToPrevPage(b.pageIndex - b.oldPageIndex);
            b.oldPageIndex = b.pageIndex
        }
    }, _removeOldElements: function (b, j) {
        var f = this, g = f.options, e = g.structure, h, d, c;
        for (h = 0; h < j; h++) {
            if (b === "first") { a("li", e.list).eq(0).remove() } else {
                d = a("li", e.list);
                c = a(d).length;
                a(d).eq(c - 1).remove()
            }
        }
    }, _setOption: function (e, g) {
        var c = this, d = c.options, b = d.structure, f;
        switch (e) {
            case "step": c._checkOptionsValidity({ step: g });
                c._setStep(g);
                c._generatePages();
                a(b.list).empty();
                c._loadElements();
                a.Widget.prototype._setOption.apply(this, arguments);
                break;
            case "speed": c._checkOptionsValidity({ speed: g });
                d.speed = g;
                a.Widget.prototype._setOption.apply(this, arguments);
                break;
            case "navigation": c._checkOptionsValidity({ navigation: g });
                if (g.next) { c._setEventHandlers("next") } if (g.prev) { c._setEventHandlers("prev") } a.Widget.prototype._setOption.apply(this, arguments);
                break;
            case "auto": f = a.extend(d.auto, g);
                c._checkOptionsValidity({ auto: f });
                if (d.auto.enabled) { c._autoMode(d.auto.direction) } else { clearInterval(b.autoModeInterval) }
        }
    }, _setStep: function (f) {
        var c = this, d = c.options, b = d.structure, e;
        e = f || d.step;
        d.step = e;
        b.step = d.width * e
    }, _setStructure: function () {
        var c = this, h = a(this.element), d = c.options, b = d.structure, f, g, e;
        b.wrapper = a("div.wrapper", h);
        b.list = a("ul", b.wrapper);
        f = a("li", b.list);
        if (f.length < d.visible) { throw new Error("At least " + d.visible + " elements are required") } for (e = f.length - 1; e >= 0; e--) {
            f = a("li", b.list);
            g = a(f).eq(f.length - 1);
            a(g).remove();
            b.paths.unshift(a("img", g).attr("src") + "~" + a("img", g).attr("id"))

        } c._generatePages();
        b.navigation.next = a(d.navigation.next);
        b.navigation.prev = a(d.navigation.prev)
    }, _setCarouselHeight: function () {
        var d = this, e = d.options, c = e.structure, b;
        b = (e.orientation === "vertical") ? e.visible * e.height + e.margin * (e.visible - 1) : e.height;
        a(c.wrapper).height(b)
    }, _setCarouselWidth: function () {
        var c = this, d = c.options, b = d.structure, e;
        e = (d.orientation === "horizontal") ? d.visible * d.width+ d.margin * (d.visible - 1) : d.width;
        a(b.wrapper).css({ width: e, overflow: "hidden" })
    }, _setEventHandlers: function (d) {
        var b = this, c = b.options;
        if (d === "next") { a(c.navigation.next).click(function () { b.next() }) } if (d === "prev") { a(c.navigation.prev).click(function () { b.prev() }) }
    }, options: { visible: 4, step: 1, width: 150, height: 80, speed: 1000, margin: 0, orientation: "horizontal", structure: null, auto: { enabled: false, direction: "next", interval: 5000 }, startAtPage: 0, navigation: { next: "#ui-rcarousel-next", prev: "#ui-rcarousel-prev"} }, carousels: []
    })
} (jQuery));

