from tkinter import Frame, Label, Canvas, NW
from typing import Any, Dict, Optional
from PIL import Image, ImageTk


class MyImage(Frame):
    """
    A custom image widget that displays images in a Frame.
    
    This class creates an image display widget that can show images either using a Label
    or a Canvas widget, depending on the configuration. The image is automatically resized
    to fit the specified dimensions.
    
    Attributes:
        width (int): Width of the image display area
        height (int): Height of the image display area
        image (PhotoImage): The tkinter PhotoImage object
        canvas (Optional[Canvas]): The Canvas widget if label=False
    """

    def __init__(
        self,
        parent: Any,
        row: int,
        column: int,
        width: int,
        height: int,
        path_image: str,
        columnspan: int = 2,
        rowspan: int = 1,
        label: bool = False,
        **kwargs
    ) -> None:
        """
        Initialize the MyImage widget.

        Args:
            parent: The parent widget
            row: Row position in the parent's grid
            column: Column position in the parent's grid
            width: Width of the image display area
            height: Height of the image display area
            path_image: Path to the image file to display
            columnspan: Number of columns the widget should span
            rowspan: Number of rows the widget should span
            label: If True, use Label widget; if False, use Canvas widget
            **kwargs: Additional keyword arguments passed to the Frame widget
        """
        super().__init__(
            parent,
            bg="#FFFFFF",
            width=width,
            height=height,
            highlightbackground="black",
            highlightthickness=1,
            padx=5,
            pady=2,
            **kwargs,
        )
        
        self.width = width
        self.height = height
        
        # Open, resize, and create the PhotoImage object
        self.image = ImageTk.PhotoImage(
            Image.open(path_image).resize((int(self.width), int(self.height)))
        )
        
        if label:
            # Use a Label widget to display the image
            label = Label(self, image=self.image)
            label.image = self.image  # keep a reference
            label.pack()
        else:
            # Use a Canvas widget to display the image
            self.canvas = Canvas(self, width=self.width, height=self.height)
            self.canvas.create_image(0, 0, anchor=NW, image=self.image)
            self.canvas.pack()
            
        # Grid the frame into the parent
        self.grid(row=row, column=column, columnspan=columnspan, rowspan=rowspan)

