(function ($) {
    var defaults = {
        currentPage: 1,
        allItems: 0,
        lastPage: 1,
        startPage: 1,
        itemsPerPage: 5,
        previousPageSymbol: '<',
        nextPageSymbol: '>',
        paginatorPosition: 'bottom',
        showIfSinglePage: false,
        currentActive: null,
        gotoElement: 1,
        paginatorType: 1
    }, windowLoaded = false;

    $.jpaginator = function (e, o) {
        this.options = $.extend({}, defaults, o || {});
        var self = this;


        this.options.allItems = $(e).children().length;
        //draw the jpaginator
        switch (this.options.paginatorPosition) {
            case 'top': { $(e).html('<div class="paginator"></div><div class="paginator_elemente">' + $(e).html() + '</div>'); break; }
            case 'bottom': { $(e).html('<div class="paginator_elemente">' + $(e).html() + '</div><div class="paginator"></div>'); break; }
            case 'both': { $(e).html('<div class="paginator"></div><div class="paginator_elemente">' + $(e).html() + '</div><div class="paginator"></div>'); break; }
            default: { $(e).html('<div class="paginator_elemente">' + $(e).html() + '</div><div class="paginator"></div>'); }
        }
        if (this.options.allItems % this.options.itemsPerPage == 0) {
            this.options.lastPage = parseInt(this.options.allItems / this.options.itemsPerPage);
        } else {
            this.options.lastPage = parseInt(this.options.allItems / this.options.itemsPerPage) + 1;
        }

        if ((this.options.startPage < 1) || (this.options.startPage > this.options.lastPage)) {
            this.options.startPage = 1;
        }

        if (!this.options.showIfSinglePage) {
            if (this.options.lastPage > 1) {
                a = 'b';
                self.appendContent(e, self, false);
            }
        } else {
            self.appendContent(e, self, false); // call function to show start page for first time. Fading effect is not required initially.
        }
    }
    var $jc = $.jpaginator;

    $jc.fn = $jc.prototype = {
        jpaginator: '0.0.1'
    };
    $jc.fn.extend = $jc.extend = $.extend;
    $jc.fn.extend({

        createPaginator: function (e) {
            var self = this;
            var e_old = e;
            $(e).find(".paginator").html("");
            style = '';
            stylebtnLeft = '';
            stylebtnRight = '';

            if (this.options.currentPage == 1) {
                stylebtnLeft += '<a href="#" class="left inactive" pg_setup="f"><img src="' + window.gm_pg_l + '" width="21" height="21" /></a>';
            } else {
                stylebtnLeft += '<a href="#" class="active left" pg_setup="-1"><img src="' + window.gm_pg_l + '" width="21" height="21" /></a>';
            }

            for (var i = 1; i <= this.options.lastPage; i++) {
                if (i == this.options.currentPage) {
                    style += '<a href="#" class="active" pg_setup="f"><img src="' + window.gm_pg_a_n + '" width="12" height="12" class="normal" /><img src="' + window.gm_pg_a_a + '" width="12" height="12" class="active" /></a>';
                } else {
                    style += '<a href="#" class="inactive" pg_setup="' + i + '"><img src="' + window.gm_pg_a_n + '" width="12" height="12" class="normal" /><img src="' + window.gm_pg_a_a + '" width="12" height="12" class="active" /></a>';
                }
            }


            if (this.options.currentPage == this.options.lastPage) {
                stylebtnRight += '<a href="#" class="inactive right" pg_setup="f"><img src="' + window.gm_pg_r + '" width="21" height="21" /></a>';
            } else {
                stylebtnRight += '<a href="#" class="active right" pg_setup="-2"><img src="' + window.gm_pg_r + '" width="21" height="21" /></a>';
            }

            if (self.options.paginatorType == 2) {
                $(e).find(".paginator").html(stylebtnLeft + '<div class="center">' + style + '</div>' + stylebtnRight);
            } else {
                $(e).find(".paginator").html(stylebtnLeft + stylebtnRight + '<div class="center">' + style + '</div>');
            }
            $(e).find(".paginator a").bind('click', function () {
                self.options.gotoElement = $(this).attr('pg_setup');
                self.appendContent(e_old, self, true);
                return false;
            });
        },

        appendContent: function (e, thisObject, effect) {
            page = thisObject.options.gotoElement;
            if (page == 'f') return;
            page = parseInt(page);
            if (page < 0) {
                if (page == -1) {
                    page = thisObject.options.currentPage - 1;
                } else {
                    page = thisObject.options.currentPage + 1;
                }
            }
            thisObject.options.currentPage = page;
            till = (thisObject.options.currentPage - 1) * thisObject.options.itemsPerPage;
            if (effect) {
                $(e).find('.element').slice(thisObject.options.currentActive, thisObject.options.itemsPerPage + thisObject.options.currentActive).fadeOut("medium", function () {
                    $(e).find('.element').slice(till, thisObject.options.itemsPerPage + till).fadeIn("medium");
                });
                thisObject.createPaginator(e);
            } else {

                // added by POINTS to fix jumping effect when changing the page (elements are hidden -> box resizes until next elements are visible)
                var maxHeight = 0;
                $(e).find('.element').slice(till, thisObject.options.itemsPerPage + till).children('div').each(function () {
                    var height = $(this).outerHeight();
                    if (maxHeight < height) {
                        maxHeight = height;
                    }
                });

                // fallback if height could not be calculated
                if (maxHeight == 0) maxHeight = 276;

                $(e).find('.element').parent().css('height', maxHeight);

                $(e).find('.element').hide();  // hide all child element of content
                $(e).find('.element').slice(till, thisObject.options.itemsPerPage + till).show();  // show only those items according to page selected.
                thisObject.createPaginator(e);   // create new paginator
            }
            thisObject.options.currentActive = till;
            return false;
        }
    });

    $.fn.jpaginator = function (o) {
        if (typeof o == 'string') {
            var instance = $(this).data('jpaginator'), args = Array.prototype.slice.call(arguments, 1);
            return instance[o].apply(instance, args);
        } else {
            return this.each(function () {
                $(this).data('jpaginator', new $jc(this, o));
            });
        }
    };
})(jQuery);
