var bannerSlider;

(function($) {
    bannerSlider = function(sliderBodyEl, sliderLeftEl, sliderRightEl, intervalEl, iConfig)
    {
        var that = this,
            config = {quant      : 4, //кол-во предлжений в блоке
                      step       : 1,
                      url        : '/advertising/banners/slider/',
                      bannerId   : null,
                      hideArrows : true,
                      classes    : {bodyLoading : 'slider-loading',
                                    item        : 'slider-item',
                                    itemLoading : 'slider-item-loading'}},
            sliders = [],//массив со слайдерами
            interval = {start : null,
                        end   : null},
            inited = false,
            total = null,
            loadingDivs = [];

        this.setConfig = function()
        {
            if (typeof(iConfig) == 'object') {
                config = $.extend(config, iConfig);
            }
        }

        this.init = function()
        {
            __showBodyLoading();

            __loadData(0, config.quant, function() {
                __hideBodyLoading();

                sliderBodyEl.empty();
                $.each(sliders, function(key, val) {
                    var item = __createItem(val, true);
                    __bindOnClick($(item), val.object_url, val.object_open);

                    sliderBodyEl.append(item);
                });

                __updateInterval(0, config.quant - 1);
                inited = true;

                __checkArrows(interval);
                __checkInterval(interval);
            });
        }

        __setup();

        function __bindOnClick(el, url, open)
        {
            el.bind('click', function(e) {
                if (open == 'external') {
                    window.open(url);
                } else {
                    window.location = url;
                }
            });
        }

        function __updateInterval(start, end)
        {
            interval.start = start;
            interval.end = end;
        }

        function __createItem(props, content)
        {
            var div = document.createElement('div');
            div.className = config.classes.item;

            if (content) {
                div.innerHTML = __getItemContent(props);
            }

            return div;
        }

        function __getItemContent(props)
        {
            var content = '\
            <div class="object-img"> \
                <img src="' + props.thumb.path + '" width="' + props.thumb.width + '" height="' + props.thumb.height + '" /> \
            </div> \
            <div class="object-name">' + props.object_name + '</div> \
            <div class="object-price"> \
                Price: $ ' + props.object_price + ' \
            </div>';

            return content;
        }

        function __loadData(offset, limit, callback)
        {
            var getParams = {id     : config.bannerId,
                             limit  : limit,
                             offset : offset};

            if (!inited) {
                getParams.total = 1;
            }

            $.getJSON(config.url, getParams, function(data) {
                sliders = sliders.concat(data.sliders);

                if (typeof(data.total) != 'undefined') {
                    total = data.total;
                }

                if (typeof(callback) == 'function') {
                    callback.call(that);
                }
            });
        }

        function __showBodyLoading()
        {
            sliderBodyEl.addClass(config.classes.bodyLoading);
        }

        function __hideBodyLoading()
        {
            sliderBodyEl.removeClass(config.classes.bodyLoading);
        }

        function __setup()
        {
            if (typeof(sliderBodyEl) != 'object' || typeof(sliderLeftEl) != 'object' || typeof(sliderRightEl) != 'object') {
                throw 'Incorrect input params';
            }

            that.setConfig(iConfig);

            __setupEvents();
        }

        function __setupEvents()
        {
            sliderLeftEl.bind('click', __onLeftClick);
            sliderRightEl.bind('click', __onRightClick);
        }

        function __onLeftClick(e)
        {
            e.preventDefault();

            var newInterval = __countNewInterval(-config.step);
            var realShift = interval.start - newInterval.start;

            if (realShift == 0) {
                return;
            }

            __checkArrows(newInterval);
            __checkInterval(newInterval);

            __loadMissing(newInterval, -realShift, function() {
                var idx = newInterval.start;
                for (var i = realShift - 1; i >= 0  ; i--) {
                    loadingDivs[i].removeClass(config.classes.itemLoading);
                    loadingDivs[i].html(__getItemContent(sliders[idx]));
                    __bindOnClick(loadingDivs[i], sliders[idx].object_url, sliders[idx].object_open);
                    idx++;
                }

                __updateInterval(newInterval.start, newInterval.end);
            });
        }

        function __onRightClick(e)
        {
            e.preventDefault();

            var newInterval = __countNewInterval(config.step);
            var realShift = newInterval.start - interval.start;

            if (realShift == 0) {
                return;
            }

            __checkArrows(newInterval);
            __checkInterval(newInterval);

            __loadMissing(newInterval, realShift, function() {
                var idx = interval.end + 1;
                for (var i = 0; i < realShift; i++) {
                    loadingDivs[i].removeClass(config.classes.itemLoading);
                    loadingDivs[i].html(__getItemContent(sliders[idx]));
                    __bindOnClick(loadingDivs[i], sliders[idx].object_url, sliders[idx].object_open);
                    idx++;
                }

                __updateInterval(newInterval.start, newInterval.end);
            });
        }

        function __loadMissing(newInterval, shift, callback)
        {
            var offset = null;
            var limit = null;

            for (var i = newInterval.start; i <= newInterval.end; i++) {
                if (typeof(sliders[i]) == 'undefined' && null === offset) {
                    offset = i;
                    break;
                }
            }

            var divs = $('div.' + config.classes.item, sliderBodyEl);
            loadingDivs = [];

            if (shift > 0) {
                for (var i = 0; i < shift; i++) {
                    $(divs[i]).remove();
                    var newDiv = $(__createItem());
                    newDiv.addClass(config.classes.itemLoading);
                    loadingDivs.push(newDiv)
                    sliderBodyEl.append(newDiv);
                }
            } else {
                for (var i = divs.length - 1, j = 0; j < Math.abs(shift); i--, j++) {
                    $(divs[i]).remove();
                    var newDiv = $(__createItem());
                    newDiv.addClass(config.classes.itemLoading);
                    loadingDivs.push(newDiv)
                    sliderBodyEl.prepend(newDiv);
                }
            }

            if (null !== offset) {
                limit = newInterval.end - offset + 1;
                __loadData(offset, limit, callback);
            } else if (typeof(callback) == 'function') {
                callback.call(that);
            }
        }

        function __countNewInterval(shift)
        {
            var out = {};

            out.start = interval.start + shift;
            out.end = interval.end + shift;

            if (shift < 0 && out.start < 0) {
                out.end += Math.abs(out.start);
                out.start = 0;
            } else if (shift > 0 && out.end > (total - 1)) {
                out.start -= out.end - (total - 1);
                out.end = total - 1;
            }

            return out;
        }

        function __checkInterval(interval)
        {
            if (interval.end - interval.start > 1) {
                var cnt = (interval.start + 1) + ' - ' + (interval.end + 1) +  ' of ' + total;
                intervalEl.html(cnt);
            } else {
                var cnt = (interval.start + 1) +  ' of ' + total;
                intervalEl.html(cnt);
            }
        }

        function __checkArrows(interval)
        {
            if (interval.start == 0) {
                sliderLeftEl.css('visibility', 'hidden');
            } else {
                sliderLeftEl.css('visibility', 'visible');
            }

            if (interval.end == (total - 1)) {
                sliderRightEl.css('visibility', 'hidden');
            } else {
                sliderRightEl.css('visibility', 'visible');
            }
        }
    };
}) (jQuery);