#!/usr/bin/python3
# -*- coding: utf-8 -*-

#  Copyright © 2013-2015  B. Clausius <barcc@gmx.de>
#
#  This program is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.

import sys, os
import itertools
from collections import OrderedDict
from xml.etree import ElementTree


def get_string(prop):
    string = prop.find('string')
    if string is None or string.attrib.get('notr') == 'true':
        return None
    return string.text
    
def parse_file(filename):
    tree = ElementTree.parse(filename)
    root = tree.getroot()
    window = root.find('widget')
    widgets = OrderedDict()
    child_items = []
    
    for prop in window.findall('property'):
        text = get_string(prop)
        if text is not None:
            child_items.append(('window', prop.attrib['name'], text))
    for tag in window:
        for widget in itertools.chain(tag.iter('widget'), tag.iter('action')):
            if widget.tag == 'widget':
                widget_class = widget.attrib['class']
            else:
                widget_class = 'QAction'
            widget_name = widget.attrib['name']
            for prop in itertools.chain(widget.findall('property'), widget.findall('attribute')):
                itemtype = prop.tag
                prop_name = prop.attrib['name']
                text = get_string(prop)
                if text is None:
                    continue
                if itemtype == 'property':
                    child_items.append((itemtype, widget_class, widget_name, prop_name, text))
                if itemtype == 'attribute':
                    parent = window.find(".//*[@name='%s']/.." % widget_name)
                    if parent and parent.attrib.get('class') == 'QTabWidget':
                        parent_name = parent.attrib['name']
                        widgets.setdefault(parent_name, 'QTabWidget')
                        child_items.append(('QTabWidget', parent_name, widget_name, text))
                    else:
                        child_items.append((itemtype, widget_class, widget_name, prop_name, text))
            if widget_class.startswith('Q'):
                widgets.setdefault(widget_name, widget_class)
    return window.attrib['class'], widgets, child_items
    
def write_file(window_class, widgets, child_items, file):
    print(
'''# -*- coding: utf-8 -*-
# auto-generated file

from PyQt5.QtWidgets import {}

def retranslate(window):'''.format(', '.join(sorted(set(widgets.values())))), file=file)
    
    print('    class UI:', file=file)
    print('        __slots__ = ()', file=file)
    for widget_name, widget_class in widgets.items():
        print('        {1} = window.findChild({0}, {1!r})'.format(widget_class, widget_name), file=file)
    print('    ui = UI()\n', file=file)
    
    for itemtype, *itemargs in child_items:
        if itemtype == 'window':
            prop_name, text = itemargs
            prop_name = ''.join(('set', prop_name[0].upper(), prop_name[1:]))
            print('    window.{}(_({!r}))'.format(prop_name, text), file=file)
        elif itemtype == 'property':
            widget_class, *itemargs = itemargs
            print('    ui.{0}.setProperty({1!r}, _({2!r}))'.format(*itemargs), file=file)
            if widget_class == 'QAction':
                print('    window.addAction(ui.{0})'.format(*itemargs), file=file)
        elif itemtype == 'QTabWidget':
            print('    ui.{0}.setTabText(ui.{0}.indexOf(ui.{1}), _({2!r}))'.format(*itemargs), file=file)
        else:
            print('    #unknown:', itemtype, *itemargs)
        
    print('\n    return ui\n', file=file)
    
def usage(exitcode):
    print('usage:')
    print(' ', os.path.basename(__file__), '-h|--help')
    print(' ', os.path.basename(__file__), 'uifilename')
    print(' ', os.path.basename(__file__), 'uifilename', 'pyfilename')
    sys.exit(exitcode)
    
def main():
    args = sys.argv[1:]
    if not args:
        usage(1)
    if args[0] in ['-h', '--help']:
        usage(0)
    windowinfo = parse_file(args[0])
    args = args[1:]
    if args:
        with open(args[0], 'wt', encoding='utf-8') as file:
            write_file(*windowinfo, file=file)
    else:
        write_file(*windowinfo, file=sys.stdout)
        
        
if __name__ == '__main__':
    main()
    

