import tkinter as tk
from tkinter import filedialog
import os
import random

# Constants
IMG_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp']

# Check if a file extension is an image
def is_image(filename):
    return any(filename.lower().endswith(ext) for ext in IMG_EXTENSIONS)

# Load images from a directory and reset history and total image count
def open_folder():
    folder = filedialog.askdirectory()
    if folder:
        file_list[:] = [(img_number, os.path.join(folder, f))
                        for img_number, f in enumerate(sorted(os.listdir(folder)), 1)
                        if is_image(f)]
        total_number_var.set(len(file_list))
        random_order[:] = random.sample(file_list, len(file_list))
        history.clear()
        images_shown_var.set(0)
        img_label.config(text="No image selected")
        refresh_buttons_state()

# Refresh the state of the buttons and checkboxes based on the current state
def refresh_buttons_state():
    state = 'normal' if file_list else 'disabled'
    limit_cb.config(state=state)
    random_cb.config(state=state)
    next_button.config(state=state)
    prev_button.config(state=state)
    if state == 'disabled':
        spinbox.config(state='disabled')

# Get the next image and update history
def next_image():
    if limit_cb_var.get() and images_shown_var.get() >= spinbox_var.get():
        tk.messagebox.showinfo(message="End of limit")
        images_shown_var.set(0)  # Reset shown image count after limit reached
    else:
        if random_cb_var.get():
            if not random_order:  # Refill the list if all random images were shown
                random_order[:] = random.sample(file_list, len(file_list))
            next_img = random_order.pop()
        else:
            next_img = file_list[(images_shown_var.get()) % len(file_list)]

        history.append(next_img)
        images_shown_var.set(len(history))  # Update images shown so far count
        show_image(next_img[1])

# Get the previous image from history
def previous_image():
    if history:
        # Go back twice and then append because the current image is also in history
        history.pop()
        if history:
            prev_img = history.pop()
            history.append(prev_img)
            images_shown_var.set(len(history))  # Update the count
            show_image(prev_img[1])
        else:
            # If no previous image is left, cycle back to the end of the history
            if file_list:
                prev_img = file_list[-1]
                history.append(prev_img)
                images_shown_var.set(len(history))  # Update the count
                show_image(prev_img[1])

# Display image file name
def show_image(filename):
    img_label.config(text=f"Image: {filename}")

# Main tkinter window setup
root = tk.Tk()
root.title('Image Viewer')

# Variables
total_number_var = tk.IntVar(value=0)
images_shown_var = tk.IntVar(value=0)
spinbox_var = tk.IntVar(value=5)
random_cb_var = tk.BooleanVar(value=False)
limit_cb_var = tk.BooleanVar(value=False)
file_list = []
random_order = []
history = []

# Buttons
open_button = tk.Button(root, text="Open Image", command=open_folder)
open_button.pack(side='top', fill='x')

next_button = tk.Button(root, text="Next Image", command=next_image, state='disabled')
next_button.pack(side='top')

prev_button = tk.Button(root, text="Previous Image", command=previous_image, state='disabled')
prev_button.pack(side='top')

# Checkboxes and Spinbox
random_cb = tk.Checkbutton(root, text="Random", variable=random_cb_var, state='disabled')
random_cb.pack(side='top')

limit_cb = tk.Checkbutton(root, text="Limit", variable=limit_cb_var, state='disabled', command=lambda: spinbox.config(state='normal' if limit_cb_var.get() else 'disabled'))
limit_cb.pack(side='top')

spinbox = tk.Spinbox(root, from_=1, to=100, wrap=True, textvariable=spinbox_var, state='disabled')
spinbox.pack(side='top')

# Labels
total_label = tk.Label(root, text="Total Images: ")
total_label.pack(side='top')

total_number_label = tk.Label(root, textvariable=total_number_var)
total_number_label.pack(side='top')

images_shown_label = tk.Label(root, text="Images shown so far: ")
images_shown_label.pack(side='top')

images_shown_number_label = tk.Label(root, textvariable=images_shown_var)
images_shown_number_label.pack(side='top')

img_label = tk.Label(root, text="No image selected")
img_label.pack(side='top', pady=20)

# Run the GUI
root.mainloop()


when the previous button reach the first image, make it call the previous image in the folder so it's not stuck. and add those images to the top of the history pool, so i can press next from there on the list.
so example in a folder of 10 images: show 1,2,3,4,5, if i press previous on 5 it'll show 1,2,3,4,5,4,3,2,1,10,9 
and the pool in the example would be from 1,2,3,4,5 to 10,9,1,2,3,4,5

make the next button call for the next img to be the next one in the pool until it reached the end of the pool, then add the next image in the folder or if the random funtion is on, call for random images to be added in the pool

in the example if random is off : 10,9,1,2,3,4,5,6,7,8
it'll show : 1,2,3,4,5,4,3,2,1,10,9,1,2,3,4,5,6,7,8
so if the random is on then, the pool would be like 10,9,1,2,3,4,5,6,7,8,1(random),4(random),3(random) (the last three number is random)
and it'll show 
it'll show : 1,2,3,4,5,4,3,2,1,10,9,1,2,3,4,5,6,7,8,1,4,3


now fix the limit. make the img count reset after every (limit value), so it just show the message after every 5 image if i keep pressing next. so that it's doesn't keep calling the message if i enable the limit when img count is already 6 and