#!/bin/env python3
# pylint: disable=missing-class-docstring,missing-function-docstring

'''
qtplasmac-materials.py

Copyright (C) 2020, 2021 Phillip A Carter
Copyright (C) 2020, 2021  Gregory D Carl

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 2 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, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
'''

import os
import sys
import json
from PyQt5.QtCore import Qt, QCoreApplication, QLocale, QTranslator
from PyQt5.QtWidgets import (
    QMainWindow,
    QWidget,
    QHBoxLayout,
    QGridLayout,
    QButtonGroup,
    QRadioButton,
    QLabel,
    QPushButton,
    QLineEdit,
    QFileDialog,
    QDialog,
    QDialogButtonBox,
    QSpacerItem,
    QVBoxLayout,
    QApplication
)
from PyQt5.QtGui import QIcon
from qtvcp.lib.preferences import Access

LANGPATH = '/usr/share/qtvcp/screens/qtarmpg/languages'
BASEPATH = os.path.dirname(__file__)
BASENAME = os.path.splitext(os.path.basename(__file__))[0]
_translate = QCoreApplication.translate

class MaterialConverter(QMainWindow):
    # pylint: disable=too-many-instance-attributes,invalid-name
    CONVERT_STATE_CREATE = 1
    CONVERT_STATE_COVNERT = 2
    CONVERT_STATE_ADD = 3

    def __init__(self, parent=None):
        super().__init__(parent)

        self.prefs_file_path = os.path.realpath(os.path.join(BASEPATH, '..', 'configs', BASENAME + '.prefs'))
        print('---debug: PATH = ',self.prefs_file_path)
        self.prefs = Access(self.prefs_file_path)

        self.convert_state = self.CONVERT_STATE_COVNERT

        wid = QWidget(self)
        self.setCentralWidget(wid)
        self.layout = QHBoxLayout()
        wid.setLayout(self.layout)
        self.iconPath = 'share/qtvcp/images/qtplasmac/images/Chips_Plasma.png'
        appPath = os.path.realpath(os.path.dirname(sys.argv[0]))
        self.iconBase = '/usr' if appPath == '/bin' else appPath.replace('/bin', '')
        self.setWindowIcon(QIcon(os.path.join(self.iconBase, self.iconPath)))
        self.setWindowTitle(_translate('MaterialConverter', 'SIBERIA Material File Converter'))
        self.create_widgets()

        self.inButton.setEnabled(True)
        self.inFile.setEnabled(True)
        # self.outUnits.hide()
        # self.outMetric.hide()
        # self.outImperial.hide()
        self.inButton.pressed.connect(self.on_in_button_pressed)
        self.outButton.pressed.connect(self.on_out_button_pressed)
        self.unitsGroup.buttonClicked.connect(self.units_group_clicked)
        self.modeGroup.buttonClicked.connect(self.mode_group_clicked)
        self.convert.pressed.connect(self.on_convert_clicked)
        self.cancel.pressed.connect(self.on_cancel_clicked)
        self.divisor = 1
        self.precision = 2
        # self.inFileName = ''
        # self.outFileName = ''
        self.fNUM = '1'
        self.fNAM = '0'
        self.fKW = '0'
        self.fPH = '0'
        self.fPD = '0'
        self.fPJH = '0'
        self.fPJD = '0'
        self.fCH = '0'
        self.fCS = '0'
        self.fCA = '0'
        self.fCV = '0'
        self.fPE = '0'
        self.fGP = '0'
        self.fCM = '1'
        self.fPHT = '0'

        savedInFile = self.prefs.getpref('Input File', '', str, 'LAST_STATE')
        if savedInFile:
            self.inFile.setText(savedInFile)
            self.inFileName = savedInFile

        savedOutFile = self.prefs.getpref('Output File', '', str, 'LAST_STATE')
        if savedOutFile:
            self.outFile.setText(savedOutFile)
            self.outFileName = savedOutFile

        wid.setStyleSheet('* {color: #ffee06; background: #16160e; font: 12pt DejaVuSans} \
                          QLabel {height: 20; width: 120} \
                          QPushButton {border: 1px solid #ffee06; border-radius: 4; height: 20; width: 160} \
                          QPushButton:disabled {color: #16160e; border: none} \
                          QPushButton:pressed {color: #16160e; background: #ffee06} \
                          QLineEdit {border: 1px solid #ffee06; border-radius: 4; height: 20; width: 460} \
                          QLineEdit:disabled {color: #16160e; border: none} \
                          QRadioButton::indicator {border: 1px solid #ffee06; border-radius: 4; height: 20; width: 20} \
                          QRadioButton::indicator:checked {background: #ffee06}' \
                         )

    def create_widgets(self):
        # pylint: disable=too-many-statements
        self.T = QGridLayout()
        self.layout.addLayout(self.T)
        self.modeGroup = QButtonGroup()
        self.inManual = QRadioButton(_translate('MaterialConverter', 'Manual'))
        self.T.addWidget(self.inManual, 0, 0, 1, 1)
        self.modeGroup.addButton(self.inManual)
        self.inSheetcam = QRadioButton('SheetCam')
        self.inSheetcam.setChecked(True)
        self.T.addWidget(self.inSheetcam, 1, 0, 1, 1)
        self.modeGroup.addButton(self.inSheetcam)
        self.inFusion = QRadioButton('Fusion 360')
        self.T.addWidget(self.inFusion, 2, 0, 1, 1)
        self.modeGroup.addButton(self.inFusion)
        self.outUnits = QLabel(_translate('MaterialConverter', 'OUTPUT UNITS:'))
        self.T.addWidget(self.outUnits, 0, 2, 1, 1)
        self.unitsGroup = QButtonGroup()
        self.outMetric = QRadioButton(_translate('MaterialConverter', 'METRIC'))
        self.outMetric.setChecked(True)
        self.T.addWidget(self.outMetric, 0, 3, 1, 1)
        self.unitsGroup.addButton(self.outMetric)
        self.outImperial = QRadioButton(_translate('MaterialConverter', 'IMPERIAL'))
        self.T.addWidget(self.outImperial, 1, 3, 1, 1)
        self.unitsGroup.addButton(self.outImperial)
        v2 = QLabel('')
        self.T.addWidget(v2, 3, 0)
        self.inButton = QPushButton(_translate('MaterialConverter', 'INPUT:'))
        # self.inButton.setLayout()
        self.inButton.setStyleSheet("text-align: right; padding-right: 1em")
        self.T.addWidget(self.inButton, 4, 0, 1, 1)
        self.inFile = QLineEdit()
        self.T.addWidget(self.inFile, 4, 1, 1, 3)
        self.outButton = QPushButton(_translate('MaterialConverter', 'OUTPUT:'))
        self.outButton.setStyleSheet("text-align: right; padding-right: 1em")
        self.T.addWidget(self.outButton, 5, 0, 1, 1)
        self.outFile = QLineEdit()
        self.T.addWidget(self.outFile, 5, 1, 1, 3)
        self.msgLabel = QLabel('')
        self.msgLabel.setAlignment(Qt.AlignCenter)
        self.T.addWidget(self.msgLabel, 6, 0, 1, 4)
        self.convert = QPushButton(_translate('MaterialConverter', 'CONVERT'))
        # self.convert.setFixedWidth(120)
        self.convert_state = self.CONVERT_STATE_COVNERT
        self.T.addWidget(self.convert, 7, 0, 1, 1)
        h1 = QLabel('')
        self.T.addWidget(h1, 7, 1, 1, 1)
        h2 = QLabel('')
        self.T.addWidget(h2, 7, 2, 1, 1)
        h3 = QLabel('')
        self.T.addWidget(h3, 7, 3, 1, 1)
        self.cancel = QPushButton(_translate('MaterialConverter', 'EXIT'))
        self.T.addWidget(self.cancel, 7, 3, 1, 1)

    def on_in_button_pressed(self):
        self.msgLabel.setText('')
        if self.inSheetcam.isChecked():
            capt = _translate('MaterialConverter', 'Select SheetCam Tool File')
            filt = _translate('MaterialConverter',
                              'Tool Files (*.[Tt][Oo][Oo][Ll][Ss]);;All Files (*)')
        elif self.inFusion.isChecked():
            capt = _translate('MaterialConverter', 'Select Fusion360 Tool File')
            filt = _translate('MaterialConverter', 'Tool Files (*.[Jj][Ss][Oo][Nn]);;All Files (*)')
        # name, _ = QFileDialog.getOpenFileName(self, capt, '~/', filt, filt,
        #                                       QFileDialog.DontUseNativeDialog)
        name, _ = QFileDialog.getOpenFileName(self, capt, '~/', filt, filt)
        if name:
            self.inFile.setText(name)
            self.inFileName = name
        else:
            self.inFile.setText('')
            self.inFileName = ''
        self.prefs.putpref('Input File', self.inFileName, str, 'LAST_STATE')

    def on_out_button_pressed(self):
        self.msgLabel.setText('')
        capt = _translate('MaterialConverter', 'QtPlasmaC Material File')
        filt = _translate('MaterialConverter', 'Material Files (*.cfg);;All Files (*)')
        # name, _ = QFileDialog.getSaveFileName(self, capt, '~/', filt, filt,
        #                                       QFileDialog.DontUseNativeDialog)
        name, _ = QFileDialog.getSaveFileName(self, capt, '~/', filt, filt)
        if name:
            self.outFile.setText(name)
            self.outFileName = name
        else:
            self.outFile.setText('')
            self.outFileName = ''
        self.prefs.putpref('Output File', self.outFileName, str, 'LAST_STATE')

    def units_group_clicked(self, button):
        self.msgLabel.setText('')
        if button.isChecked():
            if button == self.outMetric:
                self.divisor = 1
                self.precision = 2
            else:
                self.divisor = 25.4
                self.precision = 3

    def mode_group_clicked(self, button):
        self.msgLabel.setText('')
        if button.isChecked():
            if button == self.inManual:
                self.outUnits.hide()
                self.outMetric.hide()
                self.outImperial.hide()
                self.inButton.setEnabled(False)
                self.inFile.setEnabled(False)
                self.convert_state = self.CONVERT_STATE_CREATE
                self.convert.setText(_translate('MaterialConverter', 'CREATE'))
            elif button == self.inSheetcam:
                self.outUnits.show()
                self.outMetric.show()
                self.outImperial.show()
                self.inButton.setEnabled(True)
                self.inFile.setEnabled(True)
                self.convert_state = self.CONVERT_STATE_COVNERT
                self.convert.setText(_translate('MaterialConverter', 'CONVERT'))
            elif button == self.inFusion:
                self.outUnits.hide()
                self.outMetric.hide()
                self.outImperial.hide()
                self.inButton.setEnabled(True)
                self.inFile.setEnabled(True)
                self.convert_state = self.CONVERT_STATE_COVNERT
                self.convert.setText(_translate('MaterialConverter', 'CONVERT'))

    def on_convert_clicked(self):
        # pylint: disable=attribute-defined-outside-init,too-many-branches,too-many-statements
        # pylint: disable=consider-using-f-string
        self.msgLabel.setText('')
        if self.convert_state != self.CONVERT_STATE_ADD:
            if not self.inManual.isChecked():
                if not self.inFileName:
                    self.msgLabel.setText(_translate('MaterialConverter', 'missing input filename'))
                    return
                if not os.path.exists(self.inFileName):
                    self.msgLabel.setText(_translate('MaterialConverter', '{} missing').format(self.inFileName))
                    return
            if not self.outFileName:
                self.msgLabel.setText(_translate('MaterialConverter', 'missing output filename'))
                return
            self.msgLabel.setText(_translate('MaterialConverter', 'converting...'))
