class ImageViewer:
    def __init__(self, root):
        self.grid_button = tk.Button(self.main_frame, text="#", command=self.toggle_grid)
        self.grid_button.configure(**self.button_style_disabled, width=self.button_width)
        self.grid_button.pack(side=tk.LEFT, padx=(1,0), pady=0)
        ToolTip(self.grid_button, msg="Toggle grid", follow=True, 
        **self.tooltip_color)

    def toggle_grid(self):
        grid_types = ["a", "b", "c", "d"]
        
        if not hasattr(self, "grid_type"):
            self.grid_type = grid_types[0]
        else:
            current_index = grid_types.index(self.grid_type)
            next_index = (current_index + 1) % len(grid_types)
            self.grid_type = grid_types[next_index]
        self.display_image()

    def draw_grid(self, grid_type, image_width, image_height):
        # Calculate center position to center the grid on the image
        canvas_width = self.canvas.winfo_width()
        canvas_height = self.canvas.winfo_height()
        x_center = canvas_width // 2
        y_center = canvas_height // 2

        # Calculate the top-left corner position of the image
        x_start = x_center - (image_width // 2)
        y_start = y_center - (image_height // 2)
        grid_color = "grey"
        if grid_type == "a":
            # Draw a simple 3x3 grid
            for i in range(1, 3):
                self.canvas.create_line(x_start + image_width * i / 3, y_start, x_start + image_width * i / 3, y_start + image_height, fill=grid_color)
                self.canvas.create_line(x_start, y_start + image_height * i / 3, x_start + image_width, y_start + image_height * i / 3, fill=grid_color)
        elif grid_type == "b":
            # Draw a golden ratio grid
            gr = (1 + 5 ** 0.5) / 2  # golden ratio
            self.canvas.create_line(x_start + image_width / gr, y_start, x_start + image_width / gr, y_start + image_height, fill=grid_color)
            self.canvas.create_line(x_start + image_width - (image_width / gr), y_start, x_start + image_width - (image_width / gr), y_start + image_height, fill=grid_color)
            self.canvas.create_line(x_start, y_start + image_height / gr, x_start + image_width, y_start + image_height / gr, fill=grid_color)
            self.canvas.create_line(x_start, y_start + image_height - (image_height / gr), x_start + image_width, y_start + image_height - (image_height / gr), fill=grid_color)
        elif grid_type == "c":
            # Draw a 4x4 grid
            for i in range(1, 4):
                self.canvas.create_line(x_start + image_width * i / 4, y_start, x_start + image_width * i / 4, y_start + image_height, fill=grid_color)
                self.canvas.create_line(x_start, y_start + image_height * i / 4, x_start + image_width, y_start + image_height * i / 4, fill=grid_color)
        elif grid_type == "d":
            pass

    def load_image(self, image_path):
        image = Image.open(image_path)
        
        # Check if the image has EXIF data
        if "exif" in image.info:
            try:
                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)
            except ValueError as e:
                pass
            
        if self.is_greyscale:
            image = image.convert("L")
    
        if self.is_mirrored:
            image = image.transpose(Image.FLIP_LEFT_RIGHT)
        
        if self.rotated != 0:
            image = image.rotate(self.rotated, expand=True)

        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)

        if self.grid_type:
            self.draw_grid(self.grid_type, new_width, new_height)

instead of setting the button to toggle and cycle the grid. make the button open a dialog window that has 4 radio buttons that says no grid, 4x4, 3x3 and golden ratio. below those radiobuttons, put two spinboxes that sets the grid value for x and y set the value to be between 0 to 20 max on each. when the "no grid", 3x3 and 4x4 radiobuttons is pressed, make it set the values of the x and y spinboxes to it's respective state. when the golden ratio radio button is pressed, show G in X spinbox and R in Y spinbox, below that, add a "disable grid" button that immediately update the grid and disable, add an apply button and an ok button. when i press apply, update the grid without exiting the messagebox, when i press ok, close the message box with the set grid. when i press the grid button it should open the "set grid" window. when i set the grid, and press apply or ok it saves the values for the options i picked. when i press the grid button again, it removes the grid. Then if i press grid button when no grid is shown, it opens the set grid window. if i open the set grid window again, it should remember last setting i set it as initial value.