(function($){
    var PaginatePlugin = function(element, options)
    {
        var elem = $(element);
        var obj = this;
        var settings = $.extend({
        
            initialPage: 1,
            pagingLinks: 9,
            paginationSelector: null,
            showFirstLink: true,
            showPrevLink: true,
            showNextLink: true,
            showLastLink: true,
            firstLinkText: '&laquo;',
            prevLinkText: '&lsaquo;',
            nextLinkText: '&rsaquo;',
            lastLinkText: '&raquo;',
            perPage: 15

        }, options || {});

        var init = function()
        {
            settings.records = elem.children('li');
            settings.lastPage = Math.ceil(settings.records.length/settings.perPage);
            settings.currentPage = settings.initialPage >= 1 && settings.initialPage <= settings.lastPage ? settings.initialPage : 1;

            if( !settings.paginationSelector )
            {
                var id = Math.round((Math.random()*100000000));
                settings.paginationSelector = '#paging-links-'+id;
                var el = $('<span id="paging-links-'+id+'"></span>');
                elem.append(el);
            }    

            setPage(settings.initialPage);
        }
        
        var setPage = function(pageNum)
        {
            
            settings.currentPage = pageNum >= 1 && pageNum <= settings.lastPage ? pageNum : 1;

            settings.records.slice( (settings.currentPage-1)*settings.perPage, (settings.currentPage-1)*settings.perPage+settings.perPage ).show();
            settings.records.not(settings.records.slice( (settings.currentPage-1)*settings.perPage, (settings.currentPage-1)*settings.perPage+settings.perPage )).hide();
            
        if( settings.lastPage > 1 ) {
        
            var paginationContainer = $(settings.paginationSelector);
            
            paginationContainer.empty();
            
            var linksLeft = settings.pagingLinks;

            for( var i = settings.currentPage-(settings.pagingLinks-1)/2; i < settings.currentPage; i++ )
            {
                    
                if( i > 0 )
                {   
                    linksLeft--;
                    paginationContainer.each(function(){
                    
                        $(this).append($('<a href="#">'+i+'</a>').bind('click', { page: i }, function(e){
                            e.preventDefault();
                            setPage(e.data.page);
                        }));
                        
                    });
                }
                    
            }
            
            paginationContainer.append('<span><strong>'+i+'<'+'/strong><'+'/span>');
            linksLeft--;
                  
            for( var i = settings.currentPage+1; linksLeft > 0 && i <= settings.lastPage; i++ )
            {
                linksLeft--;
                paginationContainer.each(function(){
                
                    $(this).append($('<a href="#">'+i+'</a>').bind('click', { page: i }, function(e){
                        e.preventDefault();
                        setPage(e.data.page);
                    }));
                    
                });
            }

            for( var i = settings.currentPage-(settings.pagingLinks-1)/2-1; linksLeft > 0 && i > 0; i-- )
            {
                linksLeft--;
                paginationContainer.each(function(){
                
                    $(this).prepend($('<a href="#">'+i+'</a>').bind('click', { page: i }, function(e){
                        e.preventDefault();
                        setPage(e.data.page);
                    }));
                    
                });     
            }
                  
            if( settings.showPrevLink && settings.prevLinkText.length > 0 )
            {
                paginationContainer.each(function(){
                
                    $(this).prepend($('<a href="#">'+settings.prevLinkText+'</a>').bind('click', { page: settings.currentPage-1 }, function(e){
                        e.preventDefault();
                        setPage(e.data.page);
                    }).css('visibility',settings.currentPage > 1?'visible':'hidden'));
                    
                });
            }

            if( settings.showFirstLink && settings.firstLinkText.length > 0 )
            {
                paginationContainer.each(function(){
                
                    $(this).prepend($('<a href="#">'+settings.firstLinkText+'</a>').bind('click', { page: 1 }, function(e){
                        e.preventDefault();
                        setPage(e.data.page);
                    }).css('visibility',settings.currentPage > 1?'visible':'hidden'));
                    
                });
            }


            
            if( settings.showNextLink && settings.nextLinkText.length > 0 )
            {
                paginationContainer.each(function(){
                
                    $(this).append($('<a href="#">'+settings.nextLinkText+'</a>').bind('click', { page: settings.currentPage+1 }, function(e){
                        e.preventDefault();
                        setPage(e.data.page);
                    }).css('visibility',settings.currentPage < settings.lastPage?'visible':'hidden'));
                    
                });
            }

            if( settings.showLastLink && settings.lastLinkText.length > 0 )
            {
                paginationContainer.each(function(){
                
                    $(this).append($('<a href="#">'+settings.lastLinkText+'</a>').bind('click', { page: settings.lastPage }, function(e){
                        e.preventDefault();
                        setPage(e.data.page);
                    }).css('visibility',settings.currentPage < settings.lastPage?'visible':'hidden'));
                    
                });
            }
        
                }
        };                   
       


       // Private method - can only be called from within this object

       
       init();
       
   };

   $.fn.paginate = function(options)
   {
       return this.each(function()
       {
           var element = $(this);
          
           // Return early if this element already has a plugin instance
           if (element.data('paginate')) return;

           // pass options to plugin constructor
           var paginate = new PaginatePlugin(this, options);

           // Store plugin object in this element's data
           element.data('paginate', paginate);
       });
   };
})(jQuery);