#            try:
            with open(self.outFileName, 'w', encoding='utf-8') as f_out:
                f_out.write('#plasmac material file\n'\
                            '# example only, may be deleted\n'\
                            '# items marked * are mandatory\n'\
                            '# other items are optional and will default to 0\n'\
                            '#[MATERIAL_NUMBER_1]  \n'\
                            '#NAME               = \n'\
                            '#KERF_WIDTH         = \n'\
                            '#PIERCE_HEIGHT      = *\n'\
                            '#PIERCE_DELAY       = *\n'\
                            '#PUDDLE_JUMP_HEIGHT = \n'\
                            '#PUDDLE_JUMP_DELAY  = \n'\
                            '#CUT_HEIGHT         = *\n'\
                            '#CUT_SPEED          = *\n'\
                            '#CUT_AMPS           = \n'\
                            '#CUT_VOLTS          = \n'\
                            '#PAUSE_AT_END       = \n'
                            '#GAS_PRESSURE       = \n'\
                            '#CUT_MODE           = \n'\
                            '#PREHEAT            = \n'\
                            '\n')
#            except:
#                self.msgLabel.setText('WRITE ERROR!!!')
        else:
            self.fNUM = str(int(self.fNUM) + 1)
        if self.inManual.isChecked():
            getParams = self.fusion_dialog()
            if not getParams:
                self.msgLabel.setText('')
                return

            self.materialNum        = f'[MATERIAL_NUMBER_{self.fNUM}]'
            self.materialName       = f'NAME               = {self.fNAM}'
            self.materialKerf       = "{id:}{val:.{i}f}".format(id='KERF_WIDTH         = ',
                                        i=self.precision, val=float(self.fKW) / self.divisor)
            self.materialPierceH    = "{id:}{val:.{i}f}".format(id='PIERCE_HEIGHT      = ',
                                        i=self.precision, val=float(self.fPH) / self.divisor)
            self.materialPierceD    = f'PIERCE_DELAY       = {self.fPD}'
            self.materialPuddleH    = "{id:}{val:.{i}f}".format(id='PUDDLE_JUMP_HEIGHT = ',
                                        i=self.precision, val=float(self.fPJH) / self.divisor)
            self.materialPuddleD    = 'PUDDLE_JUMP_DELAY  = {}'.format(self.fPJD)
            self.materialCutH       = "{id:}{val:.{i}f}".format(id='CUT_HEIGHT         = ',
                                        i=self.precision, val=float(self.fCH) / self.divisor)
            self.materialCutS       = "{id:}{val:.{i}f}".format(id='CUT_SPEED          = ',
                                        i=0, val=float(self.fCS) / self.divisor)
            self.materialCutA       = f'CUT_AMPS           = {self.fCA}'
            self.materialCutV       = f'CUT_VOLTS          = {self.fCV}'
            self.materialPauseE     = f'PAUSE_AT_END       = {self.fPE}'
            self.materialGasP       = f'GAS_PRESSURE       = {self.fGP}'
            self.materialCutM       = f'CUT_MODE           = {self.fCM}'
            self.materialPreheat    = f'PREHEAT            = {self.fPHT}'
            self.output()
            self.convert_state = self.CONVERT_STATE_ADD
            self.convert.setText(_translate('MaterialConverter', 'ADD'))
        elif self.inSheetcam.isChecked():
