#!/usr/bin/env python3

 

import os

import sys

import time

 

try:

    import tkinter as tk

    from tkinter import ttk

    from tkinter.font import Font

except Exception as e:

    file.write(timestamp + " Tkinter library not found. Please install it. {e}" + "\n")

    print("Tkinter library not found. Please install it.")

    

import paho.mqtt.client as mqtt

 

rpi = False

try:

    import RPi.GPIO as GPIO

    rpi = True

except Exception as e:

#   file.write(timestamp + " Error :  {e}" + "\n")

    print(f"Error:  {e}")

    

class MQTT_Client:

    

    @staticmethod

    def setup(root):

        fname = os.path.basename(sys.argv[0]).strip("QTT-.py")

        fpath = os.getcwd()

        ti_m = os.path.getmtime(fpath)

        filemodtime = time.strftime("%d %H:%M", time.localtime(ti_m))

        root.title(fname + "(" + filemodtime + ")")

        

    def __init__(self, master):

        self.master = master

        self.master.geometry("250x300")

        

        self.mqtt_client = mqtt.Client()

        self._connect_mqtt_client()

        

        self.mqtt_client.on_message = self.on_message

        self.mqtt_client.subscribe("frog")

        

        self.message_list = []

        self.last_highlighted_index = None

        

        self._create_ui_components()

        

        self.master.after(500, self.check_messages)

        

    def _connect_mqtt_client(self):

        try:

            self.mqtt_client.connect("192.168.0.57", 1883, 60)

        except Exception as e:

            file.write(timestamp + " Error connecting to MQTT broker: {e}" + "\n")

            print(f"Error connecting to MQTT broker: {e}")

            self.mqtt_client.connect("192.168.0.57", 1883, 60)

            #sys.exit(1)

            

    def _create_ui_components(self):

        self.message_label = ttk.Label(self.master, text="No messages yet")

        self.message_label2 = ttk.Label(self.master, text="No messages yet")

        self.message_label3 = ttk.Label(self.master, text="        ")

        self.message_label4 = ttk.Label(self.master, text="        ")

        self.message_label5 = ttk.Label(self.master, text="")

        

        if rpi:

            self.message_label3 = ttk.Label(self.master, text="  ")

            self.message_label4 = ttk.Label(self.master, text="   ")

            

        self.listbox = tk.Listbox(self.master, height=20 if not rpi else 10)

        self.listbox.bind("<Button-1>", self.on_select)

        

        self.message_label.pack(side="top")

        self.message_label2.pack(side="top")

        self.message_label3.pack(side="left")

        self.message_label4.pack(side="right")

        self.message_label5.pack(side="bottom")

        self.listbox.pack(side="top", expand=True)

        

    def on_message(self, client, userdata, message):

        timestamp = time.strftime('%d//%m/%y  %H:%M:%S', time.localtime(time.time()))

        payload = message.payload.decode("utf-8")

        

        with open("event_list.csv", "a+") as file:

            file.write(timestamp + " " + payload + "\n")

            

        print(timestamp + " " + payload)

                        

        self.message_label.configure(text=payload + "\n" + timestamp)

 

        # Update the listbox

        self._update_listbox(payload)

 

    def _update_listbox(self, payload):

        if payload not in self.message_list:

            # Add new message to the message list and listbox

            self.message_list.insert(0, payload)

            self.listbox.insert(0, payload)

            self.listbox.itemconfig(0, bg="white", fg="black")

            

            # Reset the background and foreground color of the last highlighted index

            if self.last_highlighted_index is not None:

                self.listbox.itemconfig(self.last_highlighted_index, bg="white", fg="black")

            self.last_highlighted_index = None

        else:

            # Find the index of the existing message in the message list

            index = self.message_list.index(payload)

            

            # Remove the existing message from the message list and listbox

            self.message_list.pop(index)

            self.listbox.delete(index)

            

            # Add the existing message to the top of the message list and listbox

            self.message_list.insert(0, payload)

            self.listbox.insert(0, payload)

            self.listbox.itemconfig(0, bg="white", fg="black")

            

            # Reset the background and foreground color of the last highlighted index

            if self.last_highlighted_index is not None:

                self.listbox.itemconfig(self.last_highlighted_index, bg="white", fg="black")

            self.last_highlighted_index = None

            

 

    def check_messages(self):

        clock_time_string = time.strftime("%H:%M:%S")

        self.message_label2.configure(text=clock_time_string, font=Font(size=40 if not rpi else 25))

 

        try:

            self.mqtt_client.loop()

            self.master.after(100, self.check_messages)

        except BaseException as err:

            with open("event_list.csv", "a+") as file:

                file.write(timestamp + " An unexpected error occurred: {err}" + payload + "\n")

            print(f"An unexpected error occurred: {err}")

            self._reconnect_mqtt_client()

 

    def _reconnect_mqtt_client(self):

        self.mqtt_client.disconnect()

        self.mqtt_client = mqtt.Client()

        self._connect_mqtt_client()

        self.mqtt_client.subscribe("frog")

        self.mqtt_client.on_message = self.on_message

 

    def on_select(self, event):

        self._reconnect_mqtt_client()

 

        widget = event.widget

        selection = widget.curselection()

        if selection:

            index = selection[0]

            payload = widget.get(index)

            self.mqtt_client.publish("frog", payload)

 

 

if __name__ == "__main__":

    root = tk.Tk()

    MQTT_Client.setup(root)

    mqtt_client = MQTT_Client(root)

    root.mainloop()