
import xml.dom.minidom as minidom
import xml.dom as dom
import models

def make_dom():
    dom = minidom.parse('cheat_sheet.xml')
    return dom

def parse_data(text):
    text = text.replace('<code>', '{{{')
    text = text.replace('</code>', '}}}')
    text = text.replace('<a href="', '[[')
    text = text.replace('">', '|')
    text = text.replace('</a>', ']]')
    text = text.replace('&quot;', '"')
    return text


def parse_text(node):
    data = ''.join([n.toxml() for n in node.childNodes])
    return parse_data(data)

def parse_args(args_element, wxmethod):
    for arg_element in args_element.getElementsByTagName('arg'):
        wiki_text = parse_text(arg_element)
        wxmethod.args.append(wiki_text)
        if arg_element.getAttribute('emphasize') == 'True':
            wxmethod.args_of_interest.append(wiki_text)


def parse_styles(styles_element, wxmethod):
    for style_element in styles_element.getElementsByTagName('style'):
        wiki_text = parse_text(style_element)
        if style_element.getAttribute('default') == 'True':
            wxmethod.default_styles.append(wiki_text)
        else:
            wxmethod.styles.append(wiki_text)
            

def parse_method(method_element, wxclass):
    name = method_element.getAttribute('name')
    print '  ' + name
    wxmethod = models.wxMethod(name, wxclass)
    #print ' '*8 + wxmethod.name
    for child in method_element.childNodes:
        if child.nodeName == 'description':
            wxmethod.description = parse_text(child)
            #print ' '*12 + wxmethod.description
        elif child.nodeName == 'args':
            parse_args(child, wxmethod)
        elif child.nodeName == 'styles':
            parse_styles(child, wxmethod)
        elif child.nodeName == 'notes':
            note_elements = child.getElementsByTagName('note')
            wxmethod.notes = [parse_text(e) for e in note_elements]
    return wxmethod

def parse_methods(methods_element, wxclass):
    method_elements = methods_element.getElementsByTagName('method')
    return [parse_method(e, wxclass) for e in method_elements]


def parse_wxclass(wxclass_element):
    name = wxclass_element.getAttribute('name')
    print name
    wxclass = models.wxClass(name)
    #print '    Class: ' + wxclass.name
    for child in wxclass_element.childNodes:
        if child.nodeName == 'description':
            wxclass.description = parse_text(child)
            #print '    ' + wxclass.description
        elif child.nodeName == 'events':
            event_elements = child.getElementsByTagName('event')
            for e in event_elements:
                wxclass.events = [parse_text(e) for e in event_elements]
            #print '    Events: ' + str(wxclass.events)
        elif child.nodeName == 'notes':
            note_elements = child.getElementsByTagName('note')
            wxclass.notes = [parse_text(e) for e in note_elements]
            #print '    Notes: ' + str(wxclass.notes)            
        elif child.nodeName == 'methods':
            wxclass.methods = parse_methods(child, wxclass)

    return wxclass
                
            
def parse_category(cat_element):
    name = cat_element.getAttribute('name')
    #print 'Category: ' + name
    wxclasses = cat_element.getElementsByTagName('wxclass')
    wxclasses = [parse_wxclass(c) for c in wxclasses]

    return (name, wxclasses)


def parse_xml():
    dom = make_dom()
    categories = dom.getElementsByTagName('category')
    categories = [parse_category(cat) for cat in categories]

    return categories


def make_wxclass_toc(sheet):
    s = ''
    for category in sheet:
        name = category[0]
        wxclasses = category[1]
        s += '{{{wx.' + name + '}}}:\n '
        s += ', '.join([c.toc_str() for c in wxclasses])
        s += '<<BR>>\n'
    return s


def make_wxclass_notes(sheet):
    s = ''
    for category in sheet:
        name = category[0]
        wxclasses = category[1]
        s += '== ' + name + ' classes ==\n\n'
        for c in wxclasses:
            s += str(c)
    return s


def make_sheet():
    s = '###\n###DO NOT EDIT\n###\n'
    s += '= wxPython Classes Cheat Sheet =\n\n'
    s += 'A wikipage to help you write scripts which was generated by a script'
    s += ' attatched to the wikipage.\n\n'
    s += 'NB: Think of this page as a collection of shortcuts to the docs.'
    s += ' It is not comprehensive in any way. There are many more classes'
    s += ' in the wx library than listed here, and most classes have many more'
    s += ' methods.\nI only add to this page as I encounter new features that I'
    s += " need in my projects, and I've just discovered PySide. - Anthony.\n\n"
    s +=  '<<Anchor(Top)>>'
    s += "'''Contents:'''\n\n"

    sheet = parse_xml()
    s += make_wxclass_toc(sheet)
    s += make_wxclass_notes(sheet)

    s += '----\n'
    s += 'This page was created by AnthonyGlaser.\n\n'
    s += "Please don't edit this page directly. Instead, download "
    s += "[[attachment:cheat_sheet.xml]], [[attachment:models.py]] "
    s += ", and [[attachment:xml_parser.py]]. Modify cheat_sheet.xml "
    s += "and run the function {{{write_sheet}}} in xml_parser.py. "
    s += " Upload the output and attach any changed files.\n\nOr just "
    s += "[[http://www.youtube.com/watch?v=9hmDZz5pDOQ|stay tuned]]"
    s += " for updates."""
    return s

def write_sheet():
    with open('WxClassesCheatSheet.txt', 'w') as f:
        f.write(make_sheet())


if __name__ == '__main__':

    write_sheet()