#            try:
            with open(self.inFileName, 'r', encoding='utf-8') as f_in:
                # pylint: disable=anomalous-backslash-in-string,unused-variable
                count = 0
                valid = False
                for line in f_in:
                    if line.startswith('[Tool') and not 'Custom' in line:
                        if count and valid:
                            self.output()
                        valid = False
                        self.materialNum        = ''
                        self.materialName       = 'NAME               = '
                        self.materialKerf       = 'KERF_WIDTH         = '
                        self.materialPierceH    = 'PIERCE_HEIGHT      = '
                        self.materialPierceD    = 'PIERCE_DELAY       = '
                        self.materialPuddleH    = 'PUDDLE_JUMP_HEIGHT = 0'
                        self.materialPuddleD    = 'PUDDLE_JUMP_DELAY  = 0'
                        self.materialCutH       = 'CUT_HEIGHT         = '
                        self.materialCutS       = 'CUT_SPEED          = '
                        self.materialCutA       = 'CUT_AMPS           = 0'
                        self.materialCutV       = 'CUT_VOLTS          = 0'
                        self.materialPauseE     = 'PAUSE_AT_END       = 0'
                        self.materialGasP       = 'GAS_PRESSURE       = 0'
                        self.materialCutM       = 'CUT_MODE           = 1'
                        self.materialPreheat    = 'PREHEAT            = 0'
                    elif 'PlasmaTool' in line:
                        valid = True
                    elif 'FlameTool' in line:
                        valid = True
                    elif line.startswith('Tool\ number'):
                        a,b = line.split('=')
                        b = b.strip().replace(']','')
                        self.materialNum        = f'[MATERIAL_NUMBER_{b}]'
                    elif line.startswith('Name='):
                        a,b = line.split('=',1)
                        self.materialName       = f'NAME               = {b.strip()}'
                    elif line.startswith('Kerf\ width'):
                        a,b = line.split('=',1)
                        val = float(b.strip()) / self.divisor
                        self.materialKerf       = f"KERF_WIDTH         = {val:.{self.precision}f}"
                    elif line.startswith('Pierce\ height'):
                        a,b = line.split('=',1)
                        val = float(b.strip()) / self.divisor
                        self.materialPierceH    = f"PIERCE_HEIGHT      = {val:.{self.precision}f}"
                    elif line.startswith('Pierce\ delay'):
                        a,b = line.split('=',1)
                        self.materialPierceD    = f'PIERCE_DELAY       = {b.strip()}'
                    elif line.startswith('Высота\ прыжка'):
                        a,b = line.split('=',1)
                        self.materialPuddleH    = f'PUDDLE_JUMP_HEIGHT = {b.strip()}'
                    elif line.startswith('Задержка\ на'):
                        a,b = f_in.readline().split('=',1)
                        self.materialPuddleD    = f'PUDDLE_JUMP_DELAY  = {b.strip()}'
                    elif line.startswith('Cut\ height'):
                        a,b = line.split('=',1)
                        val = float(b.strip()) / self.divisor
                        self.materialCutH       = f"CUT_HEIGHT         = {val:.{self.precision}f}"
                    elif line.startswith('Feed\ rate'):
                        a,b = line.split('=',1)
                        val = float(b.strip()) / self.divisor
                        self.materialCutS       = f"CUT_SPEED          = {val:.0f}"
                    elif line.startswith('Cut\ current') or line.startswith('Ток\ резки') or (line.startswith('Preset\ current')
                                    and self.materialCutA == 'CUT_AMPS           = 0'):
                        a,b = line.split('=',1)
                        self.materialCutA       = f'CUT_AMPS           = {b.strip()}'
                    elif line.startswith('Cut\ voltage') or line.startswith('Напряжение\ резки') or (line.startswith('Preset\ volts')
                                    and self.materialCutV == 'CUT_VOLTS          = 0'):
                        a,b = line.split('=',1)
                        self.materialCutV       = f'CUT_VOLTS          = {b.strip()}'
                    elif line.startswith('Pause\ at\ end\ of\ cut'):
                        a,b = line.split('=',1)
                        self.materialPauseE     = f'PAUSE_AT_END       = {b.strip()}'
                    elif (line.startswith('Gas\ pressure')
                                    or (line.startswith('Preset\ Air\ Pressure')
                                    and self.materialGasP == 'GAS_PRESSURE       = 0')):
                        a,b = line.split('=',1)
                        self.materialGasp       = f'GAS_PRESSURE       = {b.strip()}'
                    elif line.startswith('Cut\ mode') or (line.startswith('Preset\ mode')
                                    and self.materialCutM == 'CUT_MODE           = 1'):
                        a,b = line.split('=',1)
                        self.materialCutM       = f'CUT_MODE           = {b.strip()}'
                    elif line.startswith('Preheat'):
                        a,b = line.split('=',1)
                        self.materialPreheat    = f'PREHEAT            = {b.strip()}'
                    count += 1
                if valid:
                    self.output()
