#!/usr/bin/env python
#coding:utf-8
# Author:  mozman --<mozman@gmx.at>
# Purpose: create tiny data
# Created: 02.10.2010
# Copyright (C) 2010, Manfred Moitzi
# License: GPLv3

import sys
import urllib2
import urlparse

import cache
from BeautifulSoup import BeautifulSoup
from itertools import chain

# cache W3C html pages - they do not change often ;-)
urlopener = urllib2.build_opener(cache.CacheHandler(".cache"))

W3CURL = "http://www.w3.org/TR/SVG11/"
ZVONURL = "http://www.zvon.org/xxl/svgReference/Output/"
ZVON_ATTRS = "http://www.zvon.org/xxl/svgReference/Output/attrs.html"

ELEMENT_INDEX = "http://www.w3.org/TR/SVG11/eltindex.html"
ELEMENTS_WITH_PROPERTIES = ['a', 'altGlyph', 'circle', 'clipPath', 'defs', 'ellipse', 'feBlend',
                            'feColorMatrix', 'feComponentTransfer', 'feComposite', 'feConvolveMatrix',
                            'feDiffuseLighting', 'feDisplacementMap', 'feFlood', 'feGaussianBlur',
                            'feImage', 'feMerge', 'feMorphology', 'feOffset', 'feSpecularLighting',
                            'feTile', 'feTurbulence', 'filter', 'font', 'foreignObject', 'g', 'glyph',
                            'glyphRef', 'image', 'line', 'linearGradient', 'marker', 'mask', 'missing-glyph',
                            'path', 'pattern', 'polygon', 'polyline', 'radialGradient', 'rect', 'stop', 'svg',
                            'switch', 'symbol', 'text', 'textPath', 'tref', 'tspan', 'use']

PREFACE_ELEMENTS = """#coding:utf-8
# generated by:  %s

from svgwrite.types import SVGElement

presentation_attributes = frozenset([ "alignment-baseline", "baseline-shift",
    "clip", "clip-path", "clip-rule", "color", "color-interpolation",
    "color-interpolation-filters", "color-profile", "color-rendering", "cursor",
    "direction", "display", "dominant-baseline", "enable-background",
    "fill", "fill-opacity", "fill-rule", "filter", "flood-color",
    "flood-opacity", "font-family", "font-size", "font-size-adjust",
    "font-stretch", "font-style", "font-variant", "font-weight",
    "glyph-orientation-horizontal", "glyph-orientation-vertical",
    "image-rendering", "kerning", "letter-spacing", "lighting-color",
    "marker-end", "marker-mid", "marker-start", "mask", "opacity",
    "overflow", "pointer-events", "shape-rendering", "stop-color",
    "stop-opacity", "stroke", "stroke-dasharray", "stroke-dashoffset",
    "stroke-linecap", "stroke-linejoin", "stroke-miterlimit",
    "stroke-opacity", "stroke-width", "text-anchor", "text-decoration",
    "text-rendering", "unicode-bidi", "visibility", "word-spacing",
    "writing-mode"])

""" % __file__

PREFACE_ATTRIBUTES = """#coding:utf-8
# generated by:  %s

from svgwrite.types import SVGAttribute

""" % __file__

class SVGElement(object):
    def __init__(self, name, attribute_names, possible_children):
        self.name = name
        self.attribute_names = attribute_names
        self.possible_children = possible_children

    def __str__(self):
        return self.name

    def tostring(self):
        if self.name in ELEMENTS_WITH_PROPERTIES:
            properties = 'presentation_attributes'
        else:
            properties = '[]'
        return "SVGElement('%s',\n    attributes=%s,\n    properties=%s,\n    children=%s)" % (
            self.name,
            self.attribute_names,
            properties,
            self.possible_children)


class SVGProp(object):
    valid_types = frozenset(['<number>', '<coordinate>', '<length>', '<attributeName>',
                       '<percentage>', '<profile-name>', '<string>', '<value>',
                       '<begin-value-list>', '<shape>', '<uri>', '<color>',
                       '<name>', '<content-type>', '<Clock-value>', '<end-value-list>',
                       '<opacity-value>', '<angle>', '<transform-list>',
                       '<list of numbers>', '<integer>', '<script>', '<path-data>',
                       '<list-of-points>', '<number-optional-number>',
                       '<filter-primitive-reference>', '<miterlimit>',
                       '<LanguageCodes>', '<NMTOKEN>'])
    def __init__(self, name, valuestr):
        self.name = name
        values = [value.strip() for value in valuestr.split('|')]
        self.types = self.gettypes(values)
        self.const = self.getconst(values)

    def __str__(self):
        return self.name

    def tostring(self):
        return "SVGAttribute('%s', anim=%s, \n    types=%s,\n    const=%s)" % (
            self.name,
            True,
            self.types,
            self.const)
    def gettypes(self, values):
        values = set(values)
        return frozenset([t[1:-1] for t in values.intersection(SVGProp.valid_types)])

    def getconst(self, values):
        values = set(values)
        return frozenset(values.difference(SVGProp.valid_types))

def write_elements(filename, elements):
    f = open(filename, 'w')
    f.write(PREFACE_ELEMENTS)
    f.write("full11_elements = { \n")
    keys = elements.keys()
    keys.sort()
    for name in keys:
        element = elements[name]
        f.write("    '%s': %s,\n\n" % (name, element.tostring()))
    f.write("}\n")
    f.close()

def create_elements_data(attributes, children):
    elements = {}
    for name, attribute_names in attributes.items():
        try:
            possible_children = children[name]
        except KeyError:
            possible_children = []
        element = SVGElement(name, attribute_names, possible_children)
        print element
        elements[name] = element
    return elements

def process_elements():
    from oldfull11data import get_content_model, get_valid_attributes
    children = get_content_model()
    attributes = get_valid_attributes()
    elements = create_elements_data(attributes, children)
    write_elements("full11elements.py", elements)

def create_attribs_data(table):
    tabledata = table.findAll('td')
    attributes = []
    for td in tabledata:
        name = td.getText()
        data = dict(td.a.attrs)
        link = data['href']
        soup = BeautifulSoup(urlopener.open(ZVONURL+link[2:]))
        value = soup.find('td', 'values').getText()
        value = value.replace('&lt;', '<')
        value = value.replace('&gt;', '>')
        value = value.replace('[', ' ')
        value = value.replace(']', ' ')
        attributes.append(SVGProp(name, value))
    return attributes

def write_attributes(attributes):
    f = open("full11attributes.py", 'w')
    f.write(PREFACE_ATTRIBUTES)
    f.write("full11_attributes = {\n")
    for attribute in attributes:
        f.write("'%s': %s,\n" % (attribute.name, attribute.tostring()))
    f.write("}\n")

def process_attributes():
    soup = BeautifulSoup(urlopener.open(ZVON_ATTRS))
    tables = soup.findAll('table')
    attributes = create_attribs_data(tables[2])
    write_attributes(attributes)

def main():
    #process_elements()
    process_attributes()

if __name__=='__main__':
    main()