 class Backbone.TableView extends Backbone.View
     tagName: "div"
     titleTemplate: _.template "<h2><%= model %></h2>"
-    filtersTemplate: _.template """
-        <% _.each(model, function (filter) { %>
-            <%= filter %>
-        <% }) %>
-    """
     searchTemplate: _.template """
         <input type="text" class="search-query pull-right" placeholder="<%= model.detail || model %>"></input>
-    """
-    inputTemplate: _.template """
-        <div class="input-prepend inline">
-            <span class="add-on"><%= name %></span><input id="<%= id %>" type="text" class="filter <%= className %>" value="<%= init %>"></input>
-        </div>
     """
     paginationTemplate: _.template """
         <ul class="pager">

        <%= pagination %>
    """
    events:
        "keypress .search-query": "updateOnEnter"
        "change   .filter":       "update"
        "click    .pager-prev":   "prevPage"
        "click    .pager-next":   "nextPage"
        "click    th":            "toggleSort"

    initialize: ->
        @collection.on "reset", @renderData
        @page = @page or 1
        @size = @size or 10
        return @

    printFilter: (name, filter) =>
        switch filter.type
            when "input"
                return @inputTemplate
                    name: @capitalize(name)
                    id: "filter" + name
                    init: filter.init or ""
                    className: filter.className or ""
        return ""

    updateOnEnter: (e) =>
        if e.keyCode == 13 then @update()
        return @

    update: =>
        data = {}
        for key, val of @initialData
            data[key] = val
        for filter, options of @filters
            field = $("#filter" + filter, @$el)
            if field
                val = field.val()
                data[filter] = (options.get? and options.get(val)) or val
        if @search
            data[@search.query or "q"] = $(".search-query", @$el).val()
        if @sortDir and @sortCol
            data.sort_dir = @sortDir
            data.sort_col = @sortCol
        data.page = @page
        data.size = @size
        @collection.fetch data: data
        return @

    capitalize: (str) ->
        str.charAt(0).toUpperCase() + str.substring(1).toLowerCase()

    renderData: =>
        $elData = $("tbody", @$el)
        if $elData
            $elData.html @dataTemplate
                collection: @collection
                columns:    @columns
                empty:      @empty or ""
        $(".page", @$el).html @page
        return @

    prevPage: =>
        @page = @page - 1
        if @page < 1
            @page = 1
        else
            @update()

    nextPage: =>
        # Since we don't have a collection count, for now we use the size of
        # the last GET as an heuristic to limit the use of nextPage
        if @collection.length == @size
            @page = @page + 1
            @update()

    toggleSort: (e) =>
        el = e.currentTarget
        cl = el.className
        if cl.indexOf("sorting_desc") >= 0
            @sortDir = "asc"
            cl = "sorting_asc"
        else if cl.indexOf("sorting") >= 0 or cl.indexOf("sorting_asc") >= 0
            @sortDir = "desc"
            cl = "sorting_desc"
        else
            return @
        $("th.sorting_desc, th.sorting_asc", @$el).removeClass("sorting_desc sorting_asc")
        $(el, @$el).addClass(cl)
        @sortCol = el.abbr
        @update()

    applyTemplate: (template, model) ->
        (model? and model and template model: model) or ""

    render: =>
        @$el.html @template

            empty:      @empty or ""
            title:      @applyTemplate @titleTemplate,      @title
            search:     @applyTemplate @searchTemplate,     @search
            pagination: @applyTemplate @paginationTemplate, @pagination

        @filters = _.map(@filters, (filter, name) => @createFilter(name, filter))
        filtersDiv = $(".filters", @$el)
        _.each @filters, (filter) ->
            filtersDiv.append filter.render().el
            filtersDiv.append " "
        @update()

class Filter extends Backbone.View
    tagName: "div"
    className: "inline"

    initialize: ->
        @id = @options.id
        @setData = @options.setData

    prettyName: (str) ->
        str.charAt(0).toUpperCase() + str.substring(1).replace(/_(\w)/g, (match, p1) -> " " + p1.toUpperCase())

    render: =>
        @options.name = @prettyName(@id)
        @$el.html @template @options
        return @

class InputFilter extends Filter
    template: _.template """
        <span class="add-on"><%= name %></span><input type="text" class="filter <%= filterClass %>" value="<%= init %>"></input>
    """
    events:
        "change .filter": "update"

    update: (e) =>
        @setData @id, @options.get e.currentTarget.value
