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

from elementmaker import E
from gettext import gettext as _

from dom import add_extra_css, build_rule, clear, svgicon
from iframe_comm import create_wrapped_iframe
from read_book.globals import runtime, ui_operations, is_dark_theme
from read_book.resources import load_resources

CLASS_NAME = 'book-content-popup-container'
TOP_LEVEL_DISPLAY = 'flex'

add_extra_css(def ():
    sel = '.' + CLASS_NAME
    style = ''
    style += build_rule(sel, justify_content='center', align_items='center', height='100%')
    sel += ' > div'
    style += build_rule(sel, border_radius='8px', border='solid currentColor 2px', margin='1rem', padding='0.5rem', box_shadow='2px 2px 4px currentColor')
    sel += ' > div'
    style += build_rule(sel, display='flex', justify_content='space-between', align_items='center')
    sel += ' > div'  # button container
    style += build_rule(sel, display='flex', justify_content='space-between', align_items='center')
    sel += ' > a'  # buttons
    style += build_rule(sel, margin_left='1ex', cursor='pointer', display='inline-block')
    style += build_rule(sel + ':hover', transform='scale(1.5)')
    style += build_rule(sel + ':active', transform='scale(2)')
    return style
)


class ContentPopupOverlay:
    def __init__(self, view):
        self.view = view
        self.loaded_resources = {}
        c = self.container
        c.classList.add(CLASS_NAME)
        c.appendChild(E.div(E.div()))
        c.addEventListener('click', self.hide)
        c.firstChild.addEventListener('click', def (ev):
            ev.stopPropagation(), ev.preventDefault()
        )
        self.pending_load = None

    def reset(self):
        if self.iframe_wrapper:
            self.iframe_wrapper.reset()

    def create_iframe(self):
        handlers = {
            'ready': self.on_iframe_ready,
            'error': self.view.on_iframe_error,
            'content_loaded': self.on_content_loaded,
            'print': self.on_print,
            'link_activated': self.on_link_activated,
            'close_requested': self.on_close_requested,
        }
        iframe_kw = {
            'seamless': True, 'sandbox': 'allow-scripts', 'style': 'width: 100%; max-height: 70vh'
        }
        if runtime.is_standalone_viewer:
            entry_point = f'{runtime.FAKE_PROTOCOL}://{runtime.SANDBOX_HOST}/book/__popup__'
        else:
            entry_point = 'read_book.footnotes'
        iframe, self.iframe_wrapper = create_wrapped_iframe(
            handlers, _('Loading data, please wait...'), entry_point, iframe_kw
        )
        iframe.style.colorScheme = 'dark' if is_dark_theme() else 'light'
        c = self.container
        c.firstChild.appendChild(iframe)

    def on_print(self, data):
        print(data.string)

    def on_link_activated(self, data):
        self.view.link_in_content_popup_activated(data.name, data.frag, data.is_popup, data.title)

    def on_close_requested(self, data):
        self.hide()

    @property
    def container(self):
        return document.getElementById('book-content-popup-overlay')

    @property
    def iframe(self):
        return self.iframe_wrapper.iframe

    @property
    def is_visible(self):
        return self.container.style.display is not 'none'

    def hide(self):
        self.container.style.display = 'none'
        ui_operations.focus_iframe()

    def show(self):
        c = self.container
        c.style.display = TOP_LEVEL_DISPLAY

    def on_iframe_ready(self, msg):
        return self.do_pending_load()

    def apply_color_scheme(self, bg, fg):
        c = self.container.firstChild
        c.style.backgroundColor = bg
        c.style.color = fg
        try:
            self.iframe.style.colorScheme = 'dark' if is_dark_theme() else 'light'
        except:
            pass

    def create_footnote_header(self, header):
        clear(header)
        header.appendChild(
            E.h3(self.current_footnote_data.title or _('Footnote')),
        )
        bc = E.div(
            E.a(svgicon('arrow-right'), title=_('Go to this footnote in the main view'), href='javascript:void(0)'),
            E.a(svgicon('close'), title=_('Close the footnotes window'), href='javascript:void(0)')
        )
        bc.firstChild.addEventListener('click', def ():
                self.hide()
                self.view.goto_named_destination(self.current_footnote_data.name, self.current_footnote_data.frag)
        )
        bc.lastChild.addEventListener('click', self.hide)
        header.appendChild(bc)

    def load_doc(self, name, done_callback):
        def cb(resource_data):
            self.loaded_resources = resource_data
            done_callback(resource_data)
        load_resources(self.view.book, name, self.loaded_resources, cb)

    def show_footnote(self, data):
        if not self.iframe_wrapper:
            self.create_iframe()
        self.current_footnote_data = data
        c = self.container.firstChild
        header = c.firstChild
        s = header.style
        s.paddingLeft = s.paddingRight = s.paddingBottom = s.paddingTop = '0'
        s.marginLeft = s.marginRight = s.marginBottom = s.marginTop = '0'
        s.borderBottom = s.borderTop = s.borderLeft = s.borderRight = 'solid currentColor 0'
        bs = 'solid currentColor 2px'
        if self.current_footnote_data.vertical_writing_mode:
            c.style.width = str(50 // data.cols_per_screen) + 'vw'
            self.iframe.style.height = '80vh'
            c.style.writingMode = 'vertical-rl' if self.current_footnote_data.rtl else 'vertical-lr'
            if self.current_footnote_data.rtl:
                s.paddingLeft = s.marginLeft = '1ex'
                s.borderLeft = bs
            else:
                s.paddingRight = s.marginRight = '1ex'
                s.borderRight = bs
        else:
            c.style.width = str(100 // data.cols_per_screen) + 'vw'
            self.iframe.style.height = '12ex'
            c.style.writingMode = 'horizontal-rl' if self.current_footnote_data.rtl else 'horizontal-lr'
            s.paddingBottom = s.marginBottom = '1ex'
            s.borderBottom = bs
        self.create_footnote_header(header)
        self.load_doc(data.name, self.show_footnote_item)
        self.iframe_wrapper.send_message('clear', text=_('Loading note, please wait...'))

    def show_footnote_item(self, resource_data):
        self.pending_load = resource_data, self.show_footnote_item_stage2
        if self.iframe_wrapper.ready:
            self.do_pending_load()
        else:
            self.iframe_wrapper.init()

    def do_pending_load(self):
        if self.pending_load:
            data, func = self.pending_load
            self.pending_load = None
            func(data)

    def show_footnote_item_stage2(self, resource_data):
        self.iframe_wrapper.send_unencrypted_message('display',
            resource_data=resource_data, book=self.view.book, name=self.current_footnote_data.name,
            frag=self.current_footnote_data.frag, settings=self.view.currently_showing.settings)

    def on_content_loaded(self, data):
        self.iframe.style.height = f'{data.height}px'