#            except:
#                self.msgLabel.setText('READ ERROR!!!')
            self.msgLabel.setText(_translate('MaterialConverter', 'FINISHED'))
        elif self.inFusion.isChecked():
            #            try:
            with open(self.inFileName, 'r', encoding='utf-8') as f_in:
                jdata = json.load(f_in)
                f_in.close()
            for t in jdata['data']:
                self.fNUM = str(t['post-process']['number'])
                self.fNAM = t['description']
                lCS = self.find_key(t, 'v_f')
                lKW = t['geometry']['CW']
                getParams = self.fusion_dialog()
                if not getParams:
                    self.msgLabel.setText('')
                    return
                self.materialNum        = '[MATERIAL_NUMBER_{}]'.format(self.fNUM)
                self.materialName       = 'NAME               = {}'.format(self.fNAM)
                self.materialKerf       = "{id:}{val:.{i}f}".format(id='KERF_WIDTH         = ',
                                          i=self.precision, val=float(lKW) / self.divisor)
                self.materialPierceH    = "{id:}{val:.{i}f}".format(id='PIERCE_HEIGHT      = ',
                                          i=self.precision, val=float(self.fPH) / self.divisor)
                self.materialPierceD    = 'PIERCE_DELAY       = {}'.format(self.fPD)
                self.materialPuddleH    = "{id:}{val:.{i}f}".format(id='PUDDLE_JUMP_HEIGHT = ',
                                          i=self.precision, val=float(self.fPJH) / self.divisor)
                self.materialPuddleD    = 'PUDDLE_JUMP_DELAY  = {}'.format(self.fPJD)
                self.materialCutH       = "{id:}{val:.{i}f}".format(id='CUT_HEIGHT         = ',
                                          i=self.precision, val=float(self.fCH) / self.divisor)
                self.materialCutS       = "{id:}{val:.{i}f}".format(id='CUT_SPEED          = ',
                                          i=0, val=float(lCS) / self.divisor)
                self.materialCutA       = 'CUT_AMPS           = {}'.format(self.fCA)
                self.materialCutV       = 'CUT_VOLTS          = {}'.format(self.fCV)
                self.materialPauseE     = 'PAUSE_AT_END       = {}'.format(self.fPE)
                self.materialGasP       = 'GAS_PRESSURE       = {}'.format(self.fGP)
                self.materialCutM       = 'CUT_MODE           = {}'.format(self.fCM)
                self.materialPreheat    = 'PREHEAT            = {}'.format(self.fPHT)
                self.output()
