class ImageViewer:
    def __init__(self, root):
        self.SUPPORTED_EXTENSIONS = (".png", ".jpg", ".jpeg", ".gif", ".bmp", ".JPG", ".JPEG", ".BMP", ".GIF", ".webp", ".WEBP")
        self.button_style = {"font": ("consolas", 10), "fg": "white", "bg": "#3c3c3c", "relief": "flat"}
		
        #self.image_loading_queue = Queue(maxsize=5)
        self.switch_timestamps = []
        self.debounce_timer = None  # Timer ID for debouncing
        self.DEBOUNCE_DELAY = 1000  # Debounce delay in milliseconds

        self.root = root
        self.root.geometry("800x600")  # Initial window size
        self.root.title("Jestur Viewer")
        self.root.configure(bg="#808080")  # Set window background color
        self.root.attributes("-topmost", True)  # Make the window stay on top

        self.image_folder = ""
        self.image_files = []
        self.current_image_index = 0

        self.main_frame = tk.Frame(self.root, bg="#808080")
        self.main_frame.pack()

        self.select_folder_button = tk.Button(self.main_frame, text="Select Folder", command=self.select_folder)
        self.select_folder_button.configure(**self.button_style)
        self.select_folder_button.pack(side=tk.LEFT, padx=5, pady=10)

        self.set_timer_button = tk.Button(self.main_frame, text="Timer", command=self.set_timer_interval)
        self.set_timer_button.configure(**self.button_style)
        self.set_timer_button.pack(side=tk.LEFT, padx=5, pady=10)

        self.start_button = tk.Button(self.main_frame, text="Start", command=self.start_pause_slideshow)
        self.start_button.configure(font=self.button_style["font"], bg="#909090", fg="#707070", relief=tk.FLAT)
        self.start_button.pack(side=tk.LEFT, padx=5, pady=10)

        self.mirror_button = tk.Button(self.main_frame, text=">|<", command=self.toggle_mirror_image)
        self.mirror_button.configure(**self.button_style)
        self.mirror_button.pack(side=tk.LEFT, padx=5, pady=10)
        
        self.greyscale_button = tk.Button(self.main_frame, text="B/W", command=self.toggle_greyscale)
        self.greyscale_button.configure(**self.button_style)
        self.greyscale_button.pack(side=tk.LEFT, padx=5, pady=10)
        
		
        self.random_next_image_var = tk.BooleanVar(value=False) # Checkbox variable
        self.random_next_image_checkbox = tk.Checkbutton(self.main_frame, text="Random", variable=self.random_next_image_var, command=self.toggle_colors)
        self.random_next_image_checkbox.configure(**self.button_style, bd=2)
        self.random_next_image_checkbox.pack(side=tk.LEFT, padx=5, pady=10)
		
		#image label
        self.canvas = tk.Canvas(self.root)
        self.is_mirrored = False
        self.is_greyscale = False
        self.is_paused = False
		
        self.timer_label = tk.Label(self.root, text="5", **self.button_style, anchor="ne") #fg="white", bg="black", font=("arial", 12), bd=1, relief=tk.RIDGE)
        self.timer_label.configure(font=("consolas",17))
        self.timer_label.place(relx=1, anchor="ne", x=-0, y=0)

        self.timer_interval = 5000  # Default time interval in milliseconds (5 seconds)
        self.set_timer_interval = 5000  # Store the set timer interval
        self.timer = None  # Timer ID
		
        self.window_size = (self.root.winfo_width(), self.root.winfo_height())
        self.resize_timer = None

        self.root.bind("<Right>", self.next_image)
        self.root.bind("<Left>", self.previous_image)
        self.root.bind("<space>", self.start_pause_slideshow)
        self.root.bind("<Configure>", self.update_image_size)
		
    def toggle_colors(self):
        if self.random_next_image_var.get():
            self.random_next_image_checkbox.configure(fg="#2c2c2c", bg="#d8d8d8")
        else:
            self.random_next_image_checkbox.configure(**self.button_style)

    def select_folder(self):
        self.image_folder = filedialog.askdirectory()
        if self.image_folder:
            image_files = os.listdir(self.image_folder) # Get all files in the selected folder
            self.image_files = [file for file in image_files if file.endswith(self.SUPPORTED_EXTENSIONS)] # Filter image files
            
            if len(self.image_files) > 0:
                self.current_image_index = 0
                self.canvas.pack(fill=tk.BOTH, expand=True)
                self.select_folder_button.pack(side=tk.LEFT, padx=5, pady=5)
                self.root.title("Jesturing in " + self.image_folder)
                self.canvas.config(bg="#808080", highlightthickness=0)
                self.display_image()   
                self.start_button.config(**self.button_style)
            else:
                messagebox.showinfo("No Image Files", "The selected folder does not contain any image files.")
                self.image_folder = ""
                self.root.title("Jestur")

    def set_timer_interval(self):
        self.root.attributes("-topmost", False)
        interval = simpledialog.askinteger("Set Timer Interval", "How many seconds?")        
        if interval:
            if interval < 1:  # Check if interval is less than 1 second
                interval = 1
            self.timer_interval = interval * 1000  # Convert to milliseconds
            self.set_timer_interval = self.timer_interval  # Store the set timer interval
        self.root.lift()  # Bring the main window to the top
        self.root.focus_force()  # Give focus to the main window
        self.root.attributes("-topmost", True)

    def start_pause_slideshow(self, event=None):
        if self.image_folder == "":
            messagebox.showinfo("You haven't picked a folder", "Please select an image folder first.")
        else:
            if self.timer is None:  # Check if timer is not running
                self.display_image()
                self.start_button.config(text="Pause")
                self.is_paused = False  # Set paused flag to False
                self.start_timer()
            else:
                if self.is_paused:  # Check if the slideshow is paused
                    self.start_button.config(text="Pause")
                    self.is_paused = False  # Set paused flag to False
                    self.start_timer()
                else:
                    self.pause_timer()
                    self.start_button.config(text="Start")
                    self.is_paused = True  # Set paused flag to True
    
    def pause_timer(self):
        if self.timer is not None:
            self.root.after_cancel(self.timer)
            self.timer = None

    def start_timer(self):
        if self.image_folder != "" and not self.is_paused:
            self.update_timer()
            self.timer = self.root.after(1000, self.start_timer)

    def update_timer(self):
        seconds_left = int(self.timer_interval / 1000)
        self.timer_label.config(text=f"{seconds_left}")
        self.timer_interval -= 1000

        if self.timer_interval < 0:
            self.timer_interval = self.set_timer_interval  # Use the stored set timer interval
            self.next_image()
			
    def toggle_mirror_image(self):
        self.is_mirrored = not self.is_mirrored
        self.display_image()

    def toggle_greyscale(self):
        self.is_greyscale = not self.is_greyscale
        self.display_image()			
		
    def load_image(self, image_path):
        image = Image.open(image_path)
        
        # Check if the image has EXIF data
        if "exif" in image.info:
            exif_data = piexif.load(image.info["exif"])
            if piexif.ImageIFD.Orientation in exif_data["0th"]:
                orientation = exif_data["0th"][piexif.ImageIFD.Orientation]
                if orientation == 3:
                    image = image.rotate(180, expand=True)
                elif orientation == 6:
                    image = image.rotate(-90, expand=True)
                elif orientation == 8:
                    image = image.rotate(90, expand=True)
    
        if self.is_greyscale:
            image = image.convert("L")
    
        if self.is_mirrored:
            image = image.transpose(Image.FLIP_LEFT_RIGHT)
    
        aspect_ratio = image.width / image.height
        canvas_width = self.canvas.winfo_width()
        canvas_height = self.canvas.winfo_height()
        max_width = min(canvas_width, int(aspect_ratio * canvas_height))
        max_height = min(canvas_height, int(canvas_width / aspect_ratio))
        scale_factor = min(max_width / image.width, max_height / image.height)
        new_width = int(image.width * scale_factor)
        new_height = int(image.height * scale_factor)
    
        if new_width > 0 and new_height > 0:
            resized_image = image.resize((new_width, new_height), Image.BICUBIC)
            self.photo = ImageTk.PhotoImage(resized_image)
            self.canvas.delete("all")
            self.canvas.create_image(canvas_width // 2, canvas_height // 2, image=self.photo)

    def display_image(self):
        if self.image_folder != "" and len(self.image_files) > 0:
            if self.update_switch_timestamps():
                # Show the text of the image name instead of loading the actual image
                image_name = self.image_files[self.current_image_index]
                self.canvas.delete("all")  # Clear the canvas
                self.canvas.create_text(
                    self.canvas.winfo_width() // 2, 
                    self.canvas.winfo_height() // 2,
                    text=image_name,
                    fill="white")

                # Set the debounce timer
                self.debounce_timer = self.root.after(self.DEBOUNCE_DELAY, self.load_image_debounced)
            else:
			# Process the queue and load the image normally if not quick-switching
                 image_path = os.path.join(self.image_folder, self.image_files[self.current_image_index])
                 threading.Thread(target=self.load_image, args=(image_path,)).start()

    def cancel_debounce(self):
        if self.debounce_timer is not None:
            self.root.after_cancel(self.debounce_timer)
            self.debounce_timer = None

    def load_image_debounced(self):
        self.debounce_timer = None  # Clear the debounce timer ID
        image_path = os.path.join(self.image_folder, self.image_files[self.current_image_index])
        threading.Thread(target=self.load_image, args=(image_path,)).start()
    
    def update_image_size(self, event=None):
        current_width = self.root.winfo_width()
        current_height = self.root.winfo_height()
    
        if (current_width, current_height) != self.window_size:
            self.window_size = (current_width, current_height)
            self.canvas.config(width=current_width, height=current_height)
            self.buffer_forsize()
			
    def buffer_forsize(self, event=None):
        if self.resize_timer:
            self.root.after_cancel(self.resize_timer)
        self.resize_timer = self.root.after(500, self.display_image)

    def update_switch_timestamps(self):
        current_time = time.time()
        self.switch_timestamps.append(current_time)
        self.switch_timestamps = [t for t in self.switch_timestamps if current_time - t <= 2]
        if len(self.switch_timestamps) > 6:
            return True  # Too many updates in a short time period
        return False
		
    def next_image(self, event=None):
        if self.image_folder != "":
            if self.random_next_image_var.get(): # Check if random next image is selected
                self.current_image_index = random.randint(0, len(self.image_files) - 1) # Randomly select the next image index
            else:
                self.current_image_index = (self.current_image_index + 1) % len(self.image_files) # Linearly select the next image index
                
            self.display_image()
            self.timer_interval = self.set_timer_interval  # Use the stored set timer interval

    def previous_image(self, event=None):
        if self.image_folder != "":
            if self.random_next_image_var.get(): # Check if random next image is selected
                self.current_image_index = random.randint(0, len(self.image_files) - 1) # Randomly select the next image index
            else:
                self.current_image_index = (self.current_image_index - 1) % len(self.image_files)
            self.display_image()
            self.timer_interval = self.set_timer_interval  # Use the stored set timer interval
			

how do i implement a queue so that when load image is called it'll be added into queue and then it'll only process the last of the queue to only process the current last image after letting go of the button. note that i need it to process the text image name like normal, and only add the image loading part to queue