
'''
qtplasmac-plasmac2qt.py

This file is used to convert settings in the .cfg files from a PlasmaC
configuration to the .prefs file for a QtPlasmaC configuration.

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 time
from shutil import copy as COPY
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *

class Converter(QMainWindow, object):

# INITIALISATION
    def __init__(self, parent=None):
        super(Converter, self).__init__(parent)
        self.appPath = os.path.realpath(os.path.dirname(sys.argv[0]))
        if len(sys.argv) > 1:
            if os.path.isfile(sys.argv[1]):
                self.mode = 'auto'
                self.iniIn = sys.argv[1]
            else:
                print('{} is not a valid file.'.format(sys.argv[1]))
                sys.exit(0)
        else:
            self.mode = ''
            self.iniIn = ''
        if 'usr' in self.appPath:
            self.simPath = '/usr/share/doc/linuxcnc/examples/sample-configs/sim/qtplasmac'
        else:
            self.simPath = self.appPath.replace('bin', 'configs/sim/qtplasmac')
        self.setFixedWidth(600)
        self.setFixedHeight(400)
        wid = QWidget(self)
        qtRectangle = self.frameGeometry()
        centerPoint = QDesktopWidget().availableGeometry().center()
        qtRectangle.moveCenter(centerPoint)
        self.move(qtRectangle.topLeft())
        self.setCentralWidget(wid)
        layout = QHBoxLayout()
        wid.setLayout(layout)
        iconPath = 'share/icons/hicolor/scalable/apps/linuxcnc_alt/linuxcncicon_plasma.svg'
        appPath = os.path.realpath(os.path.dirname(sys.argv[0]))
        iconBase = '/usr' if appPath == '/usr/bin' else appPath.replace('/bin', '/debian/extras/usr')
        self.setWindowIcon(QIcon(os.path.join(iconBase, iconPath)))
        self.setWindowTitle('PlasmaC2Qt')
        vBox = QVBoxLayout()
        if self.mode == 'auto':
            heading  = 'Plasmac is not available in LinuxCNC V2.9 and later\n\n'
        else:
            heading = ''
        heading += 'Convert Existing PlasmaC Configuration To A New QtPlasmaC Configuration\n'
        headerLabel = QLabel(heading)
        headerLabel.setAlignment(Qt.AlignCenter)
        vBox.addWidget(headerLabel)
        vSpace01 = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
        vBox.addItem(vSpace01)
        fromLabel = QLabel('INI FILE IN EXISTING PLASMAC CONFIG:')
        fromLabel.setAlignment(Qt.AlignBottom)
        vBox.addWidget(fromLabel)
        fromFileHBox = QHBoxLayout()
        self.fromFile = QLineEdit()
        self.fromFile.setEnabled(False)
        if self.mode:
            self.fromFile.setText(self.iniIn)
        else:
            fromFileButton = QPushButton('SELECT')
            fromFileHBox.addWidget(fromFileButton)
        fromFileHBox.addWidget(self.fromFile)
        vBox.addLayout(fromFileHBox)
        vSpace02 = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
        vBox.addItem(vSpace02)
        aspectLabel = QLabel('MONITOR ASPECT RATIO:')
        vBox.addWidget(aspectLabel)
        aspectHBox = QHBoxLayout()
        self.aspectGroup = QButtonGroup()
        self.aspect0 = QRadioButton('16:9')
        self.aspect0.setFixedHeight(25)
        self.aspect0.setChecked(True)
        aspectHBox.addWidget(self.aspect0)
        self.aspectGroup.addButton(self.aspect0, 0)
        self.aspect1 = QRadioButton('9:16')
        aspectHBox.addWidget(self.aspect1)
        self.aspectGroup.addButton(self.aspect1, 1)
        self.aspect2 = QRadioButton('4:3')
        aspectHBox.addWidget(self.aspect2)
        self.aspectGroup.addButton(self.aspect2, 2)
        self.aspectGroup.buttonClicked.connect(self.aspect_group_clicked)
        vBox.addLayout(aspectHBox)
        vSpace03 = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
        vBox.addItem(vSpace03)
        self.estopLabel = QLabel('ESTOP IS AN INDICATOR ONLY')
        vBox.addWidget(self.estopLabel)
        estopHBox = QHBoxLayout()
        self.estopGroup = QButtonGroup()
        self.estop0 = QRadioButton('ESTOP: 0')
        self.estop0.setFixedHeight(25)
        self.estop0.setChecked(True)
        estopHBox.addWidget(self.estop0)
        self.estopGroup.addButton(self.estop0, 0)
        self.estop1 = QRadioButton('ESTOP: 1')
        estopHBox.addWidget(self.estop1)
        self.estopGroup.addButton(self.estop1, 1)
        self.estop2 = QRadioButton('ESTOP: 2')
        estopHBox.addWidget(self.estop2)
        self.estopGroup.addButton(self.estop2, 2)
        self.estopGroup.buttonClicked.connect(self.estop_group_clicked)
        vBox.addLayout(estopHBox)
        vSpace3 = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
        vBox.addItem(vSpace3)
        laserOnLabel = QLabel('OPTIONAL:\nLaser On HAL pin: (bit output)')
        vBox.addWidget(laserOnLabel)
        self.laserOnPin = QLineEdit()
        vBox.addWidget(self.laserOnPin)
        vSpace04 = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
        vBox.addItem(vSpace04)
        buttonHBox = QHBoxLayout()
        convert = QPushButton('CONVERT')
        buttonHBox.addWidget(convert)
        cancel = QPushButton('EXIT')
        buttonHBox.addWidget(cancel)
        vBox.addLayout(buttonHBox)
        layout.addLayout(vBox)
        self.setStyleSheet( \
            'QWidget {color: #ffee06; background: #16160e} \
             QLabel {height: 20} \
             QPushButton {border: 1 solid #ffee06; border-radius: 4; height: 24; width: 80; max-width: 90} \
             QFileDialog QPushButton {border: 1 solid #ffee06; border-radius: 4; height: 30; margin: 6} \
             QPushButton:pressed {color: #16160e; background: #ffee06} \
             QLineEdit {border: 1 solid #ffee06; border-radius: 4; height: 24; padding-left: 8} \
             QFileDialog QLineEdit {border: 1 solid #ffee06; border-radius: 4; height: 30} \
             QTableView::item:selected:active {color: #16160e; background-color: #ffee06} \
             QTableView::item:selected:!active {color: #16160e; background-color: #ffee06} \
             QHeaderView::section {color: #ffee06; background-color: #36362e; border: 1 solid #ffee06; border-radius: 4; margin: 2} \
             QComboBox {color: #ffee06; background-color: #16160e; border: 1 solid #ffee06; border-radius: 4; height: 30} \
             QComboBox::drop-down {width: 0} \
             QComboBox QListView {border: 4p solid #ffee06; border-radius: 0} \
             QComboBox QAbstractItemView {border: 2px solid #ffee06; border-radius: 4} \
             QScrollBar:horizontal {background: #36362e; border: 0; border-radius: 4; margin: 0; height: 20} \
             QScrollBar::handle:horizontal {background: #ffee06; border: 2 solid #ffee06; border-radius: 4; margin: 2; width: 40} \
             QScrollBar::add-line:horizontal {width: 0} \
             QScrollBar::sub-line:horizontal {width: 0} \
             QScrollBar:vertical {background: #36362e; border: 0; border-radius: 4; margin: 0; width: 20} \
             QScrollBar::handle:vertical {background: #ffee06; border: 2 solid #ffee06; border-radius: 4; margin: 2; height: 40} \
             QScrollBar::add-line:vertical {height: 0} \
             QScrollBar::sub-line:vertical {height: 0} \
             QRadioButton::indicator {border: 1px solid #ffee06; border-radius: 4; height: 20; width: 20} \
             QRadioButton::indicator:checked {background: #ffee06} \
            ')
        convert.pressed.connect(self.convert_pressed)
        cancel.pressed.connect(self.close_app)
        if not self.mode:
            fromFileButton.pressed.connect(self.from_pressed)
        if os.path.exists('{}/linuxcnc/configs'.format(os.path.expanduser('~'))):
            self.DIR = '{}/linuxcnc/configs'.format(os.path.expanduser('~'))
        elif os.path.exists('{}/linuxcnc'.format(os.path.expanduser('~'))):
            self.DIR = '{}/linuxcnc'.format(os.path.expanduser('~'))
        else:
            self.DIR = '{}'.format(os.path.expanduser('~'))
        self.display = 'DISPLAY                 = qtvcp qtplasmac\n'
        self.estop = 'Estop type = 0'

# POPUP INFO DIALOG
    def dialog_ok(self, title, text):
        msgBox = QMessageBox()
        msgBox.setIcon(QMessageBox.Information)
        msgBox.setWindowTitle('{}'.format(title))
        msgBox.setText('{}'.format(text))
        msgBox.setStandardButtons(QMessageBox.Ok)
        buttonK = msgBox.button(QMessageBox.Ok)
        buttonK.setIcon(QIcon())
        buttonK.setText('OK')
        msgBox.setStyleSheet('QWidget {color: #ffee06; background: #16160e; font: 12pt DejaVuSans} \
                              QPushButton {border: 1px solid #ffee06; border-radius: 4; height: 20} \
                             ')
        msgBox.setBaseSize(QSize(800, 800))
        ret = msgBox.exec_()
        return ret

# SELECT PLASMAC INI FILE
    def from_pressed(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        name, _ = QFileDialog.getOpenFileName(
                    parent=self,
                    caption=self.tr("Select an INI file"),
                    filter=self.tr('INI files (*.ini);;INI files (*.[iI][nN][iI])'),
                    directory=self.DIR,
                    options=options
                    )
        if name and os.path.isfile(name):
            self.fromFile.setText(name)
        else:
            self.fromFile.setText('')
        self.iniIn = self.fromFile.text()

# ASPECT CHANGED
    def aspect_group_clicked(self, button):
        if self.aspectGroup.id(button) == 0:
            self.display = 'DISPLAY                 = qtvcp qtplasmac\n'
        elif self.aspectGroup.id(button) == 1:
            self.display = 'DISPLAY                 = qtvcp qtplasmac_9x16\n'
        elif self.aspectGroup.id(button) == 2:
            self.display = 'DISPLAY                 = qtvcp qtplasmac_4x3\n'

# ESTOP CHANGED
    def estop_group_clicked(self, button):
        if self.estopGroup.id(button) == 0:
            self.estopLabel.setText('ESTOP IS AN INDICATOR ONLY')
            self.estop = 'Estop type = 0'
        elif self.estopGroup.id(button) == 1:
            self.estopLabel.setText('ESTOP IS HIDDEN')
            self.estop = 'Estop type = 1'
        elif self.estopGroup.id(button) == 2:
            self.estopLabel.setText('ESTOP IS A BUTTON')
            self.estop = 'Estop type = 2'

# CLOSE PROGRAM
    def close_app(self):
        sys.exit(2)

# CONVERT
    def convert_pressed(self):
    # CHECK IF INI FILE NAME EXISTS
        if not self.iniIn:
            return
    # CHECK IF FULL PATH EXISTS
        if not os.path.dirname(self.iniIn):
            msg  = 'Missing path to a PlasmaC configuration\n'
            self.dialog_ok('Path Error', msg)
            self.fromFile.setFocus()
            return
    # CHECK IF VALID PLASMAC CONFIG
        if not os.path.exists('{}/plasmac'.format(os.path.dirname(self.iniIn))):
            msg  = '{}\n'.format(self.iniIn)
            msg += '\n is not a PlasmaC configuration\n'
            self.dialog_ok('Config Error', msg)
            self.fromFile.setFocus()
            return
    # CHECK IF SIM CONFIG
        simConfig = False
        with open(self.iniIn, 'r') as inFile:
            for line in inFile:
                if 'plasmac_test.py' in line and not line.startswith('#'):
                    simConfig = True
                    break
    # SET FILENAMES AND PATHS
        fName = os.path.basename(self.iniIn)
        newDir = os.path.dirname(self.iniIn)
        i = 1
        while True:
            oldDir = '{}.bkp{}'.format(os.path.dirname(self.iniIn), i)
            if not os.path.exists(oldDir):
                break
            i += 1
        newIniFile = os.path.join(newDir, fName)
        oldIniFile = os.path.join(oldDir, fName)
    # CREATE NEW DIRECTORY AND BACKUPS DIRECTORY
        try:
            os.rename(newDir, oldDir)
            os.makedirs('{}/backups'.format(newDir))
        except:
            msg  = 'Could not create directory\n'.format(newDir)
            self.dialog_ok('Directory Error', msg)
            return
    # GET THE MACHINE NAME
        with open(oldIniFile) as inFile:
            while(1):
                line = inFile.readline()
                if not line:
                    print('cannot find [EMC] section in INI file')
                    return
                if line.startswith('[EMC]'):
                    break
            while(1):
                line = inFile.readline()
                if not line:
                    print('cannot find MACHINE variable in INI file')
                    return
                if line.startswith('MACHINE'):
                    machineName = line.split('=')[1].strip().lower()
                    break
    # COPY ORIGINAL BASE MACHINE FILES IF EXISTING
        try:
            for filename in os.listdir('{}/backups'.format(oldDir)):
                if filename.startswith('_original'):
                    COPY('{}/backups/{}'.format(oldDir, filename), '{}/backups/{}'.format(newDir, filename))
        except:
            pass
    # COPY HAL FILES
        halFiles = []
        oldPostguiFile = None
        newPostguiFile = None
        newConnectionsFile = None
        with open(oldIniFile, 'r') as inFile:
            while(1):
                line = inFile.readline()
                if line.startswith('[HAL]'):
                    break
                if not line:
                    msg  = 'Could not get [HAL] section of INI file\n'
                    msg += '\nConversion cannot continue'
                    self.dialog_ok('INI File Error', msg)
                    self.fromFile.setFocus()
                    return
            while(1):
                line = inFile.readline()
                if line.startswith('POSTGUI_HALFILE'):
                    oldPostguiFile = line.split('=')[1].strip()
                    newPostguiFile = 'custom_postgui.hal'
                    halFiles.append(oldPostguiFile)
                    COPY('{}/{}'.format(oldDir, oldPostguiFile), '{}/{}'.format(newDir, newPostguiFile))
                elif 'connections.hal' in line:
                    oldConnectionsFile = line.split('=')[1].strip()
                    newConnectionsFile = 'custom.hal'
                    halFiles.append(newConnectionsFile)
                    COPY('{}/{}'.format(oldDir, oldConnectionsFile), '{}/{}'.format(newDir, newConnectionsFile))
                    with open('{}/{}'.format(newDir, newConnectionsFile), 'w') as outConFile:
                        with open('{}/{}'.format(oldDir, oldConnectionsFile), 'r') as inConFile:
                            for line in inConFile:
                                if 'plasmac:torch-on' in line:
                                    outConFile.write(line)
                                    outConFile.write('\n#***** LASER ALIGNMENT CONNECTION *****\n')
                                    if self.laserOnPin.text():
                                        outConFile.write('net plasmac:laser-on => {}\n'.format(self.laserOnPin.text()))
                                    else:
                                        outConFile.write('# net plasmac:laser-on => {YOUR_LASER_ON_OUTPUT}\n\n')
                                else:
                                    outConFile.write(line)
                elif line.startswith('HALFILE'):
                    if 'plasmac.tcl' in line:
                        halFiles.append('plasmac.tcl')
                    else:
                        hFile = line.split('=')[1].strip()
                        with open('{}/{}'.format(oldDir, hFile), 'r') as inHal:
                            if simConfig and 'motor-pos-cmd' in inHal.read():
                                halFiles.append('machine.tcl')
                                COPY('{}/machine.tcl'.format(self.simPath), '{}/machine.tcl'.format(newDir))
                            else:
                                halFiles.append(hFile)
                                COPY('{}/{}'.format(oldDir, hFile), '{}/{}'.format(newDir, hFile))
                if not line or line.startswith('['):
                    break
    # COPY TOOL TABLE
        if os.path.exists('{}/tool.tbl'.format(oldDir)):
            COPY('{}/tool.tbl'.format(oldDir), '{}/tool.tbl'.format(newDir))
    # MAKE NEW PREFERENCES FILE
        self.prefParms = []
        self.read_ini_file(oldIniFile)
        if os.path.isfile(os.path.join(oldDir, machineName + '_config.cfg')):
            self.read_con_file(os.path.join(oldDir, machineName + '_config.cfg'))
        else:
            print('file not found, config parameters can not be converted.')
        if os.path.isfile(os.path.join(oldDir, machineName + '_run.cfg')):
            self.read_run_file(os.path.join(oldDir, machineName + '_run.cfg'))
        else:
            print('file not found, run parameters can not be converted.')
        if os.path.isfile(os.path.join(oldDir, machineName + '_wizards.cfg')):
            self.read_wiz_file(os.path.join(oldDir, machineName + '_wizards.cfg'))
        else:
            print('file not found, wizard parameters can not be converted.')
        if os.path.isfile(os.path.join(oldDir, 'plasmac_stats.var')):
            self.read_sta_file(os.path.join(oldDir, 'plasmac_stats.var'))
        else:
            print('file not found, statistics can not be converted.')
        if os.path.isfile(os.path.join(oldDir, machineName + '_material.cfg')):
            self.read_mat_file(os.path.join(oldDir, machineName + '_material.cfg'), newDir, machineName)
        else:
            print('file not found, materials can not be converted.')
        self.write_prefs_files(newDir, machineName)
    # MAKE NEW INI FILE
        section = ''
        with open(newIniFile, 'w') as outFile:
            with open(oldIniFile, 'r') as inFile:
                for line in inFile:
                # SET SECTION NAMES
                    if line.startswith('['):
                        section = ''
                    if line.startswith('[APPLICATIONS]'):
                        section = 'APPLICATIONS'
                    if line.startswith('[PLASMAC]'):
                        section = 'PLASMAC'
                    if line.startswith('[FILTER]'):
                        section = 'FILTER'
                    if line.startswith('[RS274NGC]'):
                        section = 'RS274NGC'
                    if line.startswith('[HAL]'):
                        section = 'HAL'
                    if line.startswith('[DISPLAY]'):
                        section = 'DISPLAY'
                    if line.startswith('[EMC]'):
                        section = 'EMC'
                # CONVERT SECTION PARAMETERS
                    if section == 'APPLICATIONS':
                        continue
                    if section == 'PLASMAC':
                        continue
                    elif section == 'FILTER':
                        if line.startswith('[FILTER]'):
                            outFile.write('\n{}'.format(line))
                            outFile.write('PROGRAM_EXTENSION       = .ngc,.nc,.tap GCode File (*.ngc, *.nc, *.tap)\n')
                            outFile.write('ngc                     = qtplasmac_gcode\n')
                            outFile.write('nc                      = qtplasmac_gcode\n')
                            outFile.write('tap                     = qtplasmac_gcode\n')
                        continue
                    elif section == 'RS274NGC':
                        if line.startswith('SUBROUTINE') or line.startswith('USER_M_PATH'):
                            if ':./plasmac' in line:
                                line = line.replace(':./plasmac', '')
                            if line.strip().endswith('./') or './:' in line:
                                pass
                            else:
                                line = './:{}'.format(line)
                        if line.startswith('RS274NGC_STARTUP_CODE') and ('metric' in line or 'imperial' in line):
                            units = 21 if 'metric' in line else 20
                            line = 'RS274NGC_STARTUP_CODE   = G{} G40 G49 G80 G90 G92.1 G94 G97 M52P1\n'.format(units)
                        if line.startswith('#') or line.replace(' ', '').strip() == 'FEATURES=12':
                            continue
                        if line.startswith('['):
                            outFile.write('\n')
                        if line.strip():
                            outFile.write(line)
                        continue
                    elif section == 'HAL':
                        if line.startswith('[HAL]'):
                            outFile.write('\n{}'.format(line))
                            outFile.write('TWOPASS                 = ON\n')
                            outFile.write('HALUI                   = halui\n')
                            for file in halFiles:
                                if '_connections' in file:
                                    outFile.write('HALFILE                 = custom.hal\n')
                                elif 'postgui' in file:
                                    outFile.write('POSTGUI_HALFILE         = custom_postgui.hal\n')
                                else:
                                    outFile.write('HALFILE                 = {}\n'.format(file))
                            if simConfig:
                                outFile.write('POSTGUI_HALFILE         = sim_postgui.tcl\n')
                        continue
                    elif section == 'DISPLAY':
                        if line.startswith('DISPLAY'):
                            line = self.display
                        omissions = ['OPEN_F','EDITOR','TOOL_E','USER_C','EMBED_','GLADEV','CONE_B']
                        if line.startswith('#'):
                            continue
                        if line[:6] in omissions:
                            continue
                        if line.startswith('['):
                            outFile.write('\n')
                        if line.strip():
                            outFile.write(line)
                        continue
                    elif section == 'EMC':
                        if 'enable the axis_tweaks' in line:
                            continue
                        if line.startswith('['):
                            outFile.write('\n')
                        if line.strip():
                            outFile.write(line)
                        continue
                # NO CONVERSION REQUIRED
                    else:
                        if line.strip():
                            if line.startswith('['):
                                outFile.write('\n')
                            if 'marry this config' in line or 'sim testing panel' in line:
                                continue
                            outFile.write(line)
    # ADD A SIM POSTGUI IF A SIM CONFIG
        if simConfig:
            with open('{}/{}'.format(newDir, 'sim_postgui.tcl'), 'a') as outFile:
                outFile.write(self.sim_postgui())
    # WE GOT THIS FAR SO IT MAY HAVE WORKED
        msg  = 'Conversion appears successful.\n'
        if self.mode == 'automatic':
            msg += '\nRestart LinuxCNC using the following INI file:\n'
        else:
            msg += '\nStart LinuxCNC using the following INI file:\n'
        msg += '\n{}/{}.ini\n'.format(newDir, machineName)
        self.dialog_ok('Success', msg)
        print(msg)
        sys.exit(0)

# READ THE ORIGINAL INI FILE TO GET PLASMAC OPTIONS
    def read_ini_file(self, oldIniFile):
        self.buttons = {}
        for n in range(1, 21):
            self.buttons[n] = ['', '']
        bNum = 1
        n, name, c, code = None, None, None, None
        with open(oldIniFile, 'r') as inFile:
            while(1):
                line = inFile.readline()
                if not line or line.startswith('[PLASMAC]'):
                    break
            while(1):
                line = inFile.readline()
                if not line or line.startswith('['):
                    break
                if line.strip():
                    if line.startswith('MODE'):
                        self.prefParms.append('[GUI_OPTIONS]')
                        value = line.split('=')[1].strip()
                        self.prefParms.append('Mode = {}'.format(value))
                        self.prefParms.append('{}\n'.format(self.estop))
                    if line.startswith('BUTTON_'):
                        if '_NAME' in line:
                            n = line.split('_')[1].split('_')[0]
                            name = line.split('=')[1].strip()
                        if '_CODE' in line:
                            if 'cut-recovery' in line:
                                n, name, c, code = None, None, None, None
                            else:
                                c = line.split('_')[1].split('_')[0]
                                code = line.split('=')[1].strip()
                        if n == c and n and c:
                            if name and code:
                                self.buttons[bNum] = [name, code]
                            n, name, c, code = None, None, None, None
                            bNum += 1
        if self.buttons:
            self.prefParms.append('[BUTTONS]')
            for n in range(1, 21):
                self.prefParms.append('{} Name = {}'.format(n, self.buttons[n][0]))
                self.prefParms.append('{} Code = {}'.format(n, self.buttons[n][1]))
        self.prefParms.append('')

# READ THE ORIGINAL <MACHINE_NAME>_CONFIG.CFG FILE
    def read_con_file(self, conFile):
        self.prefParms.append('[PLASMA_PARAMETERS]')
        with open(conFile) as inFile:
            for line in inFile:
                if line.startswith('setup-feed-rate'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Setup Feed Rate = {}'.format(value))
                elif line.startswith('arc-fail-delay'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Arc Fail Timeout = {}'.format(value))
                elif line.startswith('arc-ok-high'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Arc OK High = {}'.format(value))
                elif line.startswith('arc-ok-low'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Arc OK Low = {}'.format(value))
                elif line.startswith('arc-max-starts'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Arc Maximum Starts = {}'.format(value))
                elif line.startswith('arc-voltage-offset'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Arc Voltage Offset = {}'.format(value))
                elif line.startswith('arc-voltage-scale'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Arc Voltage Scale = {}'.format(value))
                elif line.startswith('cornerlock-threshold'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Velocity Anti Dive Threshold = {}'.format(value))
                elif line.startswith('float-switch-travel'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Float Switch Travel = {}'.format(value))
                elif line.startswith('height-per-volt'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Height Per Volt = {}'.format(value))
                elif line.startswith('kerfcross-override'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Void Sense Override = {}'.format(value))
                elif line.startswith('ohmic-max-attempts'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Ohmic Maximum Attempts = {}'.format(value))
                elif line.startswith('ohmic-probe-offset'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Ohmic Probe Offset = {}'.format(value))
                elif line.startswith('pid-p-gain'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Pid P Gain = {}'.format(value))
                elif line.startswith('pid-d-gain'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Pid D Gain = {}'.format(value))
                elif line.startswith('pid-i-gain'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Pid I Gain = {}'.format(value))
                elif line.startswith('probe-feed-rate'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Probe Feed Rate = {}'.format(value))
                elif line.startswith('probe-start-height'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Probe Start Height = {}'.format(value))
                elif line.startswith('arc-restart-delay'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Arc Restart Delay = {}'.format(value))
                elif line.startswith('safe-height'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Safe Height = {}'.format(value))
                elif line.startswith('scribe-arm-delay'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Scribe Arming Delay = {}'.format(value))
                elif line.startswith('scribe-on-delay'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Scribe On Delay = {}'.format(value))
                elif line.startswith('skip-ihs-distance'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Skip IHS Distance = {}'.format(value))
                elif line.startswith('spotting-threshold'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Spotting Threshold = {}'.format(value))
                elif line.startswith('spotting-time'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Spotting Time = {}'.format(value))
                elif line.startswith('thc-delay'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('THC Delay = {}'.format(value))
                elif line.startswith('thc-threshold'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('THC Threshold = {}'.format(value))
            self.prefParms.append('')

# READ THE ORIGINAL <MACHINE_NAME>_RUN.CFG FILE
    def read_run_file(self, runFile):
        self.prefParms.append('[ENABLE_OPTIONS]')
        with open(runFile) as inFile:
            for line in inFile:
                if line.startswith('thc-enable'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('THC enable = {}'.format(value))
                elif line.startswith('cornerlock-enable'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Corner lock enable = {}'.format(value))
                elif line.startswith('kerfcross-enable'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Kerf cross enable = {}'.format(value))
                elif line.startswith('use-auto-volts'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Use auto volts = {}'.format(value))
                elif line.startswith('ohmic-probe-enable'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Ohmic probe enable = {}'.format(value))
            self.prefParms.append('')
        self.prefParms.append('[DEFAULT MATERIAL]')
        with open(runFile) as inFile:
            for line in inFile:
                if line.startswith('kerf-width'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Kerf width = {}'.format(value))
                elif line.startswith('pierce-height'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Pierce height = {}'.format(value))
                elif line.startswith('pierce-delay'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Pierce delay = {}'.format(value))
                elif line.startswith('puddle-jump-height'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Puddle jump height = {}'.format(value))
                elif line.startswith('puddle-jump-delay'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Puddle jump delay = {}'.format(value))
                elif line.startswith('cut-height'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Cut height = {}'.format(value))
                elif line.startswith('cut-feed-rate'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Cut feed rate = {}'.format(value))
                elif line.startswith('cut-amps'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Cut amps = {}'.format(value))
                elif line.startswith('cut-volts'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Cut volts = {}'.format(value))
                elif line.startswith('pause-at-end'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Pause at end = {}'.format(value))
                elif line.startswith('gas-pressure'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Gas pressure = {}'.format(value))
                elif line.startswith('cut-mode'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Cut mode = {}'.format(value))
            self.prefParms.append('')
        self.prefParms.append('[SINGLE CUT]')
        with open(runFile) as inFile:
            for line in inFile:
                if line.startswith('x-single-cut'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('X length = {}'.format(value))
                elif line.startswith('y-single-cut'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Y length = {}'.format(value))
            self.prefParms.append('')

# READ THE ORIGINAL <MACHINE_NAME>_WIZARDS.CFG FILE
    def read_wiz_file(self, wizFile):
        self.prefParms.append('[CONVERSATIONAL]')
        with open(wizFile) as inFile:
            for line in inFile:
                if line.startswith('preamble'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Preamble = {}'.format(value))
                elif line.startswith('origin'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Origin = {}'.format(value))
                elif line.startswith('lead-in'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Leadin = {}'.format(value))
                elif line.startswith('lead-out'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Leadout = {}'.format(value))
                elif line.startswith('hole-diameter'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Hole diameter = {}'.format(value))
                elif line.startswith('hole-speed'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Hole speed = {}'.format(value))
                elif line.startswith('grid-size'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Grid Size = {}'.format(value))
            self.prefParms.append('')

# READ THE ORIGINAL PLASMAC_STATS.VAR FILE
    def read_sta_file(self, staFile):
        self.prefParms.append('[STATISTICS]')
        with open(staFile) as inFile:
            for line in inFile:
                if line.strip().startswith('PIERCE_COUNT'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Pierce count = {}'.format(value))
                elif line.strip().startswith('CUT_LENGTH'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Cut length = {}'.format(value))
                elif line.strip().startswith('CUT_TIME'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Cut time = {}'.format(value))
                elif line.strip().startswith('TORCH_TIME'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Torch on time = {}'.format(value))
                elif line.strip().startswith('RUN_TIME'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Program run time = {}'.format(value))
                elif line.strip().startswith('RAPID_TIME'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Rapid time = {}'.format(value))
                elif line.strip().startswith('PROBE_TIME'):
                    value = line.split('=')[1].strip()
                    self.prefParms.append('Probe time = {}'.format(value))
            self.prefParms.append('')

# READ THE ORIGINAL <MACHINE_NAME>_MATERIAL.CFG FILE
    def read_mat_file(self, matFile, newDir, machineName):
        newFile = '{}/{}_material.cfg'.format(newDir, machineName)
        if os.path.isfile(newFile):
            matCopy = '{}_{}'.format(newFile, self.date, str(time.time()).split('.')[0])
            COPY(newFile, matCopy)
        with open(newFile, 'w') as outFile:
            with open(matFile) as inFile:
                for line in inFile:
                    if line.startswith('THC') or line.startswith('#THC'):
                        continue
                    outFile.write(line)

# WRITE THE NEW QTVCP.PREFS & QTPLASMAC.PREFS FILES
    def write_prefs_files(self, newDir, machineName):
        prefsFile = '{}/qtvcp.prefs'.format(newDir)
        with open(prefsFile, 'w') as outFile:
            outFile.write(\
                '[NOTIFY_OPTIONS]\n' \
                'notify_start_greeting = False\n' \
                'notify_start_title = Welcome To QtPlasmaC\n' \
                'notify_start_detail = This option can be changed in qtvcp.prefs\n' \
                'notify_start_timeout = 5\n\n')
        prefsFile = '{}/{}.prefs'.format(newDir, machineName)
        with open(prefsFile, 'w') as outFile:
            for item in self.prefParms:
                outFile.write('{}\n'.format(item))

# SIM CONFIG POSTGUI EXTRAS
    def sim_postgui(self):
        sim  = '# QTPLASMAC SIMULATOR PANEL\n\n'
        sim += '# load the simulated torch\n'
        sim += 'loadusr -Wn sim-torch sim-torch\n\n'
        sim += '# load the sim GUI\n'
        sim += 'loadusr -Wn qtplasmac_sim qtvcp qtplasmac_sim.ui\n\n'
        sim += '# connect to existing plasmac connections\n'
        sim += 'net plasmac:torch-on        =>  qtplasmac_sim.torch_on  sim-torch.start\n'
        sim += 'net plasmac:cut-volts       =>  sim-torch.voltage-in\n\n'
        sim += '# create new sim connections\n'
        sim += 'net sim:arc-ok              qtplasmac_sim.arc_ok                =>  db_arc-ok.in\n'
        sim += 'net sim:arc-voltage-in      sim-torch.voltage-out               =>  plasmac.arc-voltage-in\n'
        sim += 'net sim:arc_voltage_offset  qtplasmac_sim.arc_voltage_offset-f  =>  sim-torch.offset-in\n'
        sim += 'net sim:breakaway           qtplasmac_sim.sensor_breakaway      =>  db_breakaway.in\n'
        sim += 'net sim:float               qtplasmac_sim.sensor_float          =>  db_float.in\n'
        sim += 'net sim:move-down           qtplasmac_sim.move_down             =>  plasmac.move-down\n'
        sim += 'net sim:move-up             qtplasmac_sim.move_up               =>  plasmac.move-up\n'
        sim += 'net sim:ohmic               qtplasmac_sim.sensor_ohmic          =>  db_ohmic.in\n'
        return sim

if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setQuitOnLastWindowClosed(False)
    w = Converter()
    app.lastWindowClosed.connect(w.close_app)
    w.show()
    sys.exit(app.exec_())
