# -*- coding: iso-8859-1 -*-
"""
    MoinMoin - Frame Parser

    This parser is used to align enclosed wiki markup.
        
    Syntax:
        {{{#!frame align=align,thick=thick,style=style,color=color,
        background=background,background_image=background_image,
        position=position,width=width,padding=padding,
        margin=margin,text_align=text_align,text_font_size=text_font_size,
        text_color=text_color
        wiki markup
        }}}
    
    Parameters:
        align:      one of ['left', 'right', 'center', 'justify', 'float:left','float:right']
                    default: left
                    
        thick:      one of ['thin', 'medium','thick','1px','2px','5px','10px']
                    default: thin
                    
        style:      one of ['none','hidden', 'dotted', 'dashed', 'solid', 'double',
                            'groove', 'ridge', 'inset',  'outset']
                    default: solid
                    
        color:      each color which could be vrified by web.Color(str(name))
                    default: black
                       
        background: each color which could be vrified by web.Color(str(name))
                    default: transparent
                    
        background_image: the name of an attachment 
                          default: ''
                          
        background_repeat: one of ['repeat', 'repeat-x', 'repeat-y', 'no-repeat']
                           default: no-repeat               
                                         
        position:   one of ['static','absolute','relative','fixed','inherit']
                    default: relative
                          
        width:      has to end with % is testet by str(float(number))
                    default: auto
                          
        padding:    has to end with em is testet by str(float(number))
                    default: 0em
                          
        margin:     has to end with em is testet by str(float(number))
                    default: 0em                 
        
        text_align: one of ['left', 'right', 'center', 'justify']                              
                    default: left
                    
        text_font_size: one of ['xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large',
                                'smaller', 'larger']
                        default: ''        
        text_color: each which could be vrified by web.Color(str(name))
                    default: black
                          
        wiki markup: could any wiki markup 

    Procedure:
        Please remove the version number.
        
        The units are limited for numbers. And only one value for padding or margin 

    Examples:
        {{{
        #!frame align=float:right
        attachment:moinmoin.png
        ||A||B||
        ||C||D||
        ||C||D||
        }}}
    
        {{{ 
#!frame align=float:left,position=relative,width=48%,margin=0em,thick=2px,color=blue,background=yellow
A WikiName is a word that uses capitalized words. WikiNames automagically become hyperlinks to the WikiName's page. What exactly is an uppercase or lowercase letter is determined by the configuration, the default configuration should work for UTF-8 characters (digits are treated like lowercase characters). 


When you click on the highlighted page title (i.e. WikiName on this page), you will see a list of all pages that link to the current page. This even works on pages that are not defined yet.
}}}{{{
#!frame align=float:right,position=relative,width=50%,margin=0em,thick=2px,color=blue
When you click on the highlighted page title (i.e. WikiName on this page), you will see a list of all pages that link to the current page. This even works on pages that are not defined yet. 


A question mark before a link or a different rendering in grey means that the page is not yet defined: you can click the question mark or page name to offer a definition (e.g., ?NoSuchPageForReal). If you click on such a link, you will see a default page that you can edit; only after you save the page will it be created for real. A list of all pages that are not yet created but referred on another page is on WantedPages. 


To escape a WikiName, i.e. if you want to write the word WikiName without linking it, use an "empty" bold sequence (a sequence of six single quotes) like this: Wiki''''''Name. Alternatively, you can use the shorter sequence "``" (two backticks), i.e. Wiki``Name.
}}}
{{{ 
#!frame align=clear
}}}
        
= Album =
{{{
#!Frame align=float:right,background=gray,width=20%
#!Gallery2 album=1,front_image=100_1194.JPG,album_name=Bremen,front_image=100_1189.JPG,show_tools=0,show_text=0,show_date=0
}}}
Some images from the trip to Bremen in 2004

 * SpaceCenter 
 * ScienceCenter
{{{
#!Frame align=clear
}}}
        
    Modification History:
        @copyright: 2006 by Reimar Bauer
        @license: GNU GPL, see COPYING for details.
        
       1.6.0-2 2006-08-14 removed frame_ from paramter names
                          column:left and column:right removed becuse they are only floating elements
                          background_image, background_repeat, text_color, text_font_size added
       1.6.0-3 2006-08-15 bug fixes: position of float element wrong used and thick command failed for float
       1.6.0-4 2006-08-22 extended to use it for parsers too 
       
"""
import StringIO, os, mimetypes
from random import randint
from MoinMoin.parser import text_moin_wiki
from MoinMoin import wikiutil
from MoinMoin.action import AttachFile
from MoinMoin.util import web

Dependencies = []

