Creates a W3C compliant 'mailto' link.

    Encode/encrypt given email to reduce undesired automated email
    harvesting when embedded in a web page.

    NOTE: there is no ultimate solution to protect against email
    harvesting. All have drawbacks and can more or less be
    circumvented. There are other techniques to protect email
    addresses. We implement the less annoying one for users.

    @param email: the recipient of the email
    @param subject: a default subject for the email (must not contain
                    line feeds)
    @param body: a default body for the email
    @param cc: the co-recipient(s) of the email
    @param bcc: the hidden co-recpient(s) of the email
    @param link_label: the label of this mailto link. String
                       replacement is performed on key %(email)s with
                       the email address if needed.
    @param linkattrd: dictionary of attributes (e.g. a={'class': 'img'})
    @param escape_urlargd: boolean indicating if the function should escape
                           arguments (e.g. < becomes &lt; or " becomes &quot;)
    @param escape_linkattrd: boolean indicating if the function should escape
                           attributes (e.g. < becomes &lt; or " becomes &quot;)
    @param email_obfuscation_mode: the protection mode. See below:

    You can choose among several modes to protect emails. It is
    advised to keep the default
    CFG_MISCUTIL_EMAIL_HARVESTING_PROTECTION value, so that it is
    possible for an admin to change the policy globally.

    Available modes ([t] means "transparent" for the user):

         -1: hide all emails, excepted CFG_SITE_ADMIN_EMAIL and
             CFG_SITE_SUPPORT_EMAIL.

      [t] 0 : no protection, email returned as is.
                foo@example.com => foo@example.com

          1 : basic email munging: replaces @ by [at] and . by [dot]
                foo@example.com => foo [at] example [dot] com

      [t] 2 : transparent name mangling: characters are replaced by
              equivalent HTML entities.
                foo@example.com => &#102;&#111;&#111;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;

      [t] 3 : javascript insertion. Requires Javascript enabled on client side.

          4 : replaces @ and . characters by gif equivalents.
                foo@example.com => foo<img src="at.gif" alt=" [at] ">example<img src="dot.gif" alt=" [dot] ">com

def create_html_mailto(
        email,
        subject=None,
        body=None,
        cc=None,
        bcc=None,
        link_label="%(email)s",
        linkattrd=None,
        escape_urlargd=True,
        escape_linkattrd=True,
        email_obfuscation_mode=None):
    """Creates a W3C compliant 'mailto' link.

    Encode/encrypt given email to reduce undesired automated email
    harvesting when embedded in a web page.

    NOTE: there is no ultimate solution to protect against email
    harvesting. All have drawbacks and can more or less be
    circumvented. There are other techniques to protect email
    addresses. We implement the less annoying one for users.

    @param email: the recipient of the email
    @param subject: a default subject for the email (must not contain
                    line feeds)
    @param body: a default body for the email
    @param cc: the co-recipient(s) of the email
    @param bcc: the hidden co-recpient(s) of the email
    @param link_label: the label of this mailto link. String
                       replacement is performed on key %(email)s with
                       the email address if needed.
    @param linkattrd: dictionary of attributes (e.g. a={'class': 'img'})
    @param escape_urlargd: boolean indicating if the function should escape
                           arguments (e.g. < becomes &lt; or " becomes &quot;)
    @param escape_linkattrd: boolean indicating if the function should escape
                           attributes (e.g. < becomes &lt; or " becomes &quot;)
    @param email_obfuscation_mode: the protection mode. See below:

    You can choose among several modes to protect emails. It is
    advised to keep the default
    CFG_MISCUTIL_EMAIL_HARVESTING_PROTECTION value, so that it is
    possible for an admin to change the policy globally.

    Available modes ([t] means "transparent" for the user):

         -1: hide all emails, excepted CFG_SITE_ADMIN_EMAIL and
             CFG_SITE_SUPPORT_EMAIL.

      [t] 0 : no protection, email returned as is.
                foo@example.com => foo@example.com

          1 : basic email munging: replaces @ by [at] and . by [dot]
                foo@example.com => foo [at] example [dot] com

      [t] 2 : transparent name mangling: characters are replaced by
              equivalent HTML entities.
                foo@example.com => &#102;&#111;&#111;&#64;&#101;&#120;&#97;&#109;&#112;&#108;&#101;&#46;&#99;&#111;&#109;

      [t] 3 : javascript insertion. Requires Javascript enabled on client side.

          4 : replaces @ and . characters by gif equivalents.
                foo@example.com => foo<img src="at.gif" alt=" [at] ">example<img src="dot.gif" alt=" [dot] ">com
    """
    # TODO: implement other protection modes to encode/encript email:
    #
    # [t] 5 : form submission. User is redirected to a form that he can
    # fills in to send the email (??Use webmessage??).
    # Depending on WebAccess, ask to answer a question.
    ##
    # [t] 6 : if user can see (controlled by WebAccess), display. Else
    # ask to login to see email. If user cannot see, display
    # form submission.

    if email_obfuscation_mode is None:
        email_obfuscation_mode = cfg.get(
            'CFG_WEBSTYLE_EMAIL_ADDRESSES_OBFUSCATION_MODE')

    if linkattrd is None:
        linkattrd = {}

    parameters = {}
    if subject:
        parameters["subject"] = subject
    if body:
        parameters["body"] = body.replace('\r\n', '\n').replace('\n', '\r\n')
    if cc:
        parameters["cc"] = cc
    if bcc:
        parameters["bcc"] = bcc

    # Preprocessing values for some modes
    if email_obfuscation_mode == 1:
        # Basic Munging
        email = email.replace("@", " [at] ").replace(".", " [dot] ")
    elif email_obfuscation_mode == 2:
        # Transparent name mangling
        email = string_to_numeric_char_reference(email)

    if '%(email)s' in link_label:
        link_label = link_label % {'email': email}

    mailto_link = create_html_link('mailto:' + email, parameters,
                                   link_label, linkattrd,
                                   escape_urlargd, escape_linkattrd)

    if email_obfuscation_mode == 0:
        # Return "as is"
        return mailto_link
    elif email_obfuscation_mode == 1:
        # Basic Munging
        return mailto_link
    elif email_obfuscation_mode == 2:
        # Transparent name mangling
        return mailto_link
    elif email_obfuscation_mode == 3:
        # Javascript-based
        return '''<script language="JavaScript" ''' \
            '''type="text/javascript">''' \
            '''document.write('%s'.split("").reverse().join(""))''' \
            '''</script>''' % \
               mailto_link[::-1].replace("'", "\\'")
    elif email_obfuscation_mode == 4:
        # GIFs-based
        email = email.replace(
            '.', '<img src="%s/img/dot.gif" alt=" [dot] " '
            'style="vertical-align:bottom"  />' %
            cfg.get('CFG_SITE_URL'))
        email = email.replace(
            '@', '<img src="%s/img/at.gif" alt=" [at] " '
            'style="vertical-align:baseline" />' %
            cfg.get('CFG_SITE_URL'))
        return email

    # All other cases, including mode -1:
    return ""