#            except:
#                self.msgLabel.setText('READ ERROR!!!')
            self.msgLabel.setText('FINISHED')
        else:
            self.msgLabel.setText('Invalid Conversion')

    def find_key(self, obj, key):
        if key in obj:
            return obj[key]

        for k, v in obj.items():
            _ = k  # unused
            if isinstance(v,dict):
                item = self.find_key(v, key)
                if item is not None:
                    return item
            elif isinstance(v,list):
                for list_item in v:
                    item = self.find_key(list_item, key)
                    if item is not None:
                        return item
        return None

    def on_cancel_clicked(self):
        sys.exit()

    def output(self):
#        try:
        with open(self.outFileName, 'a', encoding='utf-8') as f_out:
            f_out.write(self.materialNum + '\n' + \
                        self.materialName + '\n' + \
                        self.materialKerf + '\n' + \
                        self.materialPierceH + '\n' + \
                        self.materialPierceD + '\n' + \
                        self.materialPuddleH + '\n' + \
                        self.materialPuddleD + '\n' + \
                        self.materialCutH + '\n' + \
                        self.materialCutS + '\n' + \
                        self.materialCutA + '\n' + \
                        self.materialCutV + '\n' + \
                        self.materialPauseE + '\n' +\
                        self.materialGasP + '\n' + \
                        self.materialCutM + '\n' + \
                        self.materialPreheat + '\n' + \
                        '\n')
