import HTMLGenerator
import Lexer
import Keywords
from _SilverCity import find_lexer_module_by_id, PropertySet, WordList
from DispatchHandler import DispatchHandler
from ScintillaConstants import SCLEX_PYTHON
import LanguageInfo

class PythonLexer(Lexer.Lexer):
    def __init__(self, properties = PropertySet()):
        self._properties = properties
        self._lexer = find_lexer_module_by_id(SCLEX_PYTHON)
        self._keyword_lists = [
            WordList(Keywords.python_keywords)
                            ]

class PythonHandler(DispatchHandler):
    def __init__(self):
        DispatchHandler.__init__(self, 'SCE_P')
        
    def event_handler(self, style, **kwargs):
        kwargs.update({'style' : style})
        # Mask out tab.timmy.whinge.level for dispatch
        handler = self.handlers.get(style & 63, None)
        if handler is None:
            self.handle_other(**kwargs)

        getattr(self, handler, self.handle_other)(**kwargs)
        
class PythonHTMLGenerator(HTMLGenerator.SimpleHTMLGenerator, PythonHandler):
    name = 'python'
    description = 'Python'
    
    def __init__(self):
        PythonHandler.__init__(self)
        HTMLGenerator.SimpleHTMLGenerator.__init__(self, 'SCE_P')
        
    def handle_other(self, style, text, **ignored):
        tab_problem = style & 64
        style = style & 63
        css_class = self.css_classes.get(style, '')
            
        if css_class:
            self._file.write('<span class="%s">' % css_class)

        if tab_problem:
            self._file.write('<span class="p_tabtimmywingylevel">')
        
        self._file.write(self.markup(text))

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

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

    def generate_html(self, file, buffer, lexer = PythonLexer()):
        self._file = file
        
        lexer.tokenize_by_style(buffer, self.event_handler)

import HyperText
class EmbeddedHyperTextHTMLGenerator(HyperText.HyperTextHTMLGenerator):
    def handle_h_tag(self, text, **ignored):
        self._file.write('<span class="python_h_tag">')
        self._file.write(self.markup(text))
        self._file.write('</span>')
        
    def handle_h_tag_unknown(self, **kwargs):
        self.handle_h_tag(**kwargs)

    def handle_h_attribute(self, text, **ignored):
        self._file.write('<span class="python_h_attribute">')
        self._file.write(self.markup(text))
        self._file.write('</span>')

    def handle_h_attribute_unknown(self, **kwargs):
        self.handle_h_attribute(**kwargs)
        
    def handle_h_double_string(self, text, **ignored):
        self._file.write('<span class="python_h_string">')
        self._file.write(self.markup(text))
        self._file.write('</span>')

    def handle_h_string_string(self, **kwargs):
        self.handle_h_double_string(**kwargs)

    def handle_other(self, style, text, **ignored):
        self._file.write('<span class="python_string">')
        self._file.write(self.markup(text))
        self._file.write('</span>')

def looks_like_markup(s):
    return s.count('<') and (s.count('/>') or s.count('</'))

def looks_like_xsl(s):
    return s.find('xsl:') != -1

def looks_like_html(s):
    # This is pretty bad...
    return s.count('html')

def guess_generator(s):
    import HyperText
    import XML
    import XSLT
    
    if looks_like_markup(s):
        if looks_like_xsl(s):
            return XSLT.XSLTHTMLGenerator()
        elif looks_like_html(s):
            return HyperText.HyperTextHTMLGenerator()
        else:
            return XML.XMLHTMLGenerator()

    return None

class SmartPythonHTMLGenerator(PythonHTMLGenerator):
    name = 'smart_python'
    description = 'Python with styled strings'

    def __init__(self):
        PythonHandler.__init__(self)
        HTMLGenerator.SimpleHTMLGenerator.__init__(self, 'SCE_P')
        
    def handle_p_string(self, text, **ignored):
        generator = guess_generator(text)
        if generator is not None:
            generator.generate_html(self._file, text)
        else:
            self.handle_other(text=text, **ignored)
                
    def handle_p_character(self, **kwargs):
        self.handle_p_string(**kwargs)
        
    def handle_p_triple(self, **kwargs):
        self.handle_p_string(**kwargs)
        
    def handle_p_tripledouble(self, **kwargs):
        self.handle_p_string(**kwargs)
        
    def handle_p_stringeol(self, **kwargs):
        self.handle_p_string(**kwargs)


python_language_info = LanguageInfo.LanguageInfo(
                'python',
                 ['py', 'pyw', 'cgi'],
                 ['.*?python.*?'],
                 [PythonHTMLGenerator, SmartPythonHTMLGenerator]
            )

LanguageInfo.register_language(python_language_info) 
