'S3DataTable constructor
@param rfields: A list of S3Resourcefield
@param data: A list of Storages the key is of the form table.field
The value is the data to be displayed in the dataTable
@param start: the first row to return from the data
@param limit: the (maximum) number of records to return
@param filterString: The string that was used in filtering the records
@param orderby: the DAL orderby construct'

def __init__(self, rfields, data, start=0, limit=None, filterString=None, orderby=None, empty=False):

    self.data = data
    self.rfields = rfields
    self.empty = empty
    colnames = []
    heading = {}
    append = colnames.append
    for rfield in rfields:
        colname = rfield.colname
        heading[colname] = rfield.label
        append(colname)
    self.colnames = colnames
    self.heading = heading
    data_len = len(data)
    if (start < 0):
        start = 0
    if (start > data_len):
        start = data_len
    if (limit == None):
        end = data_len
    else:
        end = (start + limit)
        if (end > data_len):
            end = data_len
    self.start = start
    self.end = end
    self.filterString = filterString
    if orderby:
        orderby_dirs = {}
        orderby_cols = []
        adapter = S3DAL()
        INVERT = adapter.INVERT
        append = orderby_cols.append
        for f in s3_orderby_fields(None, orderby, expr=True):
            if (type(f) is Expression):
                colname = str(f.first)
                direction = ('desc' if (f.op == INVERT) else 'asc')
            else:
                colname = str(f)
                direction = 'asc'
            orderby_dirs[colname] = direction
            append(colname)
        pos = 0
        ftuples = {}
        def resolve_sortby(rfield):
            colname = rfield.colname
            if (colname in ftuples):
                return ftuples[colname]
            ftype = rfield.ftype
            sortby = None
            if (ftype[:9] == 'reference'):
                field = rfield.field
                if (hasattr(field, 'sortby') and field.sortby):
                    sortby = field.sortby
                    if (not isinstance(sortby, (tuple, list))):
                        sortby = [sortby]
                    p = ('%s.%%s' % ftype[10:].split('.')[0])
                    sortby = [(p % fname) for fname in sortby]
            ftuples[colname] = sortby
            return sortby
        dt_ordering = []
        append = dt_ordering.append
        seen = set()
        skip = seen.add
        for (i, colname) in enumerate(orderby_cols):
            if (i < pos):
                continue
            direction = orderby_dirs[colname]
            for (col_idx, rfield) in enumerate(rfields):
                if (col_idx in seen):
                    continue
                sortby = None
                if (rfield.colname == colname):
                    sortby = (colname,)
                else:
                    sortby = resolve_sortby(rfield)
                    if ((not sortby) or (sortby != orderby_cols[i:(i + len(sortby))]) or any(((orderby_dirs[c] != direction) for c in sortby))):
                        sortby = None
                if sortby:
                    append([col_idx, direction])
                    pos += len(sortby)
                    skip(col_idx)
                    break
    else:
        dt_ordering = [[1, 'asc']]
    self.orderby = dt_ordering
