# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>

html_elements = {
    'a',
    'abbr',
    'acronym',
    'address',
    'area',
    'article',
    'aside',
    'audio',
    'b',
    'base',
    'big',
    'body',
    'blockquote',
    'br',
    'button',
    'canvas',
    'caption',
    'center',
    'cite',
    'code',
    'col',
    'colgroup',
    'command',
    'datagrid',
    'datalist',
    'dd',
    'del',
    'details',
    'dfn',
    'dialog',
    'dir',
    'div',
    'dl',
    'dt',
    'em',
    'event-source',
    'fieldset',
    'figcaption',
    'figure',
    'footer',
    'font',
    'form',
    'header',
    'h1',
    'h2',
    'h3',
    'h4',
    'h5',
    'h6',
    'hr',
    'head',
    'i',
    'iframe',
    'img',
    'input',
    'ins',
    'keygen',
    'kbd',
    'label',
    'legend',
    'li',
    'm',
    'map',
    'menu',
    'meter',
    'multicol',
    'nav',
    'nextid',
    'ol',
    'output',
    'optgroup',
    'option',
    'p',
    'pre',
    'progress',
    'q',
    's',
    'samp',
    'script',
    'section',
    'select',
    'small',
    'sound',
    'source',
    'spacer',
    'span',
    'strike',
    'strong',
    'style',
    'sub',
    'sup',
    'table',
    'tbody',
    'td',
    'textarea',
    'time',
    'tfoot',
    'th',
    'thead',
    'tr',
    'tt',
    'u',
    'ul',
    'var',
    'video',
}

mathml_elements = {
    'maction', 'math', 'merror', 'mfrac', 'mi',
    'mmultiscripts', 'mn', 'mo', 'mover', 'mpadded', 'mphantom',
    'mprescripts', 'mroot', 'mrow', 'mspace', 'msqrt', 'mstyle', 'msub',
    'msubsup', 'msup', 'mtable', 'mtd', 'mtext', 'mtr', 'munder',
    'munderover', 'none'
}

svg_elements = {
    'a', 'animate', 'animateColor', 'animateMotion',
    'animateTransform', 'clipPath', 'circle', 'defs', 'desc', 'ellipse',
    'font-face', 'font-face-name', 'font-face-src', 'g', 'glyph', 'hkern',
    'linearGradient', 'line', 'marker', 'metadata', 'missing-glyph',
    'mpath', 'path', 'polygon', 'polyline', 'radialGradient', 'rect',
    'set', 'stop', 'svg', 'switch', 'text', 'title', 'tspan', 'use'
}

html5_tags = html_elements.union(mathml_elements).union(svg_elements)


def _makeelement(tag, *args, **kwargs):
    ans = this.createElement(tag)

    for attr in kwargs:
        vattr = str.replace(str.rstrip(attr, '_'), '_', '-')
        val = kwargs[attr]
        if callable(val):
            if str.startswith(attr, 'on'):
                attr = attr[2:]
            ans.addEventListener(attr, val)
        elif val is True:
            ans.setAttribute(vattr, vattr)
        elif jstype(val) is 'string':
            ans.setAttribute(vattr, val)

    for arg in args:
        if jstype(arg) is 'string':
            arg = this.createTextNode(arg)
        ans.appendChild(arg)
    return ans


def maker_for_document(document):
    # Create an elementmaker to be used with the specified document
    E = _makeelement.bind(document)
    Object.defineProperties(E, {
        tag: {
            'value': _makeelement.bind(document, tag)
        } for tag in html5_tags
    })
    return E

if jstype(document) is 'undefined':
    E = maker_for_document({
        'createTextNode': def (value): return value;,
        'createElement': def (name):
            return {
                'name': name,
                'children': [],
                'attributes': {},
                'setAttribute': def (name, val): this.attributes[name] = val;,
                'appendChild': def (child): this.children.push(child);,
            }
    })
else:
    E = maker_for_document(document)
