var jQuery = jQuery || {};
var bm = bm || {};


bm.filterContent = (function ($) {

    var FilterContent = function (element, options) {
        this.$element = $(element);

        this.options = $.extend({}, FilterContent.DEFAULTS, options);
        this.options.showItemsInitial = this.options.showitems;
        this.$items = null;

        this.current = {
            filter: {},
            showitems: 0
        }
        this.init();
    };

    FilterContent.VERSION = '1.0.2';


    FilterContent.DEFAULTS = {
        startWith: 1,
        toggle: true,
        showitems: 0,
        loadmore: 4,
        itemCount: 0,
        itemsLeft:0,
        filter: {
        },
        show: 'all',
        classes: {
            hide: 'hideMe',
            show: 'showMe'
        }
    };

    FilterContent.prototype.init = function () {
        this.$element.data('bm.filtercontent', this);
        var elementId = this.$element.attr('id');
        //this.$items = this.$element.children().filter('.js-contentfilter-item');
        this.$items = this.$element
            .find('.js-filtercontent-item')
            .filter('[data-filter-parent="#' + elementId + '"]')

        //this.$items.css('border', '2px solid red');
        //this.$items.addClass('hidden');
        this.filter();
    };

    FilterContent.prototype.update = function (options) {
        if (options){
            options.filter = $.extend({}, this.options.filter, options.filter);
            this.options = $.extend({}, this.options, options);
        }
        this.filter();
    };


    FilterContent.prototype.showMore = function () {
        var currentLimit = this.options.showitems;
        var newLimit = (this.options.showitems + this.options.loadmore);
        this.options.showitems = newLimit;
        this.filter();
    };


    FilterContent.prototype.filter = function () {
        var self = this;
        var filterClass = 'filterComplete';

        var filteredItems = this.$items;

        var currentHeight = this.$element.height();
        var currentWidth = this.$element.width();

        //this.$element.css('min-height', currentHeight);
        this.$element.css('width', currentWidth);
        this.$element.css('overflow', 'hidden');

        // reset item count
        if (JSON.stringify(this.current.filter) != JSON.stringify(this.options.filter)) {
            this.current.filter = $.extend({}, this.current.filter, this.options.filter);
            //this.options.showitems = this.options.showItemsInitial;
            //this.$element.css('min-height', '300px');
        }

        // filter items
        $.each(this.options.filter, function (filterGroup, filterValues) {
            filteredItems = filterItems(filteredItems, filterGroup, filterValues);
        });

        // calc item counts
        this.options.itemCount = filteredItems.length;
        this.options.itemsLeft = this.options.itemCount - this.options.showitems;

        // paginate items
        if (this.options.showitems > 0) {
            filteredItems = paginateItems.call(this, filteredItems, this.options.showitems);
        }

        // filter
        filteredItems.addClass(filterClass);

        this.$items.not('.' + filterClass).addClass('hidden');
        this.$items.filter('.' + filterClass).removeClass('hidden');
        this.$items.removeClass(filterClass);


        if (this.options.itemsLeft) {
            var paginateEvent = $.Event('paginated.bm.filterContent', {
                relatedTarget: this
            });
            this.$element.trigger(paginateEvent);
        }

        var updatedEvent = $.Event('updated.bm.filterContent', {
            relatedTarget: this
        });

        //this.$element.css('min-height', '');
        this.$element.css('width', '');
        this.$element.css('overflow', '');
        this.$element.trigger(updatedEvent);

    };


    function filterItems(filterItems, filterKey, filterValue) {
        if (filterValue == 'all') {
            return filterItems;
        }

        var filterClass     = 'filter';
        var forceHideClass  = 'forceHide';
        var negate = false;
        filterItems.addClass(filterClass);

        if (filterValue == '') {
            filterValue = 'all';
        }
        $.each(filterValue.split(','), function (key, value) {
            if (value === 'all') {
                filterItems.removeClass(filterClass);
            }

            negate = (value.indexOf('!') == 0);
            if (negate){
                value = value.substring(1);
                filterItems
                    .not('.'+forceHideClass)
                    .filter('[data-filter-by-' + filterKey + ']')
                    .removeClass(filterClass)
                    .filter('[data-filter-by-' + filterKey + '="' + value + '"], [data-filter-by-' + filterKey + '*=",' + value + ',"], [data-filter-by-' + filterKey + '^="' + value + ',"], [data-filter-by-' + filterKey + '$=",' + value + '"]')
                    .addClass(forceHideClass);
            } else {
                filterItems
                    .not('.'+forceHideClass)
                    .filter('[data-filter-by-' + filterKey + '="' + value + '"], [data-filter-by-' + filterKey + '*=",' + value + ',"], [data-filter-by-' + filterKey + '^="' + value + ',"], [data-filter-by-' + filterKey + '$=",' + value + '"]')
                    .removeClass(filterClass);
            }

        });

        filterItems.filter('.'+forceHideClass).addClass(filterClass).removeClass(forceHideClass);

        filterItems.each(function(key, value) {
            if (typeof $(this).attr('data-filter-by-'+filterKey) == 'undefined') {
                $(this).removeClass(filterClass);
            }
        });
        var filteredItems = filterItems.not('.' + filterClass);

        filterItems.removeClass(filterClass);
        return filteredItems;
    }

    function paginateItems(filterItems, limit) {
        var filterCounter = 0,
            filterClass = 'paginate';

        this.$items.each(function () {
            $(this).data('page', false);
        });

        filterItems.each(function () {
            if (filterCounter < limit) {
                $(this).addClass(filterClass);
                filterCounter++;
            } else {
                return false;
            }
        });

        filterItems = filterItems.filter('.' + filterClass);

        filterItems.removeClass(filterClass);
        return filterItems;
    };

    // Contentfilter PLUGIN DEFINITION
    // ==========================

    function Plugin(option) {
        return this.each(function () {
            var $this = $(this);
            var pluginData = $this.data('bm.filtercontent');

            if (!pluginData) {
                var options = $.extend({}, FilterContent.DEFAULTS, $this.data(), typeof option === 'object' && option);
                pluginData = new FilterContent(this, options);
                $this.data('bm.filtercontent', pluginData);
            } else {
                if (typeof option === 'string') {
                    pluginData[option]();
                } else {
                    pluginData.update(option);
                }
            }
        });

    }

    var old = $.fn.filtercontent;

    $.fn.filtercontent = Plugin;
    $.fn.filtercontent.Constructor = FilterContent;


    // Contentfilter NO CONFLICT
    // ====================

    $.fn.filtercontent.noConflict = function () {
        $.fn.filtercontent = old;
        return this;
    };


    // Contentfilter DATA-API
    // =================





}(jQuery));
