import ScintillaConstants
import Utils


def replace(text, *replacements):
    for old, new in replacements:
        text = text.replace(old, new)

    return text


class HTMLGenerator:
    def escape(self, text):
        return replace(text, ('&', '&amp;'), ('<', '&lt;'), ('>', '&gt;'))

    def preformat(self, text):
        text = self.escape(text.expandtabs())
        return replace(text, (' ', '&nbsp;'), ('\n', '<br/>\n'))

    def markup(self, text):
        # XXX This is stolen from pydoc and is way too python-centric
        # there should be some way to extend it
        import re

        results = []
        here = 0
        pattern = re.compile(r'\b((http|ftp)://\S+[\w/]|'
                             r'RFC[- ]?(\d+)|'
                             r'PEP[- ]?(\d+))\b')
        while 1:
            match = pattern.search(text, here)
            if not match:
                break
            start, end = match.span()
            results.append(self.preformat(text[here:start]))

            all, scheme, rfc, pep = match.groups()
            if scheme:
                results.append('<a href="%s">%s</a>' % (
                    all, self.preformat(all)))
            elif rfc:
                url = 'http://www.rfc-editor.org/rfc/rfc%d.txt' % int(rfc)
                results.append('<a href="%s">%s</a>' % (
                    url, self.preformat(all)))
            elif pep:
                url = 'http://www.python.org/peps/pep-%04d.html' % int(pep)
                results.append('<a href="%s">%s</a>' % (
                    url, self.preformat(all)))

            here = end
        results.append(self.preformat(text[here:]))
        return ''.join(results)


def generate_css_name(state):
    return state[4:].lower()


class SimpleHTMLGenerator(HTMLGenerator):
    def __init__(self, state_prefix):
        self.css_classes = {}
        for constant in Utils.list_states(state_prefix):
            self.css_classes[getattr(ScintillaConstants, constant)] = \
                generate_css_name(constant)

    def handle_other(self, style, text, **ignored):
        css_class = self.css_classes.get(style, '')

        if css_class:
            self._file.write('<span class="%s">' % css_class)

        self._file.write(self.markup(text))

        if css_class:
            self._file.write('</span>')