#        except:
#            self.msgLabel.setText('WRITE ERROR!!!')

    def fusion_dialog(self):
        # pylint: disable=too-many-locals,too-many-statements
        dialog = QDialog()
        dialog.setWindowTitle('Material Maker')
        dialog.setWindowIcon(QIcon(os.path.join(self.iconBase, self.iconPath)))
        dialog.setModal(True)
        topL = QLabel('Items with a *** are mandatory')
        infL = QLabel(f'For Material # {self.fNUM}\n{self.fNAM}')
        dNUl = QLabel('Material Number ***')
        dNUl.setAlignment(Qt.AlignBottom|Qt.AlignRight)
        dNU = QLineEdit()
        dNU.setText(self.fNUM)
        dNU.setAlignment(Qt.AlignRight)
        dNAl = QLabel('Material Name')
        dNAl.setAlignment(Qt.AlignBottom|Qt.AlignRight)
        dNA = QLineEdit()
        dNA.setText(self.fNAM)
        dNA.setAlignment(Qt.AlignRight)
        dKWl = QLabel('Kerf Width')
        dKWl.setAlignment(Qt.AlignBottom|Qt.AlignRight)
        dKW = QLineEdit()
        dKW.setText(self.fKW)
        dKW.setAlignment(Qt.AlignRight)
        dPHl = QLabel('Pierce Height ***')
        dPHl.setAlignment(Qt.AlignBottom|Qt.AlignRight)
        dPH = QLineEdit()
        dPH.setText(self.fPH)
        dPH.setAlignment(Qt.AlignRight)
        dPDl = QLabel('Pierce Delay ***')
        dPDl.setAlignment(Qt.AlignBottom|Qt.AlignRight)
        dPD = QLineEdit()
        dPD.setText(self.fPD)
        dPD.setAlignment(Qt.AlignRight)
        dPJHl = QLabel('Puddle Jump Height')
        dPJHl.setAlignment(Qt.AlignBottom|Qt.AlignRight)
        dPJH = QLineEdit()
        dPJH.setText(self.fPJH)
        dPJH.setAlignment(Qt.AlignRight)
        dPJDl = QLabel('Puddle Jump Delay')
        dPJDl.setAlignment(Qt.AlignBottom|Qt.AlignRight)
        dPJD = QLineEdit()
        dPJD.setText(self.fPJD)
        dPJD.setAlignment(Qt.AlignRight)
        dCHl = QLabel('Cut Height ***')
        dCHl.setAlignment(Qt.AlignBottom|Qt.AlignRight)
        dCH = QLineEdit()
        dCH.setText(self.fCH)
        dCH.setAlignment(Qt.AlignRight)
        dCSl = QLabel('Cut Speed ***')
        dCSl.setAlignment(Qt.AlignBottom|Qt.AlignRight)
        dCS = QLineEdit()
        dCS.setText(self.fCS)
        dCS.setAlignment(Qt.AlignRight)
        dCAl = QLabel('Cut Amps')
        dCAl.setAlignment(Qt.AlignBottom|Qt.AlignRight)
        dCA = QLineEdit()
        dCA.setText(self.fCA)
        dCA.setAlignment(Qt.AlignRight)
        dCVl = QLabel('Cut Volts')
        dCVl.setAlignment(Qt.AlignBottom|Qt.AlignRight)
        dCV = QLineEdit()
        dCV.setText(self.fCV)
        dCV.setAlignment(Qt.AlignRight)
        dPEl = QLabel('Pause At End Of Cut')
        dPEl.setAlignment(Qt.AlignBottom|Qt.AlignRight)
        dPE = QLineEdit()
        dPE.setText(self.fPE)
        dPE.setAlignment(Qt.AlignRight)
        dGPl = QLabel('Gas Pressure')
        dGPl.setAlignment(Qt.AlignBottom|Qt.AlignRight)
        dGP = QLineEdit()
        dGP.setText(self.fGP)
        dGP.setAlignment(Qt.AlignRight)
        dCMl = QLabel('Cut Mode')
        dCMl.setAlignment(Qt.AlignBottom|Qt.AlignRight)
        dCM = QLineEdit()
        dCM.setText(self.fCM)
        dCM.setAlignment(Qt.AlignRight)
        dPHT = QLineEdit()
        dPHT.setText(self.fPHT)
        dPHT.setAlignment(Qt.AlignRight)
        vSpace1 = QSpacerItem(0, 25)
        buttons = QDialogButtonBox.Ok | QDialogButtonBox.Cancel
        buttonBox = QDialogButtonBox(buttons)
        buttonBox.accepted.connect(dialog.accept)
        buttonBox.rejected.connect(dialog.reject)
        layout = QVBoxLayout()
        dialog.setLayout(layout)
        layout.addWidget(topL)
        if self.inManual.isChecked():
            layout.addWidget(dNUl)
            layout.addWidget(dNU)
            layout.addWidget(dNAl)
            layout.addWidget(dNA)
            layout.addWidget(dKWl)
            layout.addWidget(dKW)
        else:
            layout.addWidget(infL)
        layout.addWidget(dPHl)
        layout.addWidget(dPH)
        layout.addWidget(dPDl)
        layout.addWidget(dPD)
        layout.addWidget(dPJHl)
        layout.addWidget(dPJH)
        layout.addWidget(dPJDl)
        layout.addWidget(dPJD)
        layout.addWidget(dCHl)
        layout.addWidget(dCH)
        if self.inManual.isChecked():
            layout.addWidget(dCSl)
            layout.addWidget(dCS)
        layout.addWidget(dCAl)
        layout.addWidget(dCA)
        layout.addWidget(dCVl)
        layout.addWidget(dCV)
        layout.addWidget(dPEl)
        layout.addWidget(dPE)
        layout.addWidget(dGPl)
        layout.addWidget(dGP)
        layout.addWidget(dCMl)
        layout.addWidget(dCM)
        layout.addWidget(dPHT)
        layout.addItem(vSpace1)
        layout.addWidget(buttonBox, alignment=Qt.AlignCenter)
        dialog.setStyleSheet('* { color: #ffee06; background: #16160e; font: 10pt DejaVuSans } \
                             QLineEdit { border: 1px solid #ffee06; border-radius: 4 } \
                           QPushButton {border: 1px solid #ffee06; border-radius: 4; height: 20; width: 80} \
                           QPushButton:pressed {color: #16160e; background: #ffee06}')
        response = dialog.exec_()
        if self.inManual.isChecked():
            self.fNUM = dNU.text()
            self.fNAM = dNA.text()
            self.fKW = dKW.text()
        self.fPH = dPH.text()
        self.fPD = dPD.text()
        self.fPJH = dPJH.text()
        self.fPJD = dPJD.text()
        self.fCH = dCH.text()
        if self.inManual.isChecked():
            self.fCS = dCS.text()
        self.fCA = dCA.text()
        self.fCV = dCV.text()
        self.fPE = dPE.text()
        self.fGP = dGP.text()
        self.fCM = dCM.text()
        self.fPHT = dPHT.text()
        return response

if __name__ == '__main__':

    # translation path
    LOCALEDIR = None
    lang = QLocale.system().name().split('_')[0]
    #qm_fn = f"languages/{BASENAME}_{lang}.qm"
    qm_fn = LANGPATH + f"/{BASENAME}_{lang}.qm"
    print('---debug: LANGPATH = ', qm_fn)
    localqm = os.path.join(BASEPATH, qm_fn)
    if os.path.exists(localqm):
        LOCALEDIR = localqm

    app = QApplication(sys.argv)

    if LOCALEDIR is not None:
        translator = QTranslator()
        translator.load(LOCALEDIR)
        app.installTranslator(translator)
    w = MaterialConverter()
    w.show()
    sys.exit(app.exec_())
