'Helper function to retrieve the current options for this
filter widget
@param resource: the S3Resource'

def _options(self, resource, values=None):

    T = current.T
    NOOPT = T('No    options    available')
    EMPTY = T('None')
    opts = self.opts
    selector = self.field
    if isinstance(selector, (tuple, list)):
        selector = selector[0]
    if (resource is None):
        rname = opts.get('resource')
        if rname:
            resource = current.s3db.resource(rname)
    if resource:
        rfield = S3ResourceField(resource, selector)
        field = rfield.field
        colname = rfield.colname
        ftype = rfield.ftype
    else:
        rfield = field = colname = None
        ftype = 'string'
    opt_keys = []
    multiple = (ftype[:5] == 'list:')
    if (opts.options is not None):
        options = opts.options
        if callable(options):
            options = options()
        opt_keys = options.keys()
    elif resource:
        options = None
        if (ftype == 'boolean'):
            opt_keys = (True, False)
        elif (field or rfield.virtual):
            groupby = (field if (field and (not multiple)) else None)
            virtual = (field is None)
            rows = None
            if field:
                (ktablename, key, m) = s3_get_foreign_key(field, m2m=False)
                if ktablename:
                    multiple = m
                    ktable = current.s3db.table(ktablename)
                    key_field = ktable[key]
                    colname = str(key_field)
                    query = resource.get_query()
                    rfilter = resource.rfilter
                    if rfilter:
                        join = rfilter.get_joins()
                        left = rfilter.get_joins(left=True)
                    else:
                        join = left = None
                    query &= ((key_field == field) & current.auth.s3_accessible_query('read', ktable))
                    joins = rfield.join
                    for tname in joins:
                        query &= joins[tname]
                    location_filter = opts.get('location_filter')
                    if (location_filter and ('location_id' in ktable)):
                        location = current.session.s3.location_filter
                        if location:
                            query &= (ktable.location_id == location)
                    org_filter = opts.get('org_filter')
                    if (org_filter and ('organisation_id' in ktable)):
                        root_org = current.auth.root_org()
                        if root_org:
                            query &= ((ktable.organisation_id == root_org) | (ktable.organisation_id == None))
                    rows = current.db(query).select(key_field, resource._id.min(), groupby=key_field, join=join, left=left)
            if (rows is None):
                rows = resource.select([selector], limit=None, orderby=field, groupby=groupby, virtual=virtual, as_rows=True)
            opt_keys = []
            if rows:
                kappend = opt_keys.append
                kextend = opt_keys.extend
                for row in rows:
                    val = row[colname]
                    if (virtual and callable(val)):
                        val = val()
                    if ((multiple or virtual) and isinstance(val, (list, tuple, set))):
                        kextend([v for v in val if (v not in opt_keys)])
                    elif (val not in opt_keys):
                        kappend(val)
    if ((options is None) and values):
        numeric = ((rfield.ftype in ('integer', 'id')) or (rfield.ftype[:9] == 'reference'))
        for _val in values:
            if (numeric and (_val is not None)):
                try:
                    val = int(_val)
                except ValueError:
                    continue
            else:
                val = _val
            if ((val not in opt_keys) and ((not isinstance(val, (int, long))) or (not (str(val) in opt_keys)))):
                opt_keys.append(val)
    if ((len(opt_keys) < 1) or ((len(opt_keys) == 1) and (not opt_keys[0]))):
        return (ftype, None, opts.get('no_opts', NOOPT))
    opt_list = []
    represent = opts.represent
    if (not represent):
        represent = (field.represent if field else None)
    if (options is not None):
        if opts.get('translate'):
            opt_list = [((opt, T(label)) if isinstance(label, basestring) else (opt, label)) for (opt, label) in options.items()]
        else:
            opt_list = options.items()
    elif callable(represent):
        if hasattr(represent, 'bulk'):
            opt_dict = represent.bulk(opt_keys, list_type=False, show_link=False)
            if (None in opt_keys):
                opt_dict[None] = EMPTY
            elif (None in opt_dict):
                del opt_dict[None]
            if ('' in opt_keys):
                opt_dict[''] = EMPTY
            opt_list = opt_dict.items()
        else:
            args = ({'show_link': False} if ('show_link' in represent.func_code.co_varnames) else {})
            if multiple:
                repr_opt = (lambda opt: (((opt in (None, '')) and (opt, EMPTY)) or (opt, represent([opt], **args))))
            else:
                repr_opt = (lambda opt: (((opt in (None, '')) and (opt, EMPTY)) or (opt, represent(opt, **args))))
            opt_list = map(repr_opt, opt_keys)
    elif (isinstance(represent, str) and (ftype[:9] == 'reference')):
        db = current.db
        ktable = db[ftype[10:]]
        k_id = ktable._id.name
        fieldnames = [k_id]
        fieldnames += re.findall('%\\(([a-zA-Z0-9_]*)\\)s', represent)
        represent_fields = [ktable[fieldname] for fieldname in fieldnames]
        query = (ktable.id.belongs([k for k in opt_keys if str(k).isdigit()]) & (ktable.deleted == False))
        rows = db(query).select(*represent_fields).as_dict(key=k_id)
        opt_list = []
        ol_append = opt_list.append
        for opt_value in opt_keys:
            if (opt_value in rows):
                opt_represent = (represent % rows[opt_value])
                if opt_represent:
                    ol_append((opt_value, opt_represent))
    else:
        opt_list = [(opt_value, s3_unicode(opt_value)) for opt_value in opt_keys if opt_value]
    if opts.get('sort', True):
        try:
            opt_list.sort(key=(lambda item: item[1]))
        except:
            opt_list.sort(key=(lambda item: s3_unicode(item[1])))
    options = []
    empty = False
    none = opts['none']
    for (k, v) in opt_list:
        if (k is None):
            if none:
                empty = True
                if (none is True):
                    options.append((k, v))
                else:
                    options.append((k, none))
        else:
            options.append((k, v))
    if (none and (not empty)):
        if (none is True):
            none = current.messages['NONE']
        options.append((None, none))
    if ((not opts.get('multiple', True)) and (not self.values)):
        options.insert(0, ('', ''))
    return (ftype, options, opts.get('no_opts', NOOPT))
