(function($) {
    
    $.fn.perpage = function(options){
        var opts = $.extend({}, $.fn.perpage.defaults, options);
        $(this).after("<div class='perpage'>\n Display <select id='perPage'/> rows per page</div>\n");
        $('#perPage').append('<option value="10">10</option>');
        $('#perPage').append('<option value="20">20</option>');
        $('#perPage').append('<option value="50">50</option>');
        $('#perPage').append('<option value="100">100</option>');
        $('#perPage').val(opts.count);
    }
    
    $.fn.search = function(options) {
        var opts = $.extend({}, $.fn.search.defaults, options);
        var params = opts.params;
        var dates = opts.dates;
        
        var table = $(this).parent().parent();
        if(!$('#filters', table).length){
            var row = $(this).parent().clone();
            $(row).attr('id','filters').attr('class','filters');
            //$('td', row).replaceWith("<td></td>");
            $('td', row).html('');
            $("td:last",row).attr('class','filterActions');
            $("td:last",row).append("<input type='button' value='' id='applyFilter' title='Apply' class='button apply'/>");
            $("td:last",row).append("<input type='button' value='' id='clearFilter' title='Reset' class='button empty'/>");
            $('tr:first', table).after(row);
        }
        var target = $("td:eq("+$("td", $(this).parent()).index(this)+")", $('#filters', table))
        
        var searchByParams = false;
        var out = "<div class='searchable'>\n<select class='searchParam' name='search_"+opts.searchBy+"'>\n";
        for (var val in params) {
            var selected='';
            if(val == opts.value){
                selected = 'selected';
            }
            out += "<option value='"+val+"' "+selected+">" + params[val] + "</option>\n";
            searchByParams = true;
        }
        out += "</select>\n</div>\n";
        var searchByDate = false;
        var outputDate = "<div class='datepickers'><span class='dateText'>From </span>";
        var dkey = 1;
        for (var val in dates) {
            outputDate += "<input type='text' class='searchParam' name='search_"+opts.searchBy+dkey+"'>";
            if (dkey == 1) {
                outputDate += "<span class='dateText'> to </span>";
            }
            dkey ++;
            searchByDate = true;
        }
        outputDate += "<div class='clear'></div></div>";
        if(searchByParams){
            $(target).prepend(out);
        } else if (searchByDate) {
            $(target).prepend(outputDate);
        }else{
            $(target).prepend("<div class='searchable'><input type='text' class='searchParam' name='search_"+opts.searchBy+"' value='"+opts.value+"'/></div>");
        }
        return $(this);
    };
    
    $.fn.sort = function(options) {
        var opts = $.extend({}, $.fn.sort.defaults, options);
        if ($('span', $(this)).attr('class')) return;
        if(opts.type=='none'){
            $('span', $(this)).wrap("<div class='sortable none' title='Sort ascending'></div>");
        }
        if(opts.type=='desc'){
            $('span', $(this)).wrap("<div class='sortable up' title='Sort ascending'></div>");
        }
        if(opts.type=='asc'){
            $('span', $(this)).wrap("<div class='sortable down' title='Sort descending'></div>");
        }
        $(this).append("<input type='hidden' name='sort_"+opts.sortBy+"' value='"+opts.type+"'/>");
        return $(this);
    };

    $.fn.addFiltersHandler = function (options){
        var opts = $.extend({}, $.fn.addFiltersHandler.defaults, options);
        var obj=$(this);
        $('.sortable', $(this)).click(function(){
            $('*[name^=sort_]:input').val('none');
            if($(this).hasClass('up'))   $(this).parent().find('*[name^=sort_]:input').val('asc');
            if($(this).hasClass('down')) $(this).parent().find('*[name^=sort_]:input').val('desc');
            if($(this).hasClass('none')) $(this).parent().find('*[name^=sort_]:input').val('asc');
            opts.handler(getSortList(obj)+getSearchList(obj));
        });
        $('.searchParam[type=text]', $(this)).keypress(function (e){
            if (e.which == 13) {
                   opts.handler(getSortList(obj)+getSearchList(obj));
                   return false;
                }
                return true;
            });
        $('#applyFilter', $(this)).click(function(){
            opts.handler(getSortList(obj)+getSearchList(obj));
        });
        $('#clearFilter', $(this)).click(function(){
            $("*[name^=search_]", obj).val('');
            opts.handler(getSortList(obj));
        });
        $('#perPage').unbind('change');
        $('#perPage').change(function(){
            opts.handler(getSortList(obj)+getSearchList(obj));
        });
        return $(this);
    }
    function getSortList(obj){
        var sortList = '';
        $("*[name^=sort_]", obj).each(function(){
            if($(this).val()!='none'){
                sortList+="&"+$(this).attr('name')+"="+$(this).val();
            }
        });
        return sortList;
    }
    function getSearchList(obj){
        var searchList = '';
        $("*[name^=search_]", obj).each(function(){
            if($(this).val()!=''){
                searchList+="&"+$(this).attr('name')+"="+$(this).val();
            }
        });
        return searchList;
    }
    
    $.fn.commonActions = function(options) {
        var opts = $.extend({}, $.fn.commonActions.defaults, options);
        var actions = opts.actions;
    	var context = $(this);
        /*
        var outTop = "<div class='commonActions top'>";
        var outBottom = "<div class='commonActions bottom'>";
        var outButtons='';
        for (var act in actions) {
            outButtons += "<input type='button' class='button " + act + "' name='" + act + "' value='" + actions[act] + "'/>\n";
        }
        outButtons += "</div>\n";
        $(this).after(outBottom+outButtons).before(outTop+outButtons);
        */
        if(opts.handler){
            for (var act in actions) {
                $(".button[name="+act+"], .button2[name="+act+"]").click(function(){
                    var ids = new Array();
                    $('tr:first~tr>td', context).children('.checkbox.select:checked').each(function(){                    	
                        ids.push($(this).val());
                    });
                    opts.handler($(this).attr('name'), ids);
                    return false;
                });
            }
        }
        var idIndex = $("tr:first>td",$(this)).index($('#'+opts.idColumn));
            
        $("tr:first",$(this)).prepend("<td class='checkall'><input type='checkbox' id='checkall'/></td>");
        
        $("#checkall",$(this)).click(function(){
            if($(this).attr('checked')==false){
            	$('tr:first~tr>td', context).children('.select').removeAttr('checked');
            }else{
            	$('tr:first~tr>td', context).children('.select').attr('checked', 'checked');
            }
        });
        
        var notSecond = '';
        if($('#filters', $(this)).length){
            notSecond = ':not(:eq(0))';
            $("tr:eq(1)",$(this)).prepend("<td class='filtersLabel'>Filters:</td>");
        }
        
        $("tr:not(:first)"+notSecond,$(this)).each(function(){
            var value=$("td:eq("+idIndex+")",$(this)).text();
            $(this).prepend("<td><input type='checkbox' class='checkbox select' name='cid[]' value='"+value+"'></td>");
        });
        return $(this);
    };

    function dump(obj) {
        var out = '';
        for (var i in obj) {
            out += i + ": " + obj[i] + "\n";
        }
        alert(out);
    }

    $.fn.perpage.defaults = {
             count: 10
    };
    $.fn.search.defaults = {
         searchBy: '',
         value: '',
         params: {},
         dates: {}
    };
    $.fn.sort.defaults = {
         sortBy: '',
         type: 'none'
    };
    $.fn.commonActions.defaults = {
             idColumn: 'id',
             actions: {},
             handler: null
    };
    $.fn.addFiltersHandler.defaults = {
             handler: null
    };
})(jQuery);
