#!/usr/bin/env python3

import sys
import os
import numpy as np
import pygame

Nx = int(sys.argv[1])
Ny = int(sys.argv[2])
try:
    frequency = float(sys.argv[3])
except (IndexError, ValueError):
    frequency = 5

fps = 10

nstates = 5
colors = np.linspace(0, 255, nstates, dtype=np.uint8)

red = np.random.choice(colors, size=(Ny,Nx))
green = np.zeros((Ny, Nx))
blue = np.zeros((Ny, Nx))
grid = np.dstack((red, green, blue)).astype(np.uint8)


clock = pygame.time.Clock()

def clamp(value, min, max):
  if value > max:
      return max
  elif value < min:
      return min
  return value


while True:

  for px in range(Nx):
    for py in range(Ny):
      statecount = np.zeros(nstates, dtype=np.uint8)
      for ix in [-1, 0, 1]:
        for iy in [-1, 0, 1]:

          if (px+ix) >= Nx or (px+ix) <= 0 or (py+iy) >= Ny or (py+iy) <= 0:
            i = 0
          else:
            i = int(grid[py + iy, px + ix, 0] / colors[1])

          #i = int(grid[(px + ix) % Nx, (py + iy) % Ny, 0] / colors[1])
          #i = int(grid[max(min(px + ix, Nx-1), 0), max(min(py + iy, Ny-1), 0), 0] / colors[1])
          #print(px, py, max(min(px + ix, Nx-1), 0), max(min(py + iy, Ny-1), 0), file=sys.stderr)
          statecount[i] = statecount[i] + 1

      i = int(grid[py, px, 0] / colors[1])
      i_successor = (i+1) % colors.size

      if statecount[i_successor] >= 2: #(2-np.random.randint(0, 2)):
        grid[py, px, 0] = colors[i_successor]

#    for i in range(Nx*Ny):
#      c1 = clamp(i % Nx - 1, 0, Nx - 1) 
#      c2 = clamp(int(i / Nx) - 1, 0, Ny - 1)
#      neighbourhood = grid[c1:(c1+3), c2:(c2+3), 0]
#      #print(neighbourhood.size, file=sys.stderr)




  out = grid.tobytes()
  os.write(1, out)
  clock.tick_busy_loop(fps)