# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
from __python__ import hash_literals

from elementmaker import E

from read_book.globals import runtime


def get_url(mathjax_files, name):
    ans = mathjax_files[name]
    if not ans:
        return name
    if jstype(ans) is not 'string':
        ans = mathjax_files[name] = window.URL.createObjectURL(ans)
    return ans


def postprocess(link_uid):
    for a in document.getElementsByTagName('a'):
        href = a.getAttribute('href')
        if href and href.startswith('#'):
            a.setAttribute('href', 'javascript: void(0)')
            a.setAttribute('data-' + link_uid, JSON.stringify({'frag': href[1:]}))


def load_mathjax(src):
    script = E.script(type='text/javascript')
    script.async = True
    script.src = src
    document.head.appendChild(script)


standalone_proceed_data = {
    'link_uid': None,
    'proceed': None,
    'event_listender_added': False,
}


def standalone_proceed():
    if standalone_proceed_data.proceed:
        postprocess(standalone_proceed_data.link_uid)
        standalone_proceed_data.proceed()
        standalone_proceed_data.proceed = None


def apply_mathjax(mathjax_files, link_uid, proceed):
    if runtime.is_standalone_viewer:
        if not standalone_proceed_data.event_listender_added:
            standalone_proceed_data.event_listender_added = True
            document.documentElement.addEventListener('calibre-mathjax-typeset-done', standalone_proceed)
        if standalone_proceed_data.proceed:
            print('MathJax apply called while a previous apply is still running')
        standalone_proceed_data.link_uid = link_uid
        standalone_proceed_data.proceed = proceed
        load_mathjax(f'{runtime.FAKE_PROTOCOL}://{runtime.SANDBOX_HOST}/mathjax/startup.js')
        return
    window.MathJax = v'{}'
    window.MathJax.startup = {
        'ready': def ():
            window.MathJax.startup.defaultReady()
            # monkeypatch the method responsible for mapping font URLs
            # to use our blob URLs, see https://github.com/mathjax/MathJax/issues/2458
            window.MathJax.startup.output.font.addFontURLs = def (styles, fonts, url):
                base = url.partition('/')[2]
                for name in fonts:
                    clone = v'{}'
                    font = fonts[name]
                    for key in Object.keys(font):
                        clone[key] = font[key]
                    font_name = clone.src.partition('/')[2].partition('"')[0]
                    full_name = base + '/' + font_name
                    src = get_url(mathjax_files, full_name)
                    clone.src = clone.src.replace(/".+?"/, f'"{src}"')
                    styles[name] = clone
            window.MathJax.startup.promise.then(def ():
                postprocess(link_uid)
                proceed()
            )
        ,
    }

    # also do any changes in pdf-mathjax-loader.js for the standalone
    # viewer/editor/pdf output
    window.MathJax.loader = {
        'load': ['input/tex-full', 'input/asciimath', 'input/mml', 'output/chtml'],
        'require': def (url):
            return new Promise(def (resolve, reject):
                name = url.partition('/')[2]
                script = document.createElement('script')
                script.charset = 'UTF-8'
                script.onload = def ():
                    resolve(url)
                script.onerror = def ():
                    reject(url)
                script.src = get_url(mathjax_files, name)
                document.head.appendChild(script)
            )
        ,
    }

    for s in document.scripts:
        if s.type is 'text/x-mathjax-config':
            es = document.createElement('script')
            es.text = s.text
            document.head.appendChild(es)
            document.head.removeChild(es)
    load_mathjax(get_url(mathjax_files, 'startup.js'))
