import tkinter as tk
from tkinter import ttk
from PIL import Image, ImageTk
import threading
import numpy as np
import generate  # your mandelbrot_numba / generate_mandelbrot module

class MandelbrotApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Mandelbrot Viewer")

        self.frame = ttk.Frame(root)
        self.frame.pack(fill=tk.BOTH, expand=True)

        self.canvas = tk.Canvas(self.frame, bg="black", scrollregion=(0, 0, 2000, 2000))
        self.hbar = ttk.Scrollbar(self.frame, orient=tk.HORIZONTAL, command=self.canvas.xview)
        self.vbar = ttk.Scrollbar(self.frame, orient=tk.VERTICAL, command=self.canvas.yview)
        self.canvas.config(xscrollcommand=self.hbar.set, yscrollcommand=self.vbar.set)

        self.hbar.pack(side=tk.BOTTOM, fill=tk.X)
        self.vbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        # Mandelbrot view window
        self.xmin, self.xmax = -2.0, 1.0
        self.ymin, self.ymax = -1.5, 1.5
        self.zoom_factor = 1.0
        self.image_on_canvas = None

        self.render_image()

        # Mouse bindings
        self.canvas.bind("<MouseWheel>", self.zoom)
        self.canvas.bind("<Button-1>", self.drag_start)
        self.canvas.bind("<B1-Motion>", self.drag_motion)

    def render_image(self):
        width, height = 800, 600
        max_iter = 200

        def render_task():
            # Generate the Mandelbrot array
            img_array = generate.generate_mandelbrot(
                self.xmin, self.xmax, self.ymin, self.ymax,
                width, height, max_iter
            )

            # Convert NumPy array to RGB image
            img_rgb = np.zeros((height, width, 3), dtype=np.uint8)
            img_rgb[:, :, 0] = img_array % 256
            img_rgb[:, :, 1] = (img_array * 2) % 256
            img_rgb[:, :, 2] = (img_array * 3) % 256

            # Convert NumPy array → PIL Image → ImageTk.PhotoImage
            img = Image.fromarray(img_rgb)
            self.tk_img = ImageTk.PhotoImage(img)

            # Update canvas
            self.canvas.delete("all")
            self.image_on_canvas = self.canvas.create_image(0, 0, anchor=tk.NW, image=self.tk_img)
            self.canvas.config(scrollregion=(0, 0, width, height))

        threading.Thread(target=render_task, daemon=True).start()

    def zoom(self, event):
        zoom_amount = 0.9 if event.delta > 0 else 1.1
        self.zoom_factor *= zoom_amount
        center_x = (self.xmin + self.xmax) / 2
        center_y = (self.ymin + self.ymax) / 2
        width = (self.xmax - self.xmin) * zoom_amount
        height = (self.ymax - self.ymin) * zoom_amount
        self.xmin, self.xmax = center_x - width / 2, center_x + width / 2
        self.ymin, self.ymax = center_y - height / 2, center_y + height / 2
        self.render_image()

    def drag_start(self, event):
        self.last_x, self.last_y = event.x, event.y

    def drag_motion(self, event):
        dx = event.x - self.last_x
        dy = event.y - self.last_y
        x_shift = (self.xmax - self.xmin) * dx / 800
        y_shift = (self.ymax - self.ymin) * dy / 600
        self.xmin -= x_shift
        self.xmax -= x_shift
        self.ymin += y_shift
        self.ymax += y_shift
        self.last_x, self.last_y = event.x, event.y
        self.render_image()

if __name__ == "__main__":
    root = tk.Tk()
    app = MandelbrotApp(root)
    root.mainloop()
