<?php
/**
 * SURFACE GRID — The 32x32 Lattice
 * 
 * What HOLDS. The invariant operational backbone.
 * 27 active dimensions within a 32-dimensional containment matrix.
 * PDTC = 0.84375 is the shape it holds.
 */
class SurfaceGrid
{
    public int $size;
    public int $active;
    public int $void;
    public float $pdtc;
    public float $delta_omega;

    private array $grid;
    private array $ma_gaps;

    public function __construct(array $constants)
    {
        $this->size = $constants['grid_size'];
        $this->active = $constants['active_dims'];
        $this->void = $constants['void_dims'];
        $this->pdtc = $constants['pdtc'];
        $this->delta_omega = $constants['delta_omega'];

        // Initialize the 32x32 grid with void slots at Ma gap positions
        $this->grid = array_fill(0, $this->size, array_fill(0, $this->size, 0.0));
        $this->ma_gaps = $this->computeMaGaps();
        $this->activateGrid();
    }

    /**
     * Compute the 5 Ma gap positions — the void dimensions.
     * Pattern: active/void interleaved to prevent chromatic bleeding.
     * 11011 (27) active field density within the 32-dim matrix.
     */
    private function computeMaGaps(): array
    {
        $gap = $this->void;
        $total = $this->size;
        $gaps = [];
        
        // Distribute 5 void slots evenly across 32 dimensions
        // Positions: 5, 11, 17, 23, 29 (spaced by 6, with edge wrap)
        $spacing = intdiv($total, $gap + 1);
        for ($i = 1; $i <= $gap; $i++) {
            $gaps[] = $i * $spacing - 1; // 0-indexed
        }

        return $gaps;
    }

    /**
     * Activate grid cells. Void dimensions remain zero (ghost slots).
     */
    private function activateGrid(): void
    {
        for ($x = 0; $x < $this->size; $x++) {
            for ($y = 0; $y < $this->size; $y++) {
                $dim = $x; // dimension index along x-axis
                
                if (in_array($dim, $this->ma_gaps)) {
                    $this->grid[$x][$y] = 0.0; // void
                } else {
                    // PDTC-weighted activation
                    $this->grid[$x][$y] = $this->pdtc;
                }
            }
        }
    }

    /**
     * Check if a coordinate pair falls within an active dimension.
     */
    public function isActive(int $x, int $y): bool
    {
        return !in_array($x, $this->ma_gaps) && 
               $x >= 0 && $x < $this->size && 
               $y >= 0 && $y < $this->size;
    }

    /**
     * Get the energy at a point on the grid.
     */
    public function getEnergy(int $x, int $y): float
    {
        if (!$this->isActive($x, $y)) {
            return 0.0;
        }
        return $this->grid[$x][$y];
    }

    /**
     * Set energy at a point — only within PDTC tolerance.
     */
    public function setEnergy(int $x, int $y, float $energy): bool
    {
        if (!$this->isActive($x, $y)) {
            return false;
        }

        // Enforce PDTC invariant
        $deviation = abs($energy - $this->pdtc);
        if ($deviation > $this->delta_omega) {
            return false; // Would break the lattice
        }

        $this->grid[$x][$y] = $energy;
        return true;
    }

    /**
     * Locate a resonant point — find nearest active cell to a target energy.
     */
    public function locateResonance(float $targetEnergy): ?array
    {
        $bestDist = PHP_FLOAT_MAX;
        $best = null;

        for ($x = 0; $x < $this->size; $x++) {
            for ($y = 0; $y < $this->size; $y++) {
                if (!$this->isActive($x, $y)) continue;
                
                $dist = abs($this->grid[$x][$y] - $targetEnergy);
                if ($dist < $bestDist) {
                    $bestDist = $dist;
                    $best = [$x, $y, $this->grid[$x][$y]];
                }
            }
        }

        return $best;
    }

    /**
     * Get the binary density map: 11011...
     */
    public function getDensityMap(): string
    {
        $map = '';
        for ($x = 0; $x < $this->size; $x++) {
            $map .= in_array($x, $this->ma_gaps) ? '' : '1';
        }
        return $map;
    }

    /**
     * Get Ma gap positions.
     */
    public function getMaGaps(): array
    {
        return $this->ma_gaps;
    }

    /**
     * Serialize the grid state.
     */
    public function serialize(): array
    {
        return [
            'size' => $this->size,
            'active_dims' => $this->active,
            'void_dims' => $this->void,
            'pdtc' => $this->pdtc,
            'delta_omega' => $this->delta_omega,
            'density_map' => $this->getDensityMap(),
            'ma_gaps' => $this->ma_gaps,
            'grid_hash' => md5(serialize($this->grid)),
        ];
    }
}
