# nacitanie kniznic
import tkinter as tk
from tkinter import filedialog
from tkinter import *
from matplotlib.figure import Figure 
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk) 
import numpy as np
import csv
from time import sleep
import time
import datetime
import serial.tools.list_ports
import serial
import sys
from threading import *

# premenna - uklada hodnotu tlaku, uklada flout current value
global floutik

# premenna - paused
global Paused
Paused = False

# premenna - timer
global timer
timer=0

class ReadLine:
    def __init__(self, s):
        self.buf = bytearray()  
        self.s = s
    
    def readline(self):
        i = self.buf.find(b"\n")
        if i >= 0:
            r = self.buf[:i+1]
            self.buf = self.buf[i+1:]
            return r
        while True:
            i = max(1, min(2048, self.s.in_waiting))
            data = self.s.read(i)
            i = data.find(b"\n")
            if i >= 0:
                r = self.buf + data[:i+1]
                self.buf[0:] = data[i+1:]
                return r
            else:
                self.buf.extend(data)

# premenna - currentVal/aktualna hodnota
global currentVal

# funckia - read fast
def readFast():
    global currentVal
    global Logging
    global floutik 
    global f
    rl = ReadLine(ser)
    while Reading == True:
        try:
            currentVal = rl.readline()
            floutik = float(currentVal)
            
            if Logging == True:
                now_time = time.strftime('%X')
                f.write(now_time+" "+str(floutik) +" mbar" '\n')
        except:
            continue
    

# premenna - ne/pripojene + label
global isConnected
isConnected = False

global connectLabel
connectLabel = 'Pripojenie zariadenia'

# premenna - citanie/reading
global Reading
Reading = False 

# premenna - slozka otvorenie
global fileOpened
fileOpened = False

# premenna - logovanie
global Logging
Logging = False

# premenna - priecinok
global Folder
Folder = ''

# premenna - slozka loggs
global logfile
logfile = ''

# premenna - pre f.write na loggovanie
global f

global logs
        
# funkcia - vyber priecinok
def SelectFolder():
    global Folder
    Folder = filedialog.askdirectory()
    path_name=str(Folder)

    frame0 = tk.Frame(root, width=800, height=600, relief='solid', bd=1, background="white")
    frame0.place(x=10, y=720)
    path_name_label = tk.Label(frame0, text=path_name, bg="white", fg="black", font='Helvetica 12 bold')

    path_name_label.pack()

# funkcia - ESP connect
def ConnectESP():
    global isConnected
    global connectLabel
    global ser
    global B_connect
    find_com = serial.tools.list_ports
    COM = find_com.comports()
    ser = serial.Serial()
    ser.baudrate = 115200   
    try:
        ser.port = COM[0][0]
        ser.open()
        isConnected = True
        connectLabel = 'Pripojene zariadenie'
        B_connect.config(text=connectLabel)
        B_connect["state"] = DISABLED

    except:
        tk.messagebox.showwarning(title='Chyba - nenašlo sa zariadenie', message='Pripoj zariadenie k počítaču')
        isConnected = False

# funkcia - spustenie logovania
def StartLogging():
    global f
    global Logging
    global fileOpened
    import time
    
    if Folder == '':
        tk.messagebox.showwarning(title='Chyba - žiaden priečinok', message='Vyber priečinok pre logovanie')
    elif Reading == False:
        tk.messagebox.showwarning(title='Chyba - čítanie dát', message='Spusti čítanie dát tlačidlom ON')
    else:
        nameoffile = datetime.datetime.now().strftime("%Y_%m_%d-%H_%M_%S")
        f=open(Folder + '/' + str(nameoffile) + '.txt', 'w+')
        fileOpened = True
        Logging = True

# funkcia - okno s datami z logu
def openLogWindow():
    global logfile

    logWindow = Toplevel(root)
    logWindow.title("Log")
    logWindow.geometry("797x600")
    logWindow.resizable(width=0, height=0)
    logWindow.configure(background='#93AEDC')

    frame12 = tk.Frame(logWindow, width=797, height=600, relief='solid', bd=0, background="white")
    frame12.place(x=0, y=0)

    S = Scrollbar(frame12)

    log = tk.Text(frame12, height=35, width=86)
    log.place(relx = 0, rely = 0, anchor = 'nw')
    
    S.pack(side = RIGHT, fill = Y)

    log.config(yscrollcommand = S.set)    
    log.pack(side = LEFT, fill = Y)
    S.config(command=log.yview)

    with open(logfile, "r") as txtr:
        data = txtr.read()
    log.insert(tk.END, data)
   
    
