#!/usr/bin/python

from PIL import Image
import types

im = Image.open("4dv3ntSn4il_cropped.png")
pix = im.load()
numTiles = 25
tileSize = im.size[0] // numTiles

data = [["0" for x in range(numTiles)] for y in range(numTiles)]

for x in range(0, numTiles):
    for y in range(0, numTiles):
        x_abs = x*tileSize + tileSize // 2
        y_abs = y*tileSize + tileSize // 2

        pixel = pix[x_abs, y_abs]

        if type(pixel) is tuple:
            data[x][y] = "0" if pixel == (255,255,255) else "1"
        else:
            data[x][y] = "0" if pixel / 255 > 0.5 else "1"

bits = ''.join([''.join([data[x][y] for x in range(numTiles)]) for y in range(numTiles)])

print("Number of Zeros:", bits.count("0"), "Number of Ones:", bits.count("1"), "Length:", len(bits))

snail = ""
clockwise = False
bounds = [[0,numTiles-1],[0, numTiles-1]]
pos = [0,0]
dir = [1,0] if clockwise else [0, 1]
pixels = []
while len(snail) < numTiles*numTiles:
    if pos in pixels:
        print("Fault:", pos, "already processed")
    pixels.append(pos)

    snail += data[pos[0]][pos[1]]
    next_pos = [pos[0] + dir[0], pos[1] + dir[1]]
    if dir[0] == 1 and next_pos[0] > bounds[0][1] or dir[0] == -1 and next_pos[0] < bounds[0][0] or dir[1] == 1 and next_pos[1] > bounds[1][1] or dir[1] == -1 and next_pos[1] < bounds[1][0]:
        if clockwise:
            if dir[0] == 1:
                dir = [0, 1]
                bounds[0][1] -= 1
            elif dir[0] == -1:
                dir = [0, -1]
                bounds[0][0] += 1
            elif dir[1] == 1:
                dir = [-1, 0]
                bounds[1][1] -= 1
            elif dir[1] == -1:
                dir = [1, 0]
                bounds[1][0] += 1
        else:
            if dir[0] == 1:
                dir = [0, -1]
                bounds[1][1] -= 1
            elif dir[0] == -1:
                dir = [0, 1]
                bounds[0][1] -= 1
            elif dir[1] == 1:
                dir = [1, 0]
                bounds[0][0] += 1
            elif dir[1] == -1:
                dir = [-1, 0]
                bounds[1][0] += 1

        next_pos = [pos[0] + dir[0], pos[1] + dir[1]]
    pos = next_pos

if snail.count("0") != bits.count("0") or snail.count("1") != bits.count("1"):
    print("Bits do not match")
    exit()

im = Image.new('RGB', im.black)
pix = im.load()

for tileY in range(0, numTiles):
    for tileX in range(0, numTiles):

        bit = snail[tileX * numTiles + tileY]

        for x in range(0, tileSize):
            for y in range(0, tileSize):

                x_abs = tileX * tileSize + x
                y_abs = tileY * tileSize + y

                pix[x_abs,y_abs] = (0,0,0,255) if bit == "1" else (255,255,255,255)

im.save("decoded.png")
