'Widget method for this form element. Renders a table with
read-rows for existing entries, a variable edit-row to update
existing entries, and an add-row to add new entries. This widget
uses s3.inline_component.js to facilitate manipulation of the
entries.
@param field: the Field for this form element
@param value: the current value for this field
@param attributes: keyword attributes for this widget'

def __call__(self, field, value, **attributes):

    options = self.options
    if (options.readonly is True):
        return self.represent(value)
    if (value is None):
        value = field.default
    if isinstance(value, basestring):
        data = json.loads(value)
    else:
        data = value
        value = json.dumps(value, separators=SEPARATORS)
    if (data is None):
        raise SyntaxError('No    resource    structure    information')
    self.upload = Storage()
    if (options.multiple is False):
        multiple = False
    else:
        multiple = True
    required = options.get('required', False)
    resource = self.resource
    component_name = data['component']
    component = resource.components[component_name]
    table = component.table
    formname = self._formname()
    fields = data['fields']
    items = data['data']
    has_rows = False
    item_rows = []
    prefix = component.prefix
    name = component.name
    audit = current.audit
    has_permission = current.auth.s3_has_permission
    tablename = component.tablename
    layout = self._layout()
    columns = self.options.get('columns')
    if columns:
        layout.set_columns(columns, row_actions=multiple)
    get_config = current.s3db.get_config
    _editable = get_config(tablename, 'editable')
    if (_editable is None):
        _editable = True
    _deletable = get_config(tablename, 'deletable')
    if (_deletable is None):
        _deletable = True
    _class = 'read-row    inline-form'
    if (not multiple):
        _class = ('%s    single' % _class)
    item = None
    for i in xrange(len(items)):
        has_rows = True
        item = items[i]
        if (('_delete' in item) and item['_delete']):
            continue
        elif ('_id' in item):
            record_id = item['_id']
            if _editable:
                editable = has_permission('update', tablename, record_id)
            else:
                editable = False
            if _deletable:
                deletable = has_permission('delete', tablename, record_id)
            else:
                deletable = False
        else:
            record_id = None
            if _editable:
                editable = True
            else:
                editable = False
            if _deletable:
                deletable = True
            else:
                deletable = False
        rowname = ('%s-%s' % (formname, i))
        read_row = self._render_item(table, item, fields, editable=editable, deletable=deletable, readonly=True, multiple=multiple, index=i, layout=layout, _id=('read-row-%s' % rowname), _class=_class)
        if record_id:
            audit('read', prefix, name, record=record_id, representation='html')
        item_rows.append(read_row)
    action_rows = []
    _class = 'edit-row    inline-form    hide'
    if (required and has_rows):
        _class = ('%s    required' % _class)
    if (not multiple):
        _class = ('%s    single' % _class)
    edit_row = self._render_item(table, item, fields, editable=_editable, deletable=_deletable, readonly=False, multiple=multiple, index=0, layout=layout, _id=('edit-row-%s' % formname), _class=_class)
    action_rows.append(edit_row)
    inline_open_add = ''
    insertable = get_config(tablename, 'insertable')
    if (insertable is None):
        insertable = True
    if insertable:
        insertable = has_permission('create', tablename)
    if insertable:
        _class = 'add-row    inline-form'
        explicit_add = options.explicit_add
        if (not multiple):
            explicit_add = False
            if has_rows:
                _class = ('%s    hide' % _class)
            else:
                _class = ('%s    single' % _class)
        if (required and (not has_rows)):
            explicit_add = False
            _class = ('%s    required' % _class)
        if explicit_add:
            _class = ('%s    hide' % _class)
            if (explicit_add is True):
                label = current.T('Add    another')
            else:
                label = explicit_add
            inline_open_add = A(label, _class='inline-open-add    action-lnk')
        has_rows = True
        add_row = self._render_item(table, None, fields, editable=True, deletable=True, readonly=False, multiple=multiple, layout=layout, _id=('add-row-%s' % formname), _class=_class)
        action_rows.append(add_row)
    empty_row = self._render_item(table, None, fields, editable=_editable, deletable=_deletable, readonly=False, multiple=multiple, index='default', layout=layout, _id=('empty-edit-row-%s' % formname), _class='empty-row    inline-form    hide')
    action_rows.append(empty_row)
    empty_row = self._render_item(table, None, fields, editable=_editable, deletable=_deletable, readonly=True, multiple=multiple, index='none', layout=layout, _id=('empty-read-row-%s' % formname), _class='empty-row    inline-form    hide')
    action_rows.append(empty_row)
    real_input = ('%s_%s' % (resource.tablename, field.name))
    default = {'_type': 'text', '_value': value, 'requires': (lambda v: (v, None))}
    attr = StringWidget._attributes(field, default, **attributes)
    attr['_class'] = ('%s    hide' % attr['_class'])
    attr['_id'] = real_input
    widget = layout.subform(data, item_rows, action_rows, empty=(not has_rows))
    if self.upload:
        hidden = DIV(_class='hidden', _style='display:none')
        for (k, v) in self.upload.items():
            hidden.append(INPUT(_type='text', _id=k, _name=k, _value=v, _style='display:none'))
    else:
        hidden = ''
    output = DIV(INPUT(**attr), hidden, widget, inline_open_add, _id=self._formname(separator='-'), _field=real_input, _class='inline-component')
    layout.set_columns(None)
    return output
