import sys,os,re,time
import numpy as np
import PI_GUI_App_Map as pgam
import PI_GUI_Func as pgfunc

from PyQt5 import uic
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtWidgets import QLineEdit
from PyQt5.QtWidgets import QMessageBox
from PyQt5.QtWidgets import QProgressDialog
from PyQt5.QtWidgets import QWidget
from PyQt5.QtWidgets import QGridLayout
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtWidgets import QTextBrowser
from PyQt5.QtWidgets import QLabel
from PyQt5.QtWidgets import QDesktopWidget
from PyQt5.QtWidgets import QProgressBar
from  PyQt5.QtWidgets import QFileDialog
from PyQt5.QtGui import *
from PyQt5.QtCore import Qt
from PyQt5.QtCore import QThread
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtCore import QObject

#####Monkey Patch
def AddnRefresh(self,content):
    self.append(content)
    self.verticalScrollBar().setValue(self.verticalScrollBar().maximum())
QTextBrowser.AddnRefresh=AddnRefresh

class Appmap(QWidget):

    def __init__(self,mainwin):
        super().__init__()
        self.ui=uic.loadUi('PI_GUI_App_Map.ui',self)
        self.mainwin=mainwin
        self.xlist=[]
        self.ylist=[]
        self.zlist=[]
        self.replaced_list=[]
        self.permission=False
        self.textBrowser_log=self.mainwin.textBrowser_log
        self.main()
#——————————————————————————————————#
    def main(self):
        self.setWindowTitle('Approach Curve-Map')
        self.lineEdit_xp.setText('0')
        self.lineEdit_yp.setText('0')
        self.lineEdit_zp.setText('0,2,4,6,8,10,15,20,25,30,35,40,45,50,60,70,80,90,100,125,150,200,250,300,350,450')
        self.lineEdit_monitee.setText(r'C:\Users\jy1u18\OneDrive - University of Southampton\PhD\Second Project\Electrochemistry\20211020')
        self.lineEdit.setText('dis,dis')
        self.lineEdit_xp.editingFinished.connect(
            lambda: self.list_read(widget=self.lineEdit_xp,tlist=self.xlist))
        self.lineEdit_yp.editingFinished.connect(
            lambda: self.list_read(widget=self.lineEdit_yp,tlist=self.ylist))
        self.lineEdit_zp.editingFinished.connect(
            lambda: self.list_read(widget=self.lineEdit_zp,tlist=self.zlist))
        self.lineEdit.editingFinished.connect(
            lambda: self.list_read(widget=self.lineEdit,tlist=self.replaced_list,ty=str))
        self.lineEdit_xp.editingFinished.connect(self.Sample_Stat)
        self.lineEdit_yp.editingFinished.connect(self.Sample_Stat)
        self.lineEdit_zp.editingFinished.connect(self.Sample_Stat)
        self.checkBox.clicked.connect(self.RenameSwitch)
        self.proceed.clicked.connect(self.Monitor_Thrd)
        self.toolButton.clicked.connect(self.FileBrowser)

        self.list_read(widget=self.lineEdit_xp,tlist=self.xlist)
        self.list_read(widget=self.lineEdit_yp,tlist=self.ylist)
        self.list_read(widget=self.lineEdit_zp,tlist=self.zlist)
        self.Sample_Stat()

##### GUI Slots
    def Sample_Stat(self):
        try:
            self.num2d=len(self.xlist) * len(self.ylist)
            self.num3d=len(self.zlist)
            for i in [len(self.xlist),len(self.ylist)]:
                if i != 0:
                    self.num3d=self.num3d*i
            self.lineEdit_total_2d.setText(str(self.num2d))
            self.lineEdit_total_exp.setText(str(self.num3d))
        except KeyboardInterrupt:
            raise KeyboardInterrupt
    def RenameSwitch(self):
        if self.checkBox.isChecked():
            self.label_3.setEnabled(True)
            self.lineEdit.setEnabled(True)
        else:
            self.label_3.setEnabled(False)
            self.lineEdit.setEnabled(False)
    def Monitor_Thrd(self):
        try: 
            self.mainwin.ServoCheck()
            self.filename=self.lineEdit_monitee.text()
        except Exception as arg_err:
            self.textBrowser_log.AddnRefresh(str(arg_err))
        
        if self.permission==True:
            self.proceed.setEnabled(False)
            self.msgrunning=QProgressDialog()
            self.msgrunning.setWindowTitle('Approach Curve experiment in progress...')
            self.msgrunning.setLabelText('Approach Curve experiments running.\n'
                'Do not close this or other window while running. \n This window will close upon finish.')
            self.msgrunning.setCancelButton(None)
            self.msgrunning.show()
        
            self.mon_thrd=pgfunc.ExpMonitor(self.xlist,self.ylist,self.zlist,self.num3d,self.textBrowser_log,self.filename+r'\count.txt')
            self.mon_thrd.setProgress.connect(self.msgrunning.setValue)
            self.mon_thrd.signal_ascent.connect(self.Signal_Ascent)
            self.mon_thrd.exp_cmplt.connect(self.ExpComplete)
            self.mon_thrd.start()
            if self.checkBox.isChecked()==True:
                print('rename monitor starting')
                self.rename_thrd=pgfunc.RenameMonitor(self.filename,self.replaced_list,self.zlist)
                self.rename_thrd.animation.connect(
                    lambda: self.ProgressLabelRenew)
                self.rename_thrd.start()
        else:
            self.warning=QMessageBox()
            self.warning=QMessageBox()
            self.warning.setIcon(QMessageBox.Critical)
            self.warning.setText('Servos of all axis must be on!')
            self.warning.setStandardButtons(QMessageBox.Ok)
            self.warning.setWindowTitle('Error')
            self.warning.show()
    def FileBrowser(self):
        self.filename=QFileDialog.getExistingDirectory(None,'Monitor Folder',r'C:\Users\jy1u18\OneDrive - University of Southampton\PhD\Second Project\Electrochemistry')
        if self.filename=='':
            pass
        else:
            self.lineEdit_monitee.setText(self.filename)

##### Monitor Thread Slots
    def ProgressLabelRenew(self,string):
        self.msgrunning.setLabelText('Now at '+string)
    def Signal_Ascent(self,paraset):
        self.mainwin.Receiver(paraset)
    def ExpComplete(self):
        self.textBrowser_log.AddnRefresh('Experiments done!')
        self.proceed.setEnabled(True)
        self.msgrunning.close()

##### Auxilary  Function
    def list_read(self,widget,tlist,ty=int):
        try:
            string=widget.text()
            res=[]
            element=string.split(",")
            sets=[]
            num=[]
            for ele in element:
                if '(' in ele:
                    sets.append(ele)           
                else:
                    num.append(ty(ele))
            res+=list(map(ty, num))
            for i in sets:
                numset=re.findall(r'[(](.*?)[)]', i)
                rangepara=numset[0].split(' ')
                rangepara=list(map(ty, rangepara))
                res+=np.arange(rangepara[0],rangepara[1]+1,rangepara[2]).tolist()
            tlist[:]=res
        except KeyboardInterrupt:
            raise KeyboardInterrupt
        except Exception:
            self.errormsg=QMessageBox()
            self.errormsg.setIcon(QMessageBox.Critical)
            self.errormsg.setText('Potentially input error, please check your inputs')
            self.errormsg.setStandardButtons(QMessageBox.Ok)
            self.errormsg.setWindowTitle('Error')
            self.errormsg.show()
    def closeEvent(self,event):
        try:
            self.mon_thrd.terminate()
            self.rename_thrd.terminate()
            self.textBrowser_log.AddnRefresh('monitor threads terminated')
        except Exception as arg_err:
            self.textBrowser_log.AddnRefresh(str(arg_err))
            pass
if __name__=='__main__':
    # os.system('python -m PyQt5.uic.pyuic PI_GUI_App_Map.ui -o PI_GUI_App_Map.py')

    app = QApplication(sys.argv)
    win=QWidget()
    move_request=pyqtSignal(list)
    ui=Appmap(win,move_request)
    win.show()
    sys.exit(app.exec_())