'''
css - syntax coloring css syles

Using simple 4-5 colors scheme is usually good, but some people would
like finer grain coloring. Therefore the styles are defined here in
classes and subclasses. A simple colorizer will use only the main
classes. A more complemx colorizer would use the sub classes.

Example:

    <span class="string comment"># This is an example</span>
    <span class="string docstring">""" This is a docstring """</span>
    <span class="string literal">"This is a literal"</span>

With this css rule, all these would render the same which can be fine
for most users:

    span.string {color: red}

But with this rules, each one will render differnt:

    span.string.comment {color: green}
    span.string.docstring {color: red}
    span.string.literal {color: orage}


Usage:

    >>>from css import classes
    >>>"<span class="%(keyword)s">class</span>" % classes
    <span class="statement keyword">class</span>

classes dict is immutable, (unless we add methods to edit it).

'''


class _Classes(object):
    """ Managed dictionary holding css classes """
    __slots__ = ['_dict']

    # This dict is temporray interal structure - dont try to access it.

    _dict  = {
        # class: [sub class, ...]
        'comment': [
            'docstring',
            'ignore',
            'todo',
            ],
        'constant': [
            'string',
            'character',
            'number',
            'boolean',
            'float',
            ],
        'identifier': [
            'function',
            'function-name',
            'variable',
            ],
        'statement': [
            'conditional',
            'repeat',
            'label',
            'operator',
            'keyword',
            'exception',
            'builtin',
            ],
        'preprocessor': [
            'include',
            'define',
            'macro',
            'precondition',
            ],
        'type': [
            'storageclass',
            'structure',
            'typedef',
            ],
        'special': [
            'specialchar',
            'tag',
            'delimeter',
            'special-comment',
            'debug',
            ],
        'underlined': [
            'reference',
            ],
        'error': [
            'warning',
            ],
        }

    def __init__(self):
        self.optimize()
        
    def optimize(self):
        """ Optimize css dict for fast access

        Move sub classes from their parent to the dict, so we can
        access them with single lookup.
        """
        dict = self._dict
        for cls in dict.keys():
            if isinstance(dict[cls], list):
                for subclass in dict[cls]:
                    if subclass in dict:
                        raise RuntimeError(
                            '%s: multiple subclass definition' % subclass)
                    dict[subclass] = cls
                dict[cls] = None

    def __getitem__(self, item):
        """ Return 'parent child' pair or raise KeyError

        Will raise standard KeyError for missnig keys.
        """
        parent = self._dict[item]
        if parent:
            return '%s %s' % (parent, item)
        return item
        
    def __getattr__(self, attr):
        """ Convinience method to accees keys as attributes """
        try:
            return self.__getitem__(attr)
        except KeyError, why:
            raise AttributeError(why)


classes = _Classes()


if __name__ == '__main__':
    c = classes
    # testing item access
    assert c['comment'] == 'comment'
    assert c['docstring'] == 'comment docstring'
    
    # testing attributes access
    assert c.comment == 'comment'
    assert c.docstring == 'comment docstring'

    # testing missing key
    try:
        c.nir
    except AttributeError:
        pass # :-)

    try:
        c["nir"]
    except KeyError:
        pass
    
