#!/usr/bin/env pythonw
# -*- coding: UTF-8 -*-
#
#  gnrhtml.py
#
#  Created by Giovanni Porcari on 2007-03-24.
#  Copyright (c) 2007 Softwell. All rights reserved.

from gnr.core.gnrbag import Bag
from gnr.core.gnrstring import splitAndStrip
from gnr.core.gnrstructures import GnrStructData
from gnr.core.gnrsys import expandpath

import sys

class GnrHtmlSrcError(Exception):
    pass
    
class GnrHtmlElem(object):
    def __init__(self, obj, tag):
        self.obj = obj
        self.tag = tag
        
    def __call__(self, *args, **kwargs):
        if self.tag in GnrHtmlSrc.html_autocontent_NS:
            if args:
                kwargs['content'], args = args[0], args[1:]
        child = self.obj.child(self.tag, *args, **kwargs)
        return child
        
class GnrHtmlSrc(GnrStructData):
    """Structure used to build server-side HTML pages.
    
    Prints and reports are based on this class.
    """
        
    html_base_NS = ['a', 'abbr', 'acronym', 'address', 'area', 'base', 'bdo', 'big', 'blockquote',
                    'body', 'br', 'button', 'caption', 'cite', 'code', 'col', 'colgroup', 'dd', 'del',
                    'dfn', 'dl', 'dt', 'em', 'fieldset', 'form', 'frame', 'frameset', 'head', 'hr', 'html',
                    'iframe', 'img', 'input', 'ins', 'kbd', 'label', 'legend', 'link', 'map', 'meta', 'noframes',
                    'noscript', 'object', 'ol', 'optgroup', 'option', 'param', 'samp', 'select', 'style',
                    'sub', 'sup', 'table', 'tbody', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'tt',
                    'ul', 'var']
                    
    gnrNS = ['layout', 'row', 'cell']
        
    html_autocontent_NS = ['div', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'span', 'td', 'li', 'b', 'i', 'small', 'strong',
                           'p', 'pre', 'q', ]
                           
    htmlNS = html_base_NS + html_autocontent_NS
        
    genroNameSpace = dict([(name.lower(), name) for name in htmlNS])
    genroNameSpace.update(dict([(name.lower(), name) for name in gnrNS]))
        
    def __getattr__(self, func_name):
        func_namelower = func_name.lower()
        if (func_name != func_namelower) and hasattr(self, func_namelower):
            return getattr(self, func_namelower)
        elif func_namelower in self.genroNameSpace:
            return GnrHtmlElem(self, '%s' % (self.genroNameSpace[func_namelower]))
            
        else:
            raise AttributeError, func_name
            
    def style(self, style='', **kwargs):
        """Creates a ``<style>`` tag.
        """
        self.root.builder.head.child('style', content=style, **kwargs)
        
    def comment(self, content=None):
        """Creates an HTML comment.
        """
        self.child(tag='__flatten__', content='<!--%s-->' % content)
        
    def script(self, script='', _type="text/javascript", **kwargs):
        """Creates a
 ``<script>`` tag.
        """
        self.root.builder.head.child('script', content=script, _type=_type, **kwargs)
        
    def link(self, href='', **kwargs ):
        """Creates a ``<link>`` tag.
        """
        self.root.builder.head.child('link', href=href, **kwargs)
        
    def csslink(self, href='', media='screen', **kwargs ):
        """Shortcut to create a ``<link rel="stylesheet" type="text/css"">`` tag.
        """
        self.ro
