import tkinter as tk
from tkinter import ttk
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import numpy as np
import math
import re

from mpl_toolkits.mplot3d import Axes3D

matplotlib.use("TkAgg")

# --- HDGL Machine ---
class HDGLMachine:
    def __init__(self):
        # Upper Field
        self.upper_field = {
            "prism_state": 105.0,
            "recursion_mode": False,
        }

        # Middle Field
        self.middle_field = {
            "glyph_count": 0,
            "frequency": 1.0,
        }

        # Lower Field
        self.lower_field = {
            "phase": 0.0,
            "amplitude": 1.0,
        }

    def step(self, t):
        # Example update logic
        self.middle_field["glyph_count"] = int(abs(math.sin(t)) * 10)
        self.lower_field["phase"] = math.sin(t)
        self.lower_field["amplitude"] = 0.5 + 0.5 * math.cos(t)
        return self.get_state()

    def get_state(self):
        return {
            "prism": self.upper_field["prism_state"],
            "recursion": self.upper_field["recursion_mode"],
            "glyphs": self.middle_field["glyph_count"],
            "freq": self.middle_field["frequency"],
            "phase": self.lower_field["phase"],
            "amp": self.lower_field["amplitude"],
        }

# --- GUI ---
class HDGLApp:
    def __init__(self, root):
        self.root = root
        self.root.title("HDGL Environment Visualizer")

        self.machine = HDGLMachine()

        # Matplotlib figure
        self.fig = plt.Figure(figsize=(6, 6))
        self.ax = self.fig.add_subplot(111, projection='3d')
        self.canvas = matplotlib.backends.backend_tkagg.FigureCanvasTkAgg(self.fig, master=root)
        self.canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True)

        # Animation
        self.ani = animation.FuncAnimation(self.fig, self.update_plot, interval=100)

    def update_plot(self, frame):
        state = self.machine.step(frame * 0.1)

        # Clear axes
        self.ax.cla()
        self.ax.set_xlim(-2, 2)
        self.ax.set_ylim(-2, 2)
        self.ax.set_zlim(-2, 2)

        # Generate some pseudo-environment points
        theta = np.linspace(0, 2*np.pi, 50)
        phi = np.linspace(0, np.pi, 25)
        theta, phi = np.meshgrid(theta, phi)

        r = 1 + 0.2 * np.sin(state["phase"] * theta)

        x = r * np.sin(phi) * np.cos(theta)
        y = r * np.sin(phi) * np.sin(theta)
        z = r * np.cos(phi)

        # Flatten arrays
        x = x.flatten()
        y = y.flatten()
        z = z.flatten()

        # Sizes and colors
        sizes = np.abs(np.sin(x*y + state["phase"])) * 50
        sizes = np.array(sizes, dtype=float).flatten()

        colors = np.cos(z + state["amp"])
        colors = np.array(colors, dtype=float).flatten()

        # Scatter plot (safe)
        self.ax.scatter(x, y, z, s=sizes, c=colors, cmap="viridis", depthshade=True)

        # Labels
        self.ax.set_title(f"Glyphs: {state['glyphs']} | Recursion: {state['recursion']}")

# --- Run App ---
if __name__ == "__main__":
    root = tk.Tk()
    app = HDGLApp(root)
    root.mainloop()
