import math
import time
import os
import msvcrt

# --- HDGL Machine ---
class HDGLMachine:
    def __init__(self):
        self.upper_field = {"phi": 1.6180339887, "phi_power_phi": 2.6180339887, "pi": 3.1415926535, "P3": 4.2360679775}
        self.analog_dims = {"dim_switch": 1.0, "P7": 29.0344465435}
        self.lower_field = {"inv_phi": 0.6180339887, "inv_P3": 0.2360679775}
        self.void = 0.0
        self.current_state = self.void
        self.dimension = self.analog_dims["dim_switch"]
        self.recursion_active = False
        self.seed = 0.0

    def toggle_recursion(self):
        self.recursion_active = not self.recursion_active
        print(f"Recursion: {'ON' if self.recursion_active else 'OFF'}")

    # Compute multiple channel states
    def compute_channels(self, t):
        phi = self.upper_field["phi"]
        phi_phi = self.upper_field["phi_power_phi"]
        P3 = self.upper_field["P3"]
        P7 = self.analog_dims["P7"]

        phi_val = phi * math.sin(t*phi)
        phi_phi_val = phi_phi * math.sin(t*phi_phi)
        P3_val = P3 * math.sin(t*P3)
        rec_val = (phi*math.sin(t*phi) + phi_phi*math.cos(t*phi_phi))
        if self.recursion_active:
            rec_val *= P7/P3
        return {"phi": phi_val, "phi_phi": phi_phi_val, "P3": P3_val, "recursion": rec_val}

# --- Polar ASCII Dot Field ---
class PolarHDGLVisualizer:
    def __init__(self, machine, width=80, height=40, radius_max=18, points_per_frame=5):
        self.machine = machine
        self.width = width
        self.height = height
        self.radius_max = radius_max
        self.time = 0.0
        self.dt = 0.05
        self.history = [[' ']*self.width for _ in range(self.height)]
        self.points_per_frame = points_per_frame

    def render(self, channels):
        grid = [[' ']*self.width for _ in range(self.height)]
        center_x = self.width // 2
        center_y = self.height // 2

        min_val, max_val = -500, 500

        # Plot multiple points per frame for each channel
        for name, val in channels.items():
            r = int((val - min_val) / (max_val - min_val) * self.radius_max)
            r = max(0, min(self.radius_max, r))
            char = '.' if name != "recursion" else '*'  # recursion channel highlights

            for i in range(self.points_per_frame):
                theta = self.time*0.1 + i*0.2 + hash(name)%10*0.01
                x = int(center_x + r * math.cos(theta))
                y = int(center_y + r * math.sin(theta))
                if 0 <= x < self.width and 0 <= y < self.height:
                    grid[y][x] = char

        # Keep previous points to simulate trailing waveform
        for y in range(self.height):
            for x in range(self.width):
                if self.history[y][x] != ' ' and grid[y][x] == ' ':
                    grid[y][x] = self.history[y][x]

        self.history = grid
        return grid

    def display(self, grid):
        os.system('cls')
        for row in grid:
            print(''.join(row))

    def run(self):
        print("Controls: 'r' = toggle recursion, Ctrl+C = quit")
        try:
            while True:
                channels = self.machine.compute_channels(self.time)
                grid = self.render(channels)
                self.display(grid)
                self.time += self.dt

                # Windows keypress detection
                if msvcrt.kbhit():
                    key = msvcrt.getch()
                    if key.lower() == b'r':
                        self.machine.toggle_recursion()

                time.sleep(self.dt)
        except KeyboardInterrupt:
            print("\nExiting Polar HDGL Dot Stethoscope.")

# --- Run ---
if __name__ == "__main__":
    machine = HDGLMachine()
    vis = PolarHDGLVisualizer(machine)
    vis.run()
