"""
Interactive Region Coordinate Helper
Opens an image and helps you find pixel coordinates for colorable regions.
Click on the image to see coordinates.

Usage:
    python region_helper.py images/cobrai.jpg
"""

import sys
from PIL import Image, ImageDraw, ImageFont
import tkinter as tk
from tkinter import Canvas
from PIL import ImageTk


class RegionHelper:
    def __init__(self, image_path):
        self.image_path = image_path
        self.image = Image.open(image_path)
        self.width, self.height = self.image.size
        
        # Setup UI
        self.root = tk.Tk()
        self.root.title(f"Region Helper - {image_path}")
        
        # Scale image if too large
        self.scale = 1.0
        max_display_width = 1000
        max_display_height = 800
        
        if self.width > max_display_width or self.height > max_display_height:
            scale_w = max_display_width / self.width
            scale_h = max_display_height / self.height
            self.scale = min(scale_w, scale_h)
            
            new_width = int(self.width * self.scale)
            new_height = int(self.height * self.scale)
            self.display_image = self.image.resize((new_width, new_height), Image.LANCZOS)
        else:
            self.display_image = self.image.copy()
        
        # Setup canvas
        self.canvas = Canvas(
            self.root, 
            width=self.display_image.width, 
            height=self.display_image.height
        )
        self.canvas.pack(side=tk.LEFT)
        
        # Display image
        self.photo = ImageTk.PhotoImage(self.display_image)
        self.canvas.create_image(0, 0, anchor=tk.NW, image=self.photo)
        
        # Info panel
        info_frame = tk.Frame(self.root, width=300)
        info_frame.pack(side=tk.RIGHT, fill=tk.BOTH, padx=10, pady=10)
        
        tk.Label(info_frame, text="Image Dimensions:", font=('Arial', 12, 'bold')).pack(anchor=tk.W, pady=5)
        tk.Label(info_frame, text=f"{self.width} x {self.height} pixels").pack(anchor=tk.W)
        
        if self.scale != 1.0:
            tk.Label(info_frame, text=f"Scaled: {self.scale:.2%}").pack(anchor=tk.W)
        
        tk.Label(info_frame, text="\nClick to get coordinates:", font=('Arial', 12, 'bold')).pack(anchor=tk.W, pady=(20, 5))
        
        self.coord_label = tk.Label(info_frame, text="X: -, Y: -", font=('Arial', 14))
        self.coord_label.pack(anchor=tk.W, pady=5)
        
        tk.Label(info_frame, text="\nFirst click = Top-Left", fg='blue').pack(anchor=tk.W)
        tk.Label(info_frame, text="Second click = Bottom-Right", fg='blue').pack(anchor=tk.W)
        
        tk.Label(info_frame, text="\nRegion JSON:", font=('Arial', 12, 'bold')).pack(anchor=tk.W, pady=(20, 5))
        
        self.json_text = tk.Text(info_frame, height=15, width=35, font=('Courier', 9))
        self.json_text.pack(fill=tk.BOTH, expand=True)
        
        tk.Button(info_frame, text="Clear Points", command=self.clear_points).pack(pady=10)
        tk.Button(info_frame, text="Copy JSON", command=self.copy_json).pack()
        
        # Bind events
        self.canvas.bind('<Motion>', self.on_mouse_move)
        self.canvas.bind('<Button-1>', self.on_click)
        
        # Store points
        self.points = []
        self.point_ids = []
        
        self.update_json()
        
    def on_mouse_move(self, event):
        """Show current mouse coordinates."""
        x = int(event.x / self.scale)
        y = int(event.y / self.scale)
        self.coord_label.config(text=f"X: {x}, Y: {y}")
    
    def on_click(self, event):
        """Record clicked point."""
        x = int(event.x / self.scale)
        y = int(event.y / self.scale)
        
        # Limit to 2 points (top-left, bottom-right)
        if len(self.points) >= 2:
            self.clear_points()
        
        self.points.append((x, y))
        
        # Draw point on canvas
        color = 'blue' if len(self.points) == 1 else 'red'
        point_id = self.canvas.create_oval(
            event.x - 5, event.y - 5,
            event.x + 5, event.y + 5,
            fill=color, outline='white', width=2
        )
        self.point_ids.append(point_id)
        
        # Draw rectangle if we have both points
        if len(self.points) == 2:
            x1, y1 = self.points[0]
            x2, y2 = self.points[1]
            
            # Draw on canvas (scaled)
            rect_id = self.canvas.create_rectangle(
                x1 * self.scale, y1 * self.scale,
                x2 * self.scale, y2 * self.scale,
                outline='green', width=2, dash=(5, 5)
            )
            self.point_ids.append(rect_id)
        
        self.update_json()
    
    def clear_points(self):
        """Clear all points and rectangles."""
        for point_id in self.point_ids:
            self.canvas.delete(point_id)
        
        self.points = []
        self.point_ids = []
        self.update_json()
    
    def update_json(self):
        """Update the JSON display."""
        self.json_text.delete('1.0', tk.END)
        
        if len(self.points) == 0:
            self.json_text.insert('1.0', '{\n  "name": "region_name",\n  "topLeft": [?, ?],\n  "bottomRight": [?, ?],\n  "description": "..."\n}')
        elif len(self.points) == 1:
            x, y = self.points[0]
            self.json_text.insert('1.0', f'{{\n  "name": "region_name",\n  "topLeft": [{x}, {y}],\n  "bottomRight": [?, ?],\n  "description": "..."\n}}')
        else:
            x1, y1 = self.points[0]
            x2, y2 = self.points[1]
            
            # Calculate dimensions
            width = abs(x2 - x1)
            height = abs(y2 - y1)
            
            json_str = f'''{{\n  "name": "region_name",\n  "topLeft": [{x1}, {y1}],\n  "bottomRight": [{x2}, {y2}],\n  "description": "Width: {width}px, Height: {height}px"\n}}'''
            self.json_text.insert('1.0', json_str)
    
    def copy_json(self):
        """Copy JSON to clipboard."""
        json_str = self.json_text.get('1.0', tk.END).strip()
        self.root.clipboard_clear()
        self.root.clipboard_append(json_str)
        self.root.update()
    
    def run(self):
        """Start the GUI."""
        self.root.mainloop()


if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage: python region_helper.py <image_path>")
        print("Example: python region_helper.py images/cobrai.jpg")
        sys.exit(1)
    
    image_path = sys.argv[1]
    
    try:
        helper = RegionHelper(image_path)
        helper.run()
    except FileNotFoundError:
        print(f"Error: Image file not found: {image_path}")
        sys.exit(1)
    except Exception as e:
        print(f"Error: {e}")
        sys.exit(1)