class Parser:

    extensions = ['*']
    Dependencies = Dependencies

    def __init__(self, raw, request, **kw):
        self.raw = raw
        self.request = request

        self.align = 'left'  # secured

        self.text_align = 'left' #secured
        self.text_font_size = '' #secured
        self.text_color = 'black' #secured but wrong color code name crashes
        self.thick = 'thin' #secured
        self.style = 'solid' #secured
        self.color = 'black' #secured but wrong color code name crashes
        self.background = 'transparent' #secured but wrong color code name crashes
        self.background_image = None # secured by mimetype check
        self.background_repeat = 'no-repeat'
        self.position = 'relative' #secured
        self.width = 'auto' #needs a better idea to get it secure at the moment only % is allowed
        self.padding = '0em' #needs a better idea to get it secure at the moment only em is allowed
        self.margin = '0em' #needs a better idea to get it secure at the moment only em is allowed

        for arg in kw.get('format_args', '').split(','):
            if arg.find('=') > -1:
                key, value = arg.split('=')
                setattr(self, key, wikiutil.escape(value.strip(), quote=1))


    def format(self, formatter):
        raw = self.raw
        
        import string
        raw = string.split(raw, '\n')
        parser_name = ''
        for line in raw:
            if line.strip().startswith("#!"):
                parser_name = line.strip()[2:].split()[0]
                
                for arg in line.split(','):
                    if arg.find('=') > -1:
                        key, value = arg.split('=')
                        setattr(self, key, wikiutil.escape(value.strip(), quote=1))
        
        pagename = formatter.page.page_name
        
        out = StringIO.StringIO()
        self.request.redirect(out)
        if parser_name != '':
            self.request.write(formatter.parser(parser_name, raw))
        else:
            wikiizer = text_moin_wiki.Parser(self.raw, self.request)
            wikiizer.format(formatter)
        result = out.getvalue()
        self.request.redirect()
        del out

        if self.position in ['static', 'absolute', 'relative', 'fixed', 'inherit']:
            position = self.position
        else:
            position = 'relative'

        if self.thick in ['thin', 'medium', 'thick', '1px', '2px', '5px', '10px']:
            thick = self.thick
        else:
            thick = '0'

        if self.text_align in ['left', 'right', 'center', 'justify']:
            text_align = self.text_align
        else:
           text_align = 'left'

        if self.style in ['none', 'hidden', 'dotted', 'dashed', 'solid', 'double',
                          'groove', 'ridge', 'inset', 'outset']:
            style = self.style
        else:
            style = 'solid'

        if self.color != 'transparent':
            color = web.Color(str(self.color))
        else:
            color = 'black'

        if self.background != 'transparent':
            background = web.Color(str(self.background))
        else:
            background = 'transparent'

        if self.width.endswith("%"):
            width = str(float(self.width[:-1]))+'%'
        else:
            width = 'auto'

        if self.padding.endswith("em"):
            padding = str(float(self.padding[:-2]))+'em'
        else:
            padding = '0em'

        if self.margin.endswith("em"):
            margin = str(float(self.margin[:-2]))+'em'
        else:
            margin = '0em'

        if self.text_font_size in ['xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large',
                                   'smaller', 'larger']:
            text_font_size = self.text_font_size
        else:
            text_font_size = ''

        if self.text_color != 'transparent':
            text_color = web.Color(str(self.text_color))
        else:
            text_color = 'black'

        url = ''
        if self.background_image != None:
            attachment_path = AttachFile.getAttachDir(self.request, pagename)
            file = os.path.join(attachment_path, self.background_image)
            if os.path.exists(file):
                mime_type, enc = mimetypes.guess_type(file)
                if mime_type.startswith('image'):
                    url = AttachFile.getAttachUrl(pagename, self.background_image, self.request)

        if self.background_repeat in ['repeat', 'repeat-x', 'repeat-y', 'no-repeat']:
            background_repeat = self.background_repeat
        else:
            background_repeat = 'no-repeat'

        if self.align in ['left', 'right', 'center', 'justify']:
            div = '<div align="%(align)s" style="border-width:%(thick)s; border-color:%(color)s; border-style:%(style)s; position:%(position)s; padding:%(padding)s; margin:%(margin)s; background-color:%(background)s; font-size:%(text_font_size)s; color:%(text_color)s; background-image:url(%(background_image)s); background-repeat:%(background_repeat)s;" width="%(width)s">' % {
                    "thick": thick,
                    "style": style,
                    "color": color,
                    "position": position,
                    "padding": padding,
                    "margin": margin,
                    "background": background,
                    "width": width,
                    "text_align": text_align,
                    "text_font_size": text_font_size,
                    "text_color": text_color,
                    "background_image": url,
                    "background_repeat": background_repeat,
                    "align": self.align,
                    }
            self.request.write("%(div)s%(result)s</div>" % {
                 "div": div,
                 "result": result})

        if self.align in ['float:left', 'float:right']:
            tab = '<table style="%(align)s; font-size:%(text_font_size)s; color:%(text_color)s; text-align:%(text_align)s; background-image:url(%(background_image)s); background-repeat:%(background_repeat)s; position:%(position)s;"  width="%(width)s" border="%(thick)s" bgcolor="%(background)s"><tbody><tr><td style="border-style:none;">' % {
                    "align": self.align,
                    "text_font_size": text_font_size,
                    "text_align": text_align,
                    "text_color": text_color,
                    "position": position,
                    "width": width,
                    "thick": thick,
                    "background": background,
                    "background_image": url,
                    "background_repeat": background_repeat,
                }
            self.request.write("%(tab)s%(result)s</td></tr></tbody></table>" % {
                               "tab": tab,
                               "result": result})

        if self.align == 'clear':
            self.request.write('<br clear="both">')

