import os
import glob
import random
from tkinter import Tk, Button, filedialog, Label, Checkbutton, IntVar

from PIL import Image

# Supported image extensions
IMAGE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp']

class ImageIndexerApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Image Indexer")
        
        self.open_button = Button(self.root, text="Open Folder", command=self.on_open_folder)
        self.open_button.pack()
        
        self.next_button = Button(self.root, text="Next Image", command=self.next_image, state='disabled')
        self.next_button.pack()

        self.prev_button = Button(self.root, text="Previous Image", command=self.prev_image, state='disabled')
        self.prev_button.pack()
        
        self.total_images_label = Label(self.root, text="Total images: 0")
        self.total_images_label.pack()

        # Label to show the count of images displayed
        self.img_count_label = Label(self.root, text="Images shown: 0")
        self.img_count_label.pack()

        self.random_mode = IntVar()
        self.random_checkbox = Checkbutton(self.root, text="Random", variable=self.random_mode)
        self.random_checkbox.pack()

        self.limit_mode = IntVar()
        self.limit_checkbox = Checkbutton(self.root, text="Limit to 20", variable=self.limit_mode)
        self.limit_checkbox.pack()

        self.img_num = 0
        self.image_files = []
        self.image_history = []
        self.random_pool = []  # Store images not yet shown in random mode
        self.img_count = 0  # Counter for images shown
        self.img_limit = 20  # Restrict to 20 images

    def is_image(self, filename):
        """Check if a file is an image that can be opened."""
        try:
            Image.open(filename)
            return True
        except (IOError, FileNotFoundError):
            return False

    def on_open_folder(self):
        """Open a directory and list all valid image files."""
        directory = filedialog.askdirectory()
        if not directory:
            return
        self.image_files = self.list_images(directory)  # This is your existing code.
        # Right after loading image files and before setting the index to 0:
        # Initialize random_pool with a list of indices
        self.random_pool = list(range(len(self.image_files)))
         # Reset the current image index
        self.img_num = 0
        self.image_history = []
        # Initialize random_pool with indices
        self.random_pool = list(range(len(self.image_files))) if self.random_mode.get() else []
        self.img_count = 0
        self.total_images_label.config(text=f"Total images: {len(self.image_files)}")
        self.update_img_count_label()
        if self.image_files:
            # Enable buttons after directory is loaded
            self.next_button.config(state='normal')
            self.prev_button.config(state='normal')

    def next_image(self):
        """Display the next image in a linear or random fashion without repetition."""
        if not self.image_files or (self.limit_mode.get() and self.img_count >= self.img_limit):
            return

        # Check if random_mode is enabled
        if self.random_mode.get():
            # Random mode without repetition
            if not self.random_pool:
                self.shuffle_images()  # Prepare pool if it's not already set
            self.img_num = self.random_pool.pop(0)  # Get the next image index from the pool
        else:
            # Linear mode
            self.img_num = (self.img_num + 1) % len(self.image_files)

        self.display_image(add_to_history=True)
        self.img_count += 1
        self.update_img_count_label()
        # Check if 'Previous' button should be enabled
        self.prev_button.config(state='normal' if self.image_history else 'disabled')

    def prev_image(self):
        """Display the previous image from the history, or in a linear/random fashion if empty."""
        if self.image_history:
            # Use history to go back
            self.img_num = self.image_history.pop()
        else:
            if self.random_mode.get():
                # Random mode without repetition
                if not self.random_pool:
                    self.shuffle_images()
                self.img_num = self.random_pool.pop(0)
            else:
                # Linear mode
                self.img_num = (self.img_num - 1) % len(self.image_files)

        self.display_image(add_to_history=False)

    def shuffle_images(self):
        """Shuffle the image files for random mode."""
        # Shuffle the indices, not the files
        self.random_pool = list(range(len(self.image_files)))
        random.shuffle(self.random_pool)

    def random_image(self):
        """Selects a random image from the pool and displays it."""
        if not self.image_files or (self.limit_mode.get() and self.img_count >= self.img_limit):
            return

        if not self.random_pool:
            self.shuffle_images()  # Make sure random_pool has indices
        # Pop a random index from the random pool
        self.img_num = self.random_pool.pop(random.randrange(len(self.random_pool)))
        self.display_image(add_to_history=True)
        self.img_count += 1
        self.update_img_count_label()

    def display_image(self, add_to_history):
        """Display the current image and update the history if required."""
        # Fixed the TypeError: now using the index to access the image file
        current_file = self.image_files[self.img_num]
        print(f"{self.img_num + 1}: {current_file}")
        
        if add_to_history:
            # Add the current index to the history, not the file itself
            self.image_history.append(self.img_num)
        
        # Potential code to actually show the image if desired - Replace the print statement
        # image = Image.open(current_file)
        # image.show()

        self.prev_button.config(state='normal')  # Always enable 'Previous' button

    def update_img_count_label(self):
        """Update the label that shows the count of images displayed."""
        self.img_count_label.config(text=f"Images shown: {self.img_count}")

    def list_images(self, directory):
        """List all the image files in a given directory."""
        images = []
        for extension in IMAGE_EXTENSIONS:
            images.extend(glob.glob(os.path.join(directory, f"*{extension}")))
        images = [img for img in images if self.is_image(img)]
        return images

if __name__ == '__main__':
    root = Tk()
    app = ImageIndexerApp(root)
    root.mainloop()

make it so that when the limit is clicked, it sets the limits for the following images after it is set, after the current image, then prints "end of image yr done". instead of stopping the program when the total image that has been shown is 20
also when i press previous three times, when the history is like:
1.
2.
3.
*previous press*
it returns 
1.
2.
3.
*previous press*
2.
1.
make sure it calls