'Pivot table report page
@param r: the S3Request instance
@param attr: controller attributes for the request'

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

    output = {}
    resource = self.resource
    get_config = resource.get_config
    show_filter_form = False
    if (r.representation in ('html', 'iframe')):
        filter_widgets = get_config('filter_widgets', None)
        if (filter_widgets and (not self.hide_filter)):
            from s3filter import S3FilterForm
            show_filter_form = True
            S3FilterForm.apply_filter_defaults(r, resource)
    widget_id = 'pivottable'
    maxrows = 20
    maxcols = 20
    report_vars = ('rows', 'cols', 'fact', 'totals')
    get_vars = dict(((k, v) for (k, v) in r.get_vars.iteritems() if (k in report_vars)))
    report_options = get_config('report_options', {})
    defaults = report_options.get('defaults', {})
    if (not any(((k in get_vars) for k in ('rows', 'cols', 'fact')))):
        get_vars = defaults
    get_vars['chart'] = r.get_vars.get('chart', defaults.get('chart', None))
    get_vars['table'] = r.get_vars.get('table', defaults.get('table', None))
    if get_vars:
        rows = get_vars.get('rows', None)
        if (type(rows) is list):
            rows = rows[(-1)]
        cols = get_vars.get('cols', None)
        if (type(cols) is list):
            cols = cols[(-1)]
        layer = get_vars.get('fact', 'id')
        try:
            facts = S3PivotTableFact.parse(layer)
        except SyntaxError:
            current.log.error(sys.exc_info()[1])
            facts = None
        if ((not facts) or (not any([rows, cols]))):
            pivottable = None
        else:
            prefix = resource.prefix_selector
            get_vars['rows'] = (prefix(rows) if rows else None)
            get_vars['cols'] = (prefix(cols) if cols else None)
            get_vars['fact'] = ','.join((('%s(%s)' % (fact.method, fact.selector)) for fact in facts))
            pivottable = S3PivotTable(resource, rows, cols, facts)
    else:
        pivottable = None
    if (pivottable is not None):
        pivotdata = pivottable.json(maxrows=maxrows, maxcols=maxcols)
    else:
        pivotdata = None
    if (r.representation in ('html', 'iframe')):
        tablename = resource.tablename
        if show_filter_form:
            advanced = False
            for widget in filter_widgets:
                if (('hidden' in widget.opts) and widget.opts.hidden):
                    advanced = resource.get_config('report_advanced', True)
                    break
            filter_formstyle = get_config('filter_formstyle', None)
            filter_form = S3FilterForm(filter_widgets, formstyle=filter_formstyle, advanced=advanced, submit=False, _class='filter-form', _id=('%s-filter-form' % widget_id))
            fresource = current.s3db.resource(tablename)
            alias = (resource.alias if r.component else None)
            filter_widgets = filter_form.fields(fresource, r.get_vars, alias=alias)
        else:
            filter_widgets = None
        ajax_vars = Storage(r.get_vars)
        ajax_vars.update(get_vars)
        filter_url = r.url(method='', representation='', vars=ajax_vars.fromkeys((k for k in ajax_vars if (k not in report_vars))))
        ajaxurl = attr.get('ajaxurl', r.url(method='report', representation='json', vars=ajax_vars))
        output = S3ReportForm(resource).html(pivotdata, get_vars=get_vars, filter_widgets=filter_widgets, ajaxurl=ajaxurl, filter_url=filter_url, widget_id=widget_id)
        output['title'] = self.crud_string(tablename, 'title_report')
        output['report_type'] = 'pivottable'
        self._view(r, 'pivottable.html')
        current.response.view = self._view(r, 'report.html')
    elif (r.representation == 'json'):
        output = json.dumps(pivotdata, separators=SEPARATORS)
    else:
        r.error(415, current.ERROR.BAD_FORMAT)
    return output
