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  # calculator input

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

    def compute_channel_state(self, t, channel):
        """Compute individual primitive channel state."""
        phi = self.upper_field["phi"]
        phi_phi = self.upper_field["phi_power_phi"]
        pi = self.upper_field["pi"]
        P3 = self.upper_field["P3"]

        if channel == 'phi':
            return phi * math.sin(t*phi)
        elif channel == 'phi_phi':
            return phi_phi * math.sin(t*phi_phi)
        elif channel == 'P3':
            return P3 * math.sin(t*P3)
        elif channel == 'recursion':
            val = phi * math.sin(t*phi) + phi_phi*math.cos(t*phi_phi)
            return val * (self.analog_dims["P7"]/self.lower_field["inv_P3"]) if self.recursion_active else val
        else:
            return 0.0

# --- Multi-channel Polar ASCII Hologram ---
class MultiChannelVisualizer:
    def __init__(self, machine, width=80, height=40, radius_max=20):
        self.machine = machine
        self.width = width
        self.height = height
        self.radius_max = radius_max
        self.time = 0.0
        self.dt = 0.05
        self.channels = ['phi','phi_phi','P3','recursion']
        self.history = [[' ']*self.width for _ in range(self.height)]

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

        for ch in self.channels:
            val = self.machine.compute_channel_state(self.time, ch)
            min_val, max_val = -500, 500
            r = int((val - min_val)/(max_val-min_val)*self.radius_max)
            r = max(0, min(self.radius_max, r))

            theta = self.time*2*math.pi + hash(ch)%10*0.1  # slight phase offset per channel
            x = int(center_x + r*math.cos(theta))
            y = int(center_y + r*math.sin(theta))

            char_map = {'phi': '.', 'phi_phi': ',', 'P3': 'o', 'recursion':'*'}
            char = char_map.get(ch,'.')

            if 0<=x<self.width and 0<=y<self.height:
                grid[y][x] = char

        # Merge with previous frame to retain “trails”
        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("Press 'r' to toggle recursion. Ctrl+C to quit.")
        try:
            while True:
                grid = self.render()
                self.display(grid)
                self.time += self.dt

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

                time.sleep(self.dt)
        except KeyboardInterrupt:
            print("\nExiting Multi-Channel HDGL Hologram.")

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