# funkcia - ukoncenie logovania  
def StopLogging():
    global f
    global Logging
    global fileOpened
    Logging = False
    if fileOpened == True:
        f.close()
        fileOpened = False    

# funkcia - okno s loggs
def OpenLogs():
    global logfile
    if Reading == False and Logging == False:
        logfile = filedialog.askopenfilename(filetypes=[("Text files (.txt)", ".txt")])
        EndReading()
        StopLogging()
        if logfile != '':
            openLogWindow()
    else:
        tk.messagebox.showwarning(title='Chyba - zapnuté čítanie dát', message='Čítanie dát bolo vypnuté')
        StopLogging()
        EndReading()
        logfile = filedialog.askopenfilename(filetypes=[("Text files (.txt)", ".txt")])
        if logfile != '':
            openLogWindow()

# funkcia - refresh grafu
def RefreshGraph():
    line1.set_ydata(y)
    line1.set_xdata(x)
    fig.canvas.draw()
    fig.canvas.flush_events()

# funkcia - vytvori graf a na konci zavola Refresh, aby bol vykresleny
def DrawGraph():
    global y
    global x
    global plot1
    global line1
    global fig
    y = []
    x = []
    plot1 = fig.add_subplot(111)
    fig.subplots_adjust(top=0.85, left=0.07, right=0.97)
    plot1.set_title('Monitor tlaku mikrofluidného systému',fontsize= 30, color='Black',fontweight="bold", fontname="Comic Sans MS")
    plot1.set_ylim([0,350])
    plot1.set_xlim([0, 10])
    plot1.set_ylabel("Tlak [mbar]",fontsize= 12, fontweight="bold")
    plot1.set_xlabel("Čas záznamu [s]", fontsize= 12, fontweight="bold")
    
    line1, = plot1.plot(y)
    RefreshGraph() 

# funkcia - vlakno/thread - readfast
global t1


# funkcia - spustenie citania dat
def StartReading():
    global Reading
    global plot1
    global y
    global starttime
    global Paused
    global timer
    global pasttime
    global t1

    if Paused == False:
        starttime = time.time()   
    else:
        starttime = time.time() - timer

    if isConnected == True:
        Reading = True
        t1 = Thread(target=readFast)
        t1.daemon = True
        t1.start()
    else:
        tk.messagebox.showwarning(title='Chyba - nepripojené zariadenie', message='Pripoj zariadenie tlačidlom "Pripojenie zariadenia"')

# funkcia - ukoncenie citanie dat
def EndReading():
    global Reading
    global x
    global Paused
    Paused = True
    Reading = False
    StopLogging()
    
# funkcia - ukonci citanie dat EndReading, odstrani graf a zavola DrawGraph, ktora ho znovu vytvori
def ResetReading():
    global y 
    global x
    global text
    global Paused
    x = []
    y = []
    EndReading()
    Paused = False
    text.configure(text='-')
    fig.clf()
    DrawGraph()
    
# funkcia - nakresli hlavne okno
def Draw():
    global connectLabel
    global text
    root.geometry("1024x768")
    root.resizable(width=0, height=0)
    root.configure(background='#93AEDC')
    root.title('Monitor tlaku mikrofluidného systému')

    # nadpis - senzor
    frame2 = tk.Frame(root, width=800, height=600, relief='solid', bd=3, background="white")
    frame2.place(x=250, y=520)
    label00 = tk.Label(frame2, text="Tlakový senzor SSCDANT005PGAA5", bg="#4B82E1", fg="black", height=1, width=50, font='Helvetica 12 bold')
    label00.place(relx = 10, rely = 10, anchor = 'center')

    # nadpis - aktualna hodnota
    frame = tk.Frame(root, width=800, height=600, relief='solid', bd=1, background="white")
    frame.place(x=250, y=575)
    text = tk.Label(frame, text="-", bg="white", fg="black", font='Helvetica 12 bold')
    press_value = tk.Label(frame, text="Aktuálna hodnota tlaku [mbar]", font='Helvetica 12 bold',bg="white", fg="black" )
    press_value.place(relx = 10, rely = 10, anchor = 'center')
    press_value.pack()
    
    label00.pack()
    text.pack()

    # tlacidlo - on/off/reset/connect
    frame3 = tk.Frame(root, width=800, height=600, relief='solid', bd=3,background="white")
    B_start=Button(frame3, text='ON', bd='5',bg="green", fg="black", font='Helvetica 12 bold',command=StartReading)
    frame3.place(x=10, y= 580)
    
    frame4 = tk.Frame(root, width=800, height=600, relief='solid', bd=3,background="white")
    B_stop=Button(frame4, text='OFF', bd='5', fg='Black',bg="red", font='Helvetica 12 bold',command=EndReading)
    frame4.place(x=75, y= 580)
    
    frame8 = tk.Frame(root, width=800, height=600, relief='solid', bd=3,background="white")
    B_reset=Button(frame8, text='RESET', bd='5', fg='Black',bg="#4B82E1", font='Helvetica 12 bold',command=ResetReading)
    frame8.place(x=150, y= 580)

    global B_connect
    frame20 = tk.Frame(root, width=800, height=600, relief='solid', bd=3,background="white")
    B_connect=Button(frame20, text=connectLabel, bd='5',bg="yellow", fg="black", font='Helvetica 12 bold',command=ConnectESP)
    frame20.place(x=10, y= 520)

    B_connect.pack()
    B_start.pack()
    B_stop.pack()
    B_reset.pack()

    # tlacidlo - start/stop logovanie, preicinok a logs
    frame5 = tk.Frame(root, width=800, height=600, relief='solid', bd=3,background="white")
    B_start_logging=Button(frame5, text='Zap. logovanie', bd='5',bg="#4B82E1", fg="black", font='Helvetica 12 bold', command= StartLogging)
    frame5.place(x=10, y= 650)

    frame9 = tk.Frame(root, width=800, height=600, relief='solid', bd=3,background="white")
    B_stop_logging=Button(frame9, text='Vyp. logovanie', bd='5',bg="#4B82E1", fg="black", font='Helvetica 12 bold', command= StopLogging)
    frame9.place(x=175, y= 650)

    frame6 = tk.Frame(root, width=800, height=600, relief='solid', bd=3,background="white")
    B_select_file=Button(frame6, text='Vybrať priečinok', bd='5',bg="#4B82E1", fg="black", font='Helvetica 12 bold', command = SelectFolder)
    frame6.place(x=345, y= 650)

    frame77 = tk.Frame(root, width=800, height=600, relief='solid', bd=3,background="white")
    B_open_logs=Button(frame77, text='História logov', bd='5',bg="#4B82E1", fg="black", font='Helvetica 12 bold', command=OpenLogs)
    frame77.place(x=850, y= 650)

    B_start_logging.pack()
    B_stop_logging.pack()
    B_select_file.pack()
    B_open_logs.pack()

    # graf
    global y
    global fig
    global plot1
    
    fig = Figure(figsize = (12, 5), dpi = 100, facecolor='#93AEDC',)
    
    DrawGraph()
    
    canvas = FigureCanvasTkAgg(fig, master= root)   
    canvas.get_tk_widget().pack() 
    canvas.draw()
    
# premenna - logovanie status    
global LoggingInfoShown
LoggingInfoShown = False
    
# refresher - aktulizuje vsetko    
def Refresher():
    global LoggingInfoShown
    global text
    global x
    global y
    global plot1
    global line1
    global f
    global time
    global starttime
    global floutik
    global pasttime
    global timer

    if isConnected == True:
        try:
            ser.inWaiting()
        except:
            tk.messagebox.showwarning(title='Chyba - nenašlo sa zariadenie', message='Odpojené zariadenie, program sa vypne!')
            sys.exit(0)


    if Reading == True:
        timer = (time.time() - starttime)
        x = np.append(x, timer)
        y = np.append(y, floutik)
        if len(y) > 500:
            y = y[1:]
        if len(x) > 500:
            x = x[1:]
        plot1.set_xlim([max(0, timer - 8), timer])

        RefreshGraph()
        text.configure(text=str(floutik))


    if Logging == True and LoggingInfoShown == False:
        frame10 = tk.Frame(root, width=100, height=100, relief='solid', bd=1, background="#93AEDC")
        frame10.place(x=550, y=575)
        now_logging_label = tk.Label(frame10, text='Logovanie!', bg="yellow", fg="black", font='Helvetica 12 bold')
        now_logging_label.pack()
        LoggingInfoShown = True
        
    
    if Logging == False and LoggingInfoShown == True:
        frame11 = tk.Frame(root, width=100, height=100, relief='solid', bd=0, background="#93AEDC")
        frame11.place(x=550, y=575)   
        stop_logging_label = tk.Label(frame11, text='Logovanie!', bg="#93AEDC", fg="#93AEDC", font='Helvetica 15 bold')
        stop_logging_label.pack()     
        LoggingInfoShown = False

    root.after(10, Refresher)


root = tk.Tk()
Draw()
Refresher()
root.mainloop()
