#!/usr/bin/python

import os
import re
import sys
from xml.dom.minidom import parse

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk


def extractMemberData(element, extraHeaders):
    className = element.attributes["class"].value
    isWidget = False
    if className == "GtkSourceView":
        className = "Gsv::View"
        extraHeaders.add("gtksourceviewmm.h")
        isWidget = True
    else:
        classType = Gtk.__getattr__(re.sub('^Gtk', '', className))
        className = re.sub('^Gtk', 'Gtk::', className)
        isWidget = issubclass(classType, Gtk.Widget)
    resource = None
    for child in element.childNodes:
        if child.nodeName == "property" and child.attributes["name"].value == "resource":
            resource = child.childNodes[0].data
    objectId = element.attributes["id"].value
    return {"class": className, "id": objectId, "res": resource, "iswidget": isWidget}

def genFormHeader(sourceFile):
    document = parse(sourceFile)
    extraHeaders = set()
    members = [extractMemberData(el, extraHeaders) for el in document.getElementsByTagName("object") if "id" in el.attributes]

    uiName = os.path.splitext(os.path.basename(sourceFile))[0]
    outputFile = "ui_" + uiName + '.hh'

    guardName = outputFile.upper().replace('.', '_')

    fh = open(outputFile, 'w')
    fh.write('// This file was autogenerated from %s\n\n' % sourceFile)
    fh.write('#ifndef %s\n' % guardName)
    fh.write('#define %s\n\n' % guardName)
    fh.write('#include <vector>\n')
    fh.write('#include <gtkmm.h>\n')
    for header in extraHeaders:
        fh.write('#include <%s>\n' % header)
    fh.write('\nnamespace Ui {\n')
    fh.write('struct %s {\n' % uiName)
    fh.write('\tGlib::RefPtr<Gtk::Builder> builder;\n')
    for member in members:
        if member["iswidget"] == True:
            fh.write('\t%s* %s = nullptr;\n' % (member["class"], member["id"]))
    fh.write('\n\t%s() {\n' % uiName)
    fh.write('\t\tbuilder = Gtk::Builder::create_from_resource("/org/gnome/gimagereader/%s");\n' % (uiName + '.ui'))
    fh.write('\t\tbuilder->set_translation_domain(GETTEXT_PACKAGE);\n')
    fh.write('\t}\n')
    fh.write('\n\tvoid setupUi() {\n')
    for member in members:
        if member["iswidget"] == True:
            fh.write('\t\tbuilder->get_widget("%s", %s);\n' % (member["id"], member["id"]))
            if member["res"]:
                fh.write('\t\t%s->set(Gdk::Pixbuf::create_from_resource("%s"));\n' % (member["id"], member["res"]))
    fh.write('\t}\n')
    fh.write('\n\t~%s() {\n' % uiName)
    fh.write('\t\tstd::vector<Gtk::Widget*> toplevelWidgets;\n')
    for member in members:
        if member["iswidget"] == True:
            fh.write('\t\tif(!%s->get_parent()) toplevelWidgets.push_back(%s);\n' % (member["id"], member["id"]))
    fh.write('\t\tstd::for_each(toplevelWidgets.begin(), toplevelWidgets.end(), [](Gtk::Widget* w) { delete w; });\n')
    fh.write('\t}\n')
    fh.write('};\n')
    fh.write('} // Ui\n')
    fh.write('#endif // %s\n' % guardName)
    fh.close()
    print("Wrote %s" % outputFile)

for sourceFile in sys.argv[1:]:
    genFormHeader(sourceFile)
