'Render the summary page
@param r: the S3Request
@param attr: controller attributes'

def summary(self, r, **attr):

    output = {}
    response = current.response
    resource = self.resource
    get_config = resource.get_config
    config = self._get_config(resource)
    crud_string = self.crud_string
    title = crud_string(self.tablename, 'title_list')
    output['title'] = title
    tablist = UL()
    sections = []
    commons = []
    if ('t' in r.get_vars):
        active_tab = int(r.get_vars['t'])
    else:
        active_tab = 0
    active_map = None
    show_filter_form = False
    filter_widgets = get_config('filter_widgets')
    if (filter_widgets and (not self.hide_filter)):
        show_filter_form = True
        S3FilterForm.apply_filter_defaults(r, resource)
    tab_idx = 0
    widget_idx = 0
    targets = []
    pending = []
    attr['filter_form'] = form_id = 'summary-filter-form'
    for section in config:
        common = section.get('common')
        section_id = section['name']
        s = DIV(_class='section-container', _id=section_id)
        if (not common):
            label = section['label']
            translate = section.get('translate', True)
            if (isinstance(label, basestring) and translate):
                label = current.T(label)
            tablist.append(LI(A(label, _href=('#%s' % section_id))))
        if (common or (active_tab == tab_idx)):
            visible = True
        else:
            visible = False
        widgets = section.get('widgets', [])
        for widget in widgets:
            widget_id = ('summary-%s' % widget_idx)
            r.get_vars['w'] = r.vars['w'] = widget_id
            filterable = widget.get('filterable', True)
            if filterable:
                targets.append(widget_id)
                if ((not visible) and widget.get('ajax_init')):
                    pending.append(widget_id)
            method = widget.get('method')
            if callable(method):
                content = method(r, widget_id=widget_id, visible=visible, **attr)
            else:
                handler = r.get_widget_handler(method)
                if (handler is None):
                    handler = resource.crud
                if (handler is not None):
                    if (method == 'datatable'):
                        dtargs = attr.get('dtargs', {})
                        dtargs['dt_searching'] = 'false'
                        attr['dtargs'] = dtargs
                    content = handler(r, method=method, widget_id=widget_id, visible=visible, **attr)
                else:
                    r.error(405, current.ERROR.BAD_METHOD)
            if isinstance(content, dict):
                if ((r.http == 'POST') and content.get('success')):
                    next_url = content.get('next')
                    if next_url:
                        self.next = next_url
                        return content
                for (k, v) in content.items():
                    if (k not in ('tabs', 'sections', 'widget')):
                        output[k] = v
                content = content.get('widget', 'EMPTY')
            elif (isinstance(content, MAP) and (common or (active_tab == tab_idx))):
                active_map = content
            s.append(DIV(content, _id=('%s-container' % widget_id), _class='widget-container'))
            widget_idx += 1
        if common:
            commons.append(s)
        else:
            sections.append(s)
            tab_idx += 1
    r.get_vars.pop('w', None)
    if (len(sections) > 1):
        output['tabs'] = tablist
        for s in sections:
            s.add_class('hide')
    else:
        output['tabs'] = ''
    output['sections'] = sections
    output['common'] = commons
    target = '    '.join(targets)
    filter_ajax = True
    if show_filter_form:
        if (active_tab != 0):
            submit_url_vars = {'t': active_tab}
        else:
            submit_url_vars = {}
        filter_submit_url = attr.get('filter_submit_url')
        if (not filter_submit_url):
            _vars = self._remove_filters(r.get_vars)
            _vars.update(submit_url_vars)
            filter_submit_url = r.url(vars=_vars)
        filter_ajax_url = attr.get('filter_ajax_url', r.url(method='filter', vars={}, representation='options'))
        filter_clear = get_config('filter_clear', current.deployment_settings.get_ui_filter_clear())
        filter_formstyle = get_config('filter_formstyle')
        filter_submit = get_config('filter_submit', True)
        filter_form = S3FilterForm(filter_widgets, clear=filter_clear, formstyle=filter_formstyle, submit=filter_submit, ajax=filter_ajax, url=filter_submit_url, ajaxurl=filter_ajax_url, _class='filter-form', _id=form_id)
        fresource = current.s3db.resource(resource.tablename)
        alias = (resource.alias if r.component else None)
        output['filter_form'] = filter_form.html(fresource, r.get_vars, target=target, alias=alias)
    else:
        output['filter_form'] = ''
    response.view = self._view(r, 'summary.html')
    if (len(sections) > 1):
        pending = (','.join(pending) if pending else 'null')
        script = ('S3.search.summary_tabs("%s",%s,"%s")' % (form_id, active_tab, pending))
        response.s3.jquery_ready.append(script)
    if active_map:
        active_map.callback = ('S3.search.summary_maps("%s")' % form_id)
    return output
