from lxml import etree
from io import StringIO, BytesIO


import argparse
import glob
import os
import sys
import time
import traceback
from functools import partial

from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import (
    QDial,
    QSlider,
    QProgressBar,
    QGroupBox,
    QTextEdit,
    QLineEdit,
    QVBoxLayout,
    QHBoxLayout,
    QApplication,
    QCheckBox,
    QComboBox,
    QDialog,
    QDialogButtonBox,
    QSpinBox,
    QDoubleSpinBox,
    QGridLayout,
    QHBoxLayout,
    QLabel,
    QListWidget,
    QPushButton,
    QSlider,
    QTableWidget,
    QTableWidgetItem,
    QVBoxLayout,
    QWidget,
    QRadioButton,
    QTabWidget,
)


class WinForm(QWidget):
    def __init__(self, args, parent=None):
        if not args.xmlfile:
            exit(1)

        super(WinForm, self).__init__(parent)
        self.setWindowTitle(f"PYVCP: {args.xmlfile[0]}")
        xml = open(args.xmlfile[0], "rb").read()
        root = etree.fromstring(xml, parser=etree.XMLParser(remove_comments=True))

        layout = QVBoxLayout()
        self.setLayout(layout)

        for child in root.iterchildren():
            self.show_element(child, layout)

    def show_element(self, element, layout):
        if hasattr(self, f"show_{element.tag}"):
            getattr(self, f"show_{element.tag}")(element, layout)
        else:
            print(f"missing type: {element.tag}")
            layout.addWidget(QLabel(f"## {element.tag} ##"))

    def show_radiobutton(self, element, layout):
        choices = []
        for child in element.iterchildren():
            if child.tag == "choices":
                for name in child.text.strip("[").strip("]").split(","):
                    title = name.strip().strip("'").strip("\"")
                    choices.append(title)
                    radio = QRadioButton(title)
                    layout.addWidget(radio)

    def show_scale(self, element, layout):
        orient = "HORIZONTAL"
        for child in element.iterchildren():
            if child.tag == "orient":
                orient = child.text
        if orient == "HORIZONTAL":
            slider = QSlider(Qt.Horizontal)
        else:
            slider = QSlider(Qt.Vertical)
            slider.setMinimumHeight(50)

        for child in element.iterchildren():
            if child.tag == "min":
                slider.setMinimum(float(child.text))
            if child.tag == "max":
                slider.setMaximum(float(child.text))
        layout.addWidget(slider)

    def show_bar(self, element, layout):
        bar = QProgressBar()

        for child in element.iterchildren():
            if child.tag == "min":
                bar.setMinimum(float(child.text))
            if child.tag == "max":
                bar.setMaximum(float(child.text))

        # bar.setOrientation(1)
        bar.setValue(1)
        layout.addWidget(bar)

    def show_dial(self, element, layout):
        text = ""
        for child in element.iterchildren():
            if child.tag == "text":
                text = child.text.strip('"')
        label = QDial()
        layout.addWidget(label)

    def show_jogwheel(self, element, layout):
        text = ""
        for child in element.iterchildren():
            if child.tag == "text":
                text = child.text.strip('"')
        label = QDial()
        layout.addWidget(label)

    def show_button(self, element, layout):
        text = ""
        for child in element.iterchildren():
            if child.tag == "text":
                text = child.text.strip('"')
        label = QPushButton(text)
        layout.addWidget(label)

    def show_checkbutton(self, element, layout):
        text = ""
        for child in element.iterchildren():
            if child.tag == "text":
                text = child.text.strip('"')
        label = QCheckBox(text)
        layout.addWidget(label)

    def show_label(self, element, layout):
        text = ""
        for child in element.iterchildren():
            if child.tag == "text":
                text = child.text.strip('"')
        label = QLabel(text)
        layout.addWidget(label)

    def show_u32(self, element, layout):
        self.show_number(element, layout)

    def show_s32(self, element, layout):
        self.show_number(element, layout)

    def show_number(self, element, layout):
        fmt = "0.1f"
        for child in element.iterchildren():
            if child.tag == "format":
                fmt = child.text.strip('"')
        label = QLabel(f"%{fmt}" % (0.00,))
        layout.addWidget(label)

    def show_spinbox(self, element, layout):
        spinbox = QDoubleSpinBox()
        layout.addWidget(spinbox)

    def show_led(self, element, layout):
        label = QLabel("*")
        layout.addWidget(label)

    def show_labelframe(self, element, layout):
        gbox_layout = QVBoxLayout()
        gbox_widget = QGroupBox()
        gbox_widget.setTitle(element.get("text", ""))
        gbox_widget.setLayout(gbox_layout)
        layout.addWidget(gbox_widget)
        for child in element.iterchildren():
            if child.tag not in {"relief", "font", "bd"}:
                self.show_element(child, gbox_layout)
        layout.addStretch()

    def show_vbox(self, element, layout):
        vbox_layout = QVBoxLayout()
        vbox_widget = QWidget()
        vbox_widget.setLayout(vbox_layout)
        layout.addWidget(vbox_widget)
        for child in element.iterchildren():
            if child.tag not in {"relief", "font", "bd"}:
                self.show_element(child, vbox_layout)
        layout.addStretch()

    def show_hbox(self, element, layout):
        hbox_layout = QHBoxLayout()
        hbox_widget = QWidget()
        hbox_widget.setLayout(hbox_layout)
        layout.addWidget(hbox_widget)
        for child in element.iterchildren():
            if child.tag not in {"relief", "font", "bd"}:
                self.show_element(child, hbox_layout)
        layout.addStretch()

    def show_tabs(self, element, layout):
        tab_names = []
        for child in element.iterchildren():
            if child.tag == "names":
                for name in child.text.strip("[").strip("]").split(","):
                    tab_names.append(name.strip().strip("'").strip("\""))

        tabwidget = QTabWidget()
        layout.addWidget(tabwidget)

        tab_n = 0
        for child in element.iterchildren():
            if child.tag == "names":
                continue

            tab_inner_widget = QWidget()
            tab_inner_layout = QVBoxLayout()
            tab_inner_widget.setLayout(tab_inner_layout)
            tabwidget.addTab(tab_inner_widget, tab_names[tab_n])
            tab_n += 1

            self.show_element(child, tab_inner_layout)


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("xmlfile", help="xmlfile", nargs=1, type=str, default=None)
    args = parser.parse_args()

    app = QApplication(sys.argv)
    form = WinForm(args)
    form.show()
    sys.exit(app.exec_())