#ifndef SPHERE_LUT_H
#define SPHERE_LUT_H

#include <Arduino.h>

// Sphere lookup table for 10x10x10 cube
// Data represents one octant (0-4, 0-4, 0-4) for 5 growth iterations
// Use mirroring to create full sphere centered at (4.5, 4.5, 4.5)
// Format: sphereLUT[y][x][z][iteration] = 1 if lit, 0 if dark

const uint8_t SPHERE_ITERATIONS = 4;

// 4D array: [y][x][z][iteration]
// NOTE: Index order is Y, X, Z (not X, Y, Z)
const uint8_t sphereLUT[5][5][5][5] PROGMEM = {
  // y = 0
  {
    // x = 0
    {
      {0, 0, 0, 0, 0},  // z=0: iterations 0,1,2,3,4
      {0, 0, 0, 0, 0},  // z=1
      {0, 0, 0, 0, 0},  // z=2
      {0, 0, 0, 0, 0},  // z=3
      {0, 0, 0, 0, 1}   // z=4
    },
    // x = 1
    {
      {0, 0, 0, 0, 0},  // z=0
      {0, 0, 0, 0, 0},  // z=1
      {0, 0, 0, 0, 1},  // z=2
      {0, 0, 0, 0, 1},  // z=3
      {0, 0, 0, 1, 1}   // z=4
    },
    // x = 2
    {
      {0, 0, 0, 0, 0},  // z=0
      {0, 0, 0, 0, 1},  // z=1
      {0, 0, 0, 0, 1},  // z=2
      {0, 0, 0, 1, 1},  // z=3
      {0, 0, 0, 1, 1}   // z=4
    },
    // x = 3
    {
      {0, 0, 0, 0, 0},  // z=0
      {0, 0, 0, 0, 1},  // z=1
      {0, 0, 0, 1, 1},  // z=2
      {0, 0, 0, 1, 1},  // z=3
      {0, 0, 1, 1, 0}   // z=4
    },
    // x = 4
    {
      {0, 0, 0, 0, 1},  // z=0
      {0, 0, 0, 1, 1},  // z=1
      {0, 0, 0, 1, 1},  // z=2
      {0, 0, 1, 1, 0},  // z=3
      {0, 0, 1, 0, 0}   // z=4
    }
  },
  
  // y = 1
  {
    // x = 0
    {
      {0, 0, 0, 0, 0},  // z=0
      {0, 0, 0, 0, 0},  // z=1
      {0, 0, 0, 0, 1},  // z=2
      {0, 0, 0, 0, 1},  // z=3
      {0, 0, 0, 1, 1}   // z=4
    },
    // x = 1
    {
      {0, 0, 0, 0, 0},  // z=0
      {0, 0, 0, 0, 1},  // z=1
      {0, 0, 0, 1, 1},  // z=2
      {0, 0, 0, 1, 1},  // z=3
      {0, 0, 1, 1, 0}   // z=4
    },
    // x = 2
    {
      {0, 0, 0, 0, 1},  // z=0
      {0, 0, 0, 1, 1},  // z=1
      {0, 0, 0, 1, 1},  // z=2
      {0, 0, 1, 1, 0},  // z=3
      {0, 0, 1, 0, 0}   // z=4
    },
    // x = 3
    {
      {0, 0, 0, 0, 1},  // z=0
      {0, 0, 0, 1, 1},  // z=1
      {0, 0, 1, 1, 0},  // z=2
      {0, 0, 1, 0, 0},  // z=3
      {0, 1, 1, 0, 0}   // z=4
    },
    // x = 4
    {
      {0, 0, 0, 1, 1},  // z=0
      {0, 0, 1, 1, 0},  // z=1
      {0, 0, 1, 0, 0},  // z=2
      {0, 1, 1, 0, 0},  // z=3
      {0, 1, 0, 0, 0}   // z=4
    }
  },
  
  // y = 2
  {
    // x = 0
    {
      {0, 0, 0, 0, 0},  // z=0
      {0, 0, 0, 0, 1},  // z=1
      {0, 0, 0, 0, 1},  // z=2
      {0, 0, 0, 1, 1},  // z=3
      {0, 0, 0, 1, 1}   // z=4
    },
    // x = 1
    {
      {0, 0, 0, 0, 1},  // z=0
      {0, 0, 0, 1, 1},  // z=1
      {0, 0, 0, 1, 1},  // z=2
      {0, 0, 1, 1, 0},  // z=3
      {0, 0, 1, 0, 0}   // z=4
    },
    // x = 2
    {
      {0, 0, 0, 0, 1},  // z=0
      {0, 0, 0, 1, 1},  // z=1
      {0, 0, 1, 1, 0},  // z=2
      {0, 0, 1, 0, 0},  // z=3
      {0, 1, 1, 0, 0}   // z=4
    },
    // x = 3
    {
      {0, 0, 0, 1, 1},  // z=0
      {0, 0, 1, 1, 0},  // z=1
      {0, 0, 1, 0, 0},  // z=2
      {0, 1, 1, 0, 0},  // z=3
      {0, 1, 0, 0, 0}   // z=4
    },
    // x = 4
    {
      {0, 0, 0, 1, 1},  // z=0
      {0, 0, 1, 0, 0},  // z=1
      {0, 1, 1, 0, 0},  // z=2
      {0, 1, 0, 0, 0},  // z=3
      {1, 1, 0, 0, 0}   // z=4
    }
  },
  
  // y = 3
  {
    // x = 0
    {
      {0, 0, 0, 0, 0},  // z=0
      {0, 0, 0, 0, 1},  // z=1
      {0, 0, 0, 1, 1},  // z=2
      {0, 0, 0, 1, 1},  // z=3
      {0, 0, 1, 1, 0}   // z=4
    },
    // x = 1
    {
      {0, 0, 0, 0, 1},  // z=0
      {0, 0, 0, 1, 1},  // z=1
      {0, 0, 1, 1, 0},  // z=2
      {0, 0, 1, 0, 0},  // z=3
      {0, 1, 1, 0, 0}   // z=4
    },
    // x = 2
    {
      {0, 0, 0, 1, 1},  // z=0
      {0, 0, 1, 1, 0},  // z=1
      {0, 0, 1, 0, 0},  // z=2
      {0, 1, 1, 0, 0},  // z=3
      {0, 1, 0, 0, 0}   // z=4
    },
    // x = 3
    {
      {0, 0, 0, 1, 1},  // z=0
      {0, 0, 1, 0, 0},  // z=1
      {0, 1, 1, 0, 0},  // z=2
      {0, 1, 0, 0, 0},  // z=3
      {1, 1, 0, 0, 0}   // z=4
    },
    // x = 4
    {
      {0, 0, 1, 1, 0},  // z=0
      {0, 1, 1, 0, 0},  // z=1
      {0, 1, 0, 0, 0},  // z=2
      {1, 1, 0, 0, 0},  // z=3
      {1, 0, 0, 0, 0}   // z=4
    }
  },
  
  // y = 4
  {
    // x = 0
    {
      {0, 0, 0, 0, 1},  // z=0
      {0, 0, 0, 1, 1},  // z=1
      {0, 0, 0, 1, 1},  // z=2
      {0, 0, 1, 1, 0},  // z=3
      {0, 0, 1, 0, 0}   // z=4
    },
    // x = 1
    {
      {0, 0, 0, 1, 1},  // z=0
      {0, 0, 1, 1, 0},  // z=1
      {0, 0, 1, 0, 0},  // z=2
      {0, 1, 1, 0, 0},  // z=3
      {0, 1, 0, 0, 0}   // z=4
    },
    // x = 2
    {
      {0, 0, 0, 1, 1},  // z=0
      {0, 0, 1, 0, 0},  // z=1
      {0, 1, 1, 0, 0},  // z=2
      {0, 1, 0, 0, 0},  // z=3
      {1, 1, 0, 0, 0}   // z=4
    },
    // x = 3
    {
      {0, 0, 1, 1, 0},  // z=0
      {0, 1, 1, 0, 0},  // z=1
      {0, 1, 0, 0, 0},  // z=2
      {1, 1, 0, 0, 0},  // z=3
      {1, 0, 0, 0, 0}   // z=4
    },
    // x = 4
    {
      {0, 0, 1, 0, 0},  // z=0
      {0, 1, 0, 0, 0},  // z=1
      {1, 1, 0, 0, 0},  // z=2
      {1, 0, 0, 0, 0},  // z=3
      {1, 0, 0, 0, 0}   // z=4
    }
  }
};

// Helper function to read from PROGMEM
// NOTE: Array is indexed as [y][x][z][iteration]
inline uint8_t getSphereValue(uint8_t y, uint8_t x, uint8_t z, uint8_t iteration) {
  return pgm_read_byte(&sphereLUT[y][x][z][iteration]);
}

// Function to check if a voxel should be lit for a given iteration
// Handles full 10x10x10 cube by mirroring the octant data
inline bool isSphereVoxelLit(uint8_t x, uint8_t y, uint8_t z, uint8_t iteration) {
  // Mirror coordinates around center (4.5, 4.5, 4.5)
  uint8_t mx = (x < 5) ? x : (9 - x);
  uint8_t my = (y < 5) ? y : (9 - y);
  uint8_t mz = (z < 5) ? z : (9 - z);
  
  // Look up in table - note the order is y, x, z
  return getSphereValue(my, mx, mz, iteration) == 1;
}

#endif // SPHERE_LUT_H