import tkinter as tk
from tkinter import PhotoImage, messagebox, filedialog
import json
import sys

class Tooltip:
    """Create a tooltip for a given widget."""
    def __init__(self, widget, text='widget info'):
        self.widget = widget
        self.text = text
        self.tipwindow = None
        self.id = None
        self.x = self.y = 0
        self.widget.bind("<Enter>", self.showtip)
        self.widget.bind("<Leave>", self.hidetip)

    def showtip(self, event=None):
        "Display text in tooltip window"
        if self.tipwindow or not self.text:
            return
        x, y, _cx, cy = self.widget.bbox("insert")
        x = x + self.widget.winfo_rootx() + 25
        y = y + cy + self.widget.winfo_rooty() + 25
        self.tipwindow = tw = tk.Toplevel(self.widget)
        tw.wm_overrideredirect(True)
        tw.wm_geometry(f"+{x}+{y}")
        label = tk.Label(tw, text=self.text, justify=tk.LEFT,
                         background="#ffffe0", relief=tk.SOLID, borderwidth=1,
                         font=("tahoma", "8", "normal"))
        label.pack(ipadx=1)

    def hidetip(self, event=None):
        "Hide the tooltip window"
        tw = self.tipwindow
        self.tipwindow = None
        if tw:
            tw.destroy()

class ToolbarApp:
    def __init__(self, root):
        self.root = root
        self.root.title("BOB CAD")
        self.root.geometry("800x600")

        self.active_buttons = {}
        self.work_areas = []
        self.work_area_names = set()
        self.selected_bottom_button = None

        # UI Configuration
        self.toolbar = tk.Frame(root, bd=1, relief=tk.RAISED)
        self.toolbar.pack(side=tk.TOP, fill=tk.X)

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

        self.bottom_toolbar = tk.Frame(root, bd=1, relief=tk.RAISED)
        self.bottom_toolbar.pack(side=tk.BOTTOM, fill=tk.X)

        self.extra_buttons_frame = None
        self.current_work_area = None
        self.hbar = tk.Scrollbar(self.root, orient=tk.HORIZONTAL)
        self.hbar.pack(side=tk.BOTTOM, fill=tk.X)

        self.create_toolbar_buttons()

    def create_toolbar_buttons(self):
        button_files = [
            "button_model.json",
            "button_pieces.json",
            "button_modify.json",
            "button_construction.json",
            "button_industrialization.json",
            "button_grading.json",
            "button_measurements.json",
            "button_settings.json",
            "button_help.json",
            "button_about.json"
        ]

        for button_file in button_files:
            settings = self.load_button_settings(button_file)
            if settings:
                text = settings.get("text")
                color = settings.get("color", "pink")
                subbuttons = settings.get("subbuttons", [])
                icon_path = settings.get("icon", None)
                tooltip_text = settings.get("tooltip", "")

                icon = None
                if icon_path:
                    try:
                        icon = PhotoImage(file=icon_path)
                    except Exception as e:
                        messagebox.showerror("Error", f"Cannot load icon {icon_path}: {e}")
                        print(f"Error: Cannot load icon {icon_path}: {e}", file=sys.stderr)

                main_button = tk.Button(
                    self.toolbar, text=text, relief=tk.FLAT, image=icon, compound=tk.LEFT,
                    width=20, font=("Arial", 10), bg=color, activebackground='grey',
                    command=lambda txt=text, sb=subbuttons: self.toggle_subbuttons(txt, sb)
                )
                main_button.image = icon
                main_button.pack(side=tk.LEFT, padx=2, pady=2)

                Tooltip(main_button, tooltip_text)

                self.active_buttons[text] = False

    def load_button_settings(self, file_name):
        try:
            with open(file_name, 'r') as file:
                return json.load(file)
        except FileNotFoundError:
            messagebox.showerror("Error", f"Cannot find settings file {file_name}!")
            print(f"Error: Cannot find settings file {file_name}!", file=sys.stderr)
            return {}
        except json.JSONDecodeError as e:
            messagebox.showerror("Error", f"Error decoding JSON in file {file_name}: {e}")
            print(f"Error: Error decoding JSON in file {file_name}: {e}", file=sys.stderr)
            return {}

    def toggle_subbuttons(self, button_text, subbuttons):
        if self.active_buttons.get(button_text, False):
            self.hide_subbuttons()
        else:
            self.hide_subbuttons()
            self.show_subbuttons(subbuttons)
            self.active_buttons[button_text] = True

    def hide_subbuttons(self):
        if self.extra_buttons_frame:
            self.extra_buttons_frame.place_forget()
            self.extra_buttons_frame = None
        for key in self.active_buttons:
            self.active_buttons[key] = False

    def show_subbuttons(self, subbuttons):
        self.extra_buttons_frame = tk.Frame(self.main_frame, bg="lightgrey", bd=1, relief=tk.RAISED)
        for subbutton in subbuttons:
            sub_text = subbutton.get("text")
            sub_color = subbutton.get("color", "lightgrey")
            tooltip_text = subbutton.get("tooltip", "")

            button = tk.Button(
                self.extra_buttons_frame, text=sub_text, relief=tk.FLAT, bg=sub_color, width=20, font=("Arial", 8),
                command=lambda txt=sub_text: self.subbutton_action(txt)
            )
            button.pack(side=tk.TOP, anchor="w", pady=2)

            Tooltip(button, tooltip_text)

        self.extra_buttons_frame.place(relx=0, rely=0, anchor="nw")

    def subbutton_action(self, subbutton_text):
        if subbutton_text == "Nou":
            self.create_new_work_area()
            self.hide_subbuttons()
        elif subbutton_text == "Salveaza":
            self.save_work_areas()
        elif subbutton_text == "Incarca":
            self.load_work_areas()

    def create_new_work_area(self):
        work_area_name = f"Model{len(self.work_areas) + 1}"
        while work_area_name in self.work_area_names:
            work_area_name = f"Model{len(self.work_areas) + 1}"

        if self.current_work_area:
            self.current_work_area.pack_forget()

        pleasant_color = "#e6ffe6"
        highlight_color = "#ccffcc"

        new_work_area = tk.Frame(self.main_frame, bg=pleasant_color)
        new_work_area.pack(side=tk.TOP, fill=tk.BOTH, expand=True)

        canvas = tk.Canvas(new_work_area, bg=pleasant_color, scrollregion=(0, 0, 10000, 10000))
        canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        vbar = tk.Scrollbar(new_work_area, orient=tk.VERTICAL, command=canvas.yview)
        vbar.pack(side=tk.RIGHT, fill=tk.Y)

        self.hbar.config(command=canvas.xview)
        canvas.config(xscrollcommand=self.hbar.set, yscrollcommand=vbar.set)

        self.current_work_area = new_work_area
        self.work_areas.append(new_work_area)
        self.work_area_names.add(work_area_name)

        # Crearea butonului în bara de jos
        toolbar_button = tk.Button(
            self.bottom_toolbar, text=work_area_name, width=10,
            command=lambda wa=new_work_area: self.switch_to_work_area(wa, toolbar_button)
        )
        toolbar_button.pack(side=tk.LEFT, padx=2, pady=2)

        self.show_creation_message(work_area_name)
        self.pulse_animation(new_work_area, pleasant_color, highlight_color, 0)

    def show_creation_message(self, name):
        messagebox.showinfo("Model Creat", f"Noul model '{name}' a fost creat cu succes!")

    def pulse_animation(self, widget, color1, color2, count):
        if count < 6:  # Pulse 3 times (alternating colors)
            next_color = color1 if count % 2 == 0 else color2
            widget.config(bg=next_color)
            self.root.after(200, self.pulse_animation, widget, color1, color2, count + 1)

    def switch_to_work_area(self, work_area, button):
        if self.current_work_area:
            self.current_work_area.pack_forget()
        work_area.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
        self.current_work_area = work_area
        self.hide_subbuttons()

        # Reseteaza culoarea butonului anterior selectat
        if self.selected_bottom_button:
            self.selected_bottom_button.config(bg="lightgrey")
        
        # Schimba culoarea butonului curent selectat
        button.config(bg="lightblue")
        self.selected_bottom_button = button

    def save_work_areas(self):
        data = []
        for i, work_area in enumerate(self.work_areas):
            work_area_name = f"Model{i + 1}"
            data.append({
                "name": work_area_name,
                "content": self.get_canvas_content(work_area)
            })

        file_path = filedialog.asksaveasfilename(defaultextension=".json", filetypes=[("JSON files", "*.json")])
        if file_path:
            with open(file_path, 'w') as file:
                json.dump(data, file)
            messagebox.showinfo("Salvat", f"Work areas salvate in {file_path}!")

    def get_canvas_content(self, work_area):
        canvas = work_area.winfo_children()[0]
        items = canvas.find_all()
        content = []
        for item in items:
            content.append({
                "type": canvas.type(item),
                "coords": canvas.coords(item),
                "tags": canvas.gettags(item),
                "options": canvas.itemconfig(item)
            })
        return content

    def load_work_areas(self):
        file_path = filedialog.askopenfilename(filetypes=[("JSON files", "*.json")])
        if file_path:
            with open(file_path, 'r') as file:
                data = json.load(file)
            for entry in data:
                work_area_name = entry["name"]
                if work_area_name in self.work_area_names:
                    continue

                pleasant_color = "#e6ffe6"
                highlight_color = "#ccffcc"

                new_work_area = tk.Frame(self.main_frame, bg=pleasant_color)
                new_work_area.pack(side=tk.TOP, fill=tk.BOTH, expand=True)

                canvas = tk.Canvas(new_work_area, bg=pleasant_color, scrollregion=(0, 0, 10000, 10000))
                canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

                vbar = tk.Scrollbar(new_work_area, orient=tk.VERTICAL, command=canvas.yview)
                vbar.pack(side=tk.RIGHT, fill=tk.Y)

                self.hbar.config(command=canvas.xview)
                canvas.config(xscrollcommand=self.hbar.set, yscrollcommand=vbar.set)

                self.current_work_area = new_work_area
                self.work_areas.append(new_work_area)
                self.work_area_names.add(work_area_name)

                # Crează un buton nou în bara de jos cu denumirea modelului
                toolbar_button = tk.Button(
                    self.bottom_toolbar, text=work_area_name, width=10,
                    command=lambda wa=new_work_area: self.switch_to_work_area(wa, toolbar_button)
                )
                toolbar_button.pack(side=tk.LEFT, padx=2, pady=2)

                self.set_canvas_content(canvas, entry["content"])

                self.show_creation_message(work_area_name)
                self.pulse_animation(new_work_area, pleasant_color, highlight_color, 0)

    def set_canvas_content(self, canvas, content):
        for item in content:
            item_type = item["type"]
            coords = item["coords"]
            tags = item["tags"]
            options = item["options"]

            if item_type == "rectangle":
                canvas.create_rectangle(*coords, **{k: v[-1] for k, v in options.items()})
            elif item_type == "oval":
                canvas.create_oval(*coords, **{k: v[-1] for k, v in options.items()})
            # Adăugați aici și alte tipuri de elemente, dacă este necesar

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