# -*- coding: utf-8 -*-

import os
import re
from StringIO import StringIO

from trac.core import *
from trac.resource import *
from trac.mimeview.api import Context
from trac.wiki.parser import WikiParser
from trac.wiki.formatter import Formatter
from trac.util.html import Markup
from trac.wiki.formatter import WikiProcessor, _markup_to_unicode
from genshi.core import Markup, escape

def wiki_to_html(wikitext, env, req, db=None,
                 absurls=False, escape_newlines=False,resource=None):
    if not wikitext:
        return Markup()
    abs_ref, href = (req or env).abs_href, (req or env).href
    #for image macro ,use arg resource
    context = Context.from_request(req, absurls=absurls)
    context.resource=Resource(resource)
    out = StringIO()
    WikiToEditHtmlFormatter(env,context).format(wikitext, out, escape_newlines)
    return Markup(out.getvalue())


def is_missing_link(element):
    if isinstance(element ,Element):
        if element.tag == 'a' and element.attrib.get('class')=='missing wiki':
            return True
    return False

class WikiToEditHtmlFormatter(Formatter):
    #ignore_missing_pages = True

    def _make_link(self, ns, target, match, label):
        #force ignore_missing_pages = True
        #if ret contains '<a class="missing wiki"' return match
        elem = Formatter._make_link(self, ns, target, match, label)
        #if str(elem)[:23] == u'<a class="missing wiki"' :
        if is_missing_link(elem) == True:
            return match
        else:
            return elem

    # -- Wiki engine
    
    # if '!' : not delete '!'
    # if missing link : dont make link
    def handle_match(self, fullmatch):
        for itype, match in fullmatch.groupdict().items():
            if match and not itype in self.wikiparser.helper_patterns:
                # Check for preceding escape character '!'
                if match[0] == '!':
                    return escape(match) # not delete '!'
                if itype in self.wikiparser.external_handlers:
                    external_handler = self.wikiparser.external_handlers[itype]
                    elem = external_handler(self, match, fullmatch)
                    if is_missing_link(elem) == True:
                        return escape(match)
                    else:
                        return elem
                else:
                    internal_handler = getattr(self, '_%s_formatter' % itype)
                    elem = internal_handler(match, fullmatch)
                    if is_missing_link(elem) == True:
                        return escape(match)
                    else:
                        return elem

    # WikiMacros
    def _macro_formatter(self, match, fullmatch):
        name = fullmatch.group('macroname')
        if name.lower() == 'br':
            return '<br />'
        elif name.lower() == 'image':
            return Formatter._macro_formatter(self, match, fullmatch)
        #elif name in ['html']:
        #    args = fullmatch.group('macroargs')
        #    try:
        #        macro = WikiProcessor(self, name)
        #        return macro.process(args, in_paragraph=True)
        #    except Exception, e:
        #        self.env.log.error('Macro %s(%s) failed' % (name, args),
        #                           exc_info=True)
        #        return system_message('Error: Macro %s(%s) failed' % (name, args),
        #                              e)
        return match

    # Code blocks
    
    def handle_code_block(self, line):
        if line.strip() == WikiParser.STARTBLOCK:
            self.in_code_block += 1
            if self.in_code_block == 1:
                self.code_processor = None
                self.code_text = ''
            else:
                self.code_text += line + os.linesep
                #if not self.code_processor:
                #    self.code_processor = WikiProcessor(self, 'default')
                self.code_processor = WikiProcessor(self, 'default')
        elif line.strip() == WikiParser.ENDBLOCK:
            self.in_code_block -= 1
            if self.in_code_block == 0 and self.code_processor:
                self.close_table()
                self.close_paragraph()
                processed = self.code_processor.process(self.code_text)
                #self.out.write(_markup_to_unicode(processed))
                #plugin = WlwCodePlugin(processed,0)
                self.out.write(_markup_to_unicode(processed))

            else:
                self.code_text += line + os.linesep
        elif not self.code_processor:
            #match = WikiParser._processor_re.search(line)
            #if match and False:
            #    name = match.group(1)
            #    self.code_processor = WikiProcessor(self, name)
            #else:
            self.code_text += line + os.linesep 
            self.code_processor = WikiProcessor(self, 'default')
        else:
            self.code_text += line + os.linesep
