jQuery.fn.sortElements = (function(){
    
    var sort = [].sort;
 
    return function(comparator, getSortable) {
        
        var _default = function(a, b){
            a = $(a).text();
            b = $(b).text();
            
            if(a.match(/^[\d]+$/)){
                return parseInt(a, 10) > parseInt(b, 10) ? 1 : -1;
            }else if(a.match(/^[\d]{1,2}\.[\d]{1,2}\.[\d]{2,4}/)){
                var as = a.split(/^([\d]{1,2})\.([\d]{1,2})\.([\d]{2,4})/);
                var bs = b.split(/^([\d]{1,2})\.([\d]{1,2})\.([\d]{2,4})/);
                var astr = as[3]+"-"+as[2]+"-"+as[1]+as[4];
                var bstr = bs[3]+"-"+bs[2]+"-"+bs[1]+bs[4];
                return astr > bstr ? 1 : -1;  
            }else if(a.match(/^[\d]+.?[\d]*,?[\d]*/)){
                a = a.replace('.','').replace(',','.');
                b = b.replace('.','').replace(',','.');
                return parseFloat(a) > parseFloat(b) ? 1 : -1;
            }else{
                return a > b ? 1 : -1;   
            }
        }
        var _default_inv = function(a, b){
            return (_default(a, b) * -1);        
        }
 
        var numeric = function(a, b){
            return parseInt($(a).text(), 10) > parseInt($(b).text(), 10) ? 1 : -1;
        }
 
        var auto = function(a, b){
            invers = !inverse;
            a = $(a).text();
            b = $(b).text();
 
            return (isNaN(a) || isNaN(b) ? a > b : +a > +b) ? inverse ? -1 : 1 : inverse ? 1 : -1;
        }
        
        if(!$.isFunction(comparator)){
            if(comparator.match(/^default/)){
                if(comparator.match(/inverse$/))
                    comparator = _default_inv;
                else
                    comparator = _default;
            }
            else if(comparator.match(/^numeric/)) comparator = numeric;
            else if(comparator.match(/^auto/)) comparator = auto;      
        }

        getSortable = getSortable || function(){
            return this;
        };
 
        var placements = this.map(function(){

            var sortElement = getSortable.call(this),
            parentNode = sortElement.parentNode,
            nextSibling = parentNode.insertBefore(
                document.createTextNode(''),
                sortElement.nextSibling
                );
 
            return function() {
 
                if (parentNode === this) {
                    throw new Error(
                        "You can't sort elements if any one is a descendant of another."
                        );
                }
                parentNode.insertBefore(this, nextSibling);
                parentNode.removeChild(nextSibling);
            };
        });
 
        return sort.call(this, comparator).each(function(i){
            placements[i].call(getSortable.call(this));
        });
 
    };
 
})();

$(function(){
    $.currentGrid = "";
    
    $.fn.createGrid = function(query, _class){
        return $(this).each(function(){
            //Aussehen für default herstellen
            if(!$(this).hasClass('default') && !$(this).hasClass('small'))
                return;
            $(this).wrap($("<div>").addClass('gridContainer'));
            $(this).find('thead').addClass('gridHeaderRow');
            
            if($(this).attr('title') && $(this).attr('title').length > 0){
                $(this).closest('.gridContainer').prepend($('<div class="gridTitle"></div>').text($(this).attr('title')));
                $(this).removeAttr('title');
            }
            
            $(this).find('tbody').addClass('gridWrapper');
            $(this).find('tr').filter(':odd').addClass('odd');
            
            $('.gridHeaderRow th').each(function(){
                if(!this.hasAttribute('width')){
                    $(this).attr('width', $(this).outerWidth());
                }
            });
            
            if($(this).hasClass('default'))
                $(this).closest('.gridContainer').append($('<div class="gridPager"><div class="gridSearch"><input type="text" value="" placeholder="Suche"></div><div class="gridLimit"><input type="text" class="nRowsShowing" style="width: 20px;" value="15"></div><a class="button Z gridBack" href="#">Zurück</a><a class="button W gridNext" href="#">Weiter</a><div class="gridTotal"></div><div class="gridButton gridSave">Save</div><div class="wildcards"><small>Wildcards: * beliebige, ? genau eins</small></div></div>'));
        
            $('.gridHeaderRow th').each(function(i){
                $(this).click(function(){
                    if($(this).hasClass('sorted')){
                        $(this).removeClass('sorted');
                        $('.gridContainer tr td:nth-child('+(i+1)+')').sortElements("default inverse", function(){
                            return this.parentNode; 
                        });
                    }else{
                        $(this).addClass('sorted');
                        $('.gridContainer tr td:nth-child('+(i+1)+')').sortElements("default", function(){
                            return this.parentNode; 
                        });
                    }
                });
            });
            
            if(query == undefined){
                query = "";
            }
            
            var search = "";
            var index = 0;
            var limit = parseInt($('.gridContainer .nRowsShowing').val(),10);
            
            if($(this).hasClass('default')){
                $('.gridContainer .gridSearch input').keyup(function(){
                    var searchOld = search;
                    search = $(this).val();
                    /*
                if(search.length < 1 && searchOld < 1)
                    return;
                    */
                
                    index = 0;
                    $.currentGrid = query + "&ajax=true&search="+search+"&index="+index+"&limit="+limit;
                    $.post(window.location.href, $.currentGrid, function(data){
                        var tableRows = $(data).find(_class).find('tbody tr');
                        $('.gridContainer tbody').html(tableRows);
                        $('.grid').trigger('gridChange');
                    })
                });
            
                $('.gridContainer .gridLimit input').change(function(){ 
                    limit = parseInt($('.gridContainer .nRowsShowing').val(),10);
                    $.currentGrid = query + "&ajax=true&search="+search+"&index="+index+"&limit="+limit;
                    $.post(window.location.href, $.currentGrid, function(data){
                        var tableRows = $(data).find(_class).find('tbody tr');
                        $('.gridContainer tbody').html(tableRows);
                        $('.grid').trigger('gridChange');
                    })
                });
            
                $('.gridContainer .gridBack').click(function(){
                    index = index < limit ? 0 : index-limit;
                    $.currentGrid = query + "&ajax=true&search="+search+"&index="+index+"&limit="+limit;
                    $.post(window.location.href, $.currentGrid, function(data){
                        var tableRows = $(data).find(_class).find('tbody tr');
                        $('.gridContainer tbody').html(tableRows);
                        $('.grid').trigger('gridChange');
                    })
                });
                $('.gridContainer .gridNext').click(function(){
                    if($('.grid tbody tr').length < 1){
                        return;
                    }
                    index+= limit;
                    $.currentGrid = query + "&ajax=true&search="+search+"&index="+index+"&limit="+limit;
                    $.post(window.location.href, $.currentGrid, function(data){
                        var tableRows = $(data).find(_class).find('tbody tr');
                        $('.gridContainer tbody').html(tableRows);
                        $('.grid').trigger('gridChange');
                    })
                });
            }
        })
    }
});