ot.builder.head.child('link', href=href, rel="stylesheet", _type="text/css", media=media, **kwargs)
        
    def meta(self, name=None, content=None, http_equiv=None, **kwargs):
        """Creates a ``<meta>`` tag.
        """
        _attributes = dict()
        if http_equiv:
            _attributes['http-equiv'] = http_equiv
        self.root.builder.head.child('meta', _name=name, _content=content, _attributes=_attributes, **kwargs)
        
    def child(self, tag, *args, **kwargs):
        """Creates a tag.
        """
        for lbl in ['_class', 'class_', '_type', 'type_', '_for', 'for_']:
            if lbl in kwargs:
                kwargs[lbl.replace('_', '')] = kwargs.pop(lbl)
                
        if 'name' in kwargs:
            kwargs['_name'] = kwargs.pop('name')
        return super(GnrHtmlSrc, self).child(tag, *args, **kwargs)
        
    def layout(self, name='l1', um='mm', top=0, left=0, bottom=0, right=0, width=0, height=0,
               border_width=0.3, border_color='grey', border_style='solid', row_border=True, cell_border=True,
               lbl_height=3, lbl_class='lbl_base', content_class='content_base',
               hasBorderTop=None, hasBorderLeft=None, hasBorderRight=None, hasBorderBottom=None,
               **kwargs):
        """Build the layout.
        
        :param name: the layout name. Default value is ``l1``
        :param um: add???. Default value is ``mm``
        :param top: the height of the top region. Default value is ``0``
        :param left: the width of the left region. Default value is ``0``
        :param bottom: the height of the bottom region. Default value is ``0``
        :param right: the width of the right region. Default value is ``0``
        :param width: layout's width. Default value is ``0``
        :param height: layout's height. Default value is ``0``
        :param border_width: add the border width. Default value is ``0.3``
        :param border_color: add the border color. Default value is ``grey``
        :param border_style: add the border style. Default value is ``solid``
        :param row_border: add the row border. Default value is ``True``
        :param cell_border: add the cell border. Default value is ``True``
        :param lbl_height: add the label height. Default value is ``3``
        :param lbl_class: add the label class. Default value is ``lbl_base``
        :param content_class: add the content class. Default value is ``content_base``
        :param hasBorderTop: add the top border. Default value is ``None``
        :param hasBorderLeft: add the left border. Default value is ``None``
        :param hasBorderRight: add the right border. Default value is ``None``
        :param hasBorderBottom: add the bottom border. Default value is ``None``
        :returns: the layout
        """
        self.style(".%s_layout{border:%s%s %s %s;position:absolute;}" % (
        name, border_width, um, border_style, border_color))
            
        layout = self.child(tag='layout', **kwargs)
        layout.layout_name = name
        layout.layout_class = '%s_layout' % name
        layout.um = um
        layout.top = float(top or 0)
        layout.left = float(left or 0)
        layout.bottom = float(bottom or 0)
        layout.right = float(right or 0)
        layout.width = float(width or 0)
        layout.height = float(height or 0)
        layout.border_width = float(border_width or 0)
        layout.border_color = border_color
        layout.border_style = border_style
        layout.row_border = row_border
        layout.cell_border = cell_border
        layout.lbl_height = float(lbl_height or 0)
        layout.lbl_class = lbl_class
        layout.content_class = content_class
        layout.elastic_rows = []
        layout.hasBorderTop = hasBorderTop
        layout.hasBorderLeft = hasBorderLeft
        layout.hasBorderRight = hasBorderRight
        layout.hasBorderBottom = hasBorderBottom
        layout.nested = self.parentNode.getAttr('tag') == 'cell'
        return layout
            
    def row(self, height=0, row_border=None, cell_border=None, lbl_height=None, lbl_class=None, content_class=None,
            **kwargs):
        """Construct a row.
        
        :param height: the row's height. Default value is ``0``
        :param row_border: the row's border. Default value is ``None``
        :param cell_border: the border of the row's cell. Default value is ``None``
        :param lbl_height: the height of the row's label. Default value is ``None``
        :param lbl_class: the class of the row's label. Default value is ``None``
        :param content_class: the class of the row's content. Default value is ``None``
        :returns: the row
        """
        assert self.parentNode.getAttr('tag') == 'layout'
        lay