#!/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:
    fps = float(sys.argv[3])
except (IndexError, ValueError):
    fps = 15

#fps = 15

colors = np.array([
    0x0, 0x0, 0x0,
#    0x07,0x07,0x07,
#    0x1F,0x07,0x07,
#    0x2F,0x0F,0x07,
#    0x47,0x0F,0x07,
    0x57,0x17,0x07,
#    0x67,0x1F,0x07,
#    0x77,0x1F,0x07,
#    0x8F,0x27,0x07,
    0x9F,0x2F,0x07,
#    0xAF,0x3F,0x07,
#    0xBF,0x47,0x07,
#    0xC7,0x47,0x07,
    0xDF,0x4F,0x07,
#    0xDF,0x57,0x07,
#    0xDF,0x57,0x07,
#    0xD7,0x5F,0x07,
#    0xD7,0x5F,0x07,
 #   0xD7,0x67,0x0F,
 #   0xCF,0x6F,0x0F,
 #   0xCF,0x77,0x0F,
    0xCF,0x7F,0x0F,
 #   0xCF,0x87,0x17,
 #   0xC7,0x87,0x17,
 #   0xC7,0x8F,0x17,
 #   0xC7,0x97,0x1F,
 #   0xBF,0x9F,0x1F,
 #   0xBF,0x9F,0x1F,
 #   0xBF,0xA7,0x27,
    0xBF,0xA7,0x27,
 #   0xBF,0xAF,0x2F,
 #   0xB7,0xAF,0x2F,
 #   0xB7,0xB7,0x2F,
 #   0xB7,0xB7,0x37,
 #   0xCF,0xCF,0x6F,
 #   0xDF,0xDF,0x9F,
 #   0xEF,0xEF,0xC7,
 #   0xFF,0xFF,0xFF
], dtype=np.uint8)

colors = np.reshape(colors, (colors.size//3, 3))

grid = np.zeros((Ny,Nx), dtype=np.int32)
gridout = np.zeros((Ny,Nx), dtype=np.int32)
grid[0,:].fill(colors.shape[0]-1)

clock = pygame.time.Clock()



def state2red(c):
    return colors[c, 0]

def state2green(c):
    return colors[c, 1]

def state2blue(c):
    return colors[c, 2]

i = 0

while True:
    i = i + 1
    rnd = np.random.randint(3, size=(Ny, Nx))

    for px in range(Nx):
        for py in range(1, Ny):
            #grid[py, px] = max(grid[py-1, px] - 1, 0) # v1
            #grid[py, px] = max(grid[py-1, px] - (rnd[py, px] & 1), 0) # v2
            grid[py, (px - rnd[py, px] + 1) % Nx] = max(grid[py-1, px] - (rnd[py, px] & 1), 0) # v3

    #if i % 100 == 0:
    #    grid[0,:].fill(0)
    #elif (i - (colors.shape[0] +10)) % 100 == 0:
    #    grid[0,:].fill(colors.shape[0]-1)

    gridup = np.flipud(np.fliplr(grid))
    np.clip(grid + gridup, 0, colors.shape[0]-1, out=gridout)

    #out = np.dstack((state2red(gridout), state2green(gridout), state2blue(gridout), np.full((Ny, Nx), 100, dtype=np.uint8))).astype(np.uint8).tobytes()
    out = np.dstack((state2red(gridout), state2green(gridout), state2blue(gridout))).astype(np.uint8).tobytes()
    
    os.write(1, out)
    clock.tick_busy_loop(fps)