#!/usr/bin/env python

import sys
import time
import array
import colorsys
import math
import subprocess

import Image
import GDprep
import gameduino.remote
import gameduino.sim

gd = gameduino.remote.Gameduino(sys.argv[1], 115200)
# gd = gameduino.sim.Gameduino()
gd.silence()
gd.wr(0x2899, 0)

imageram = GDprep.ImageRAM()

bg = GDprep.alphamask(Image.open("bootlogo.png"))
fg = bg.copy()
bg64 = Image.new(bg.mode, (512,512))
bg64.paste(bg, (0,0))

def isforegnd(im, pal):
    (w,h) = im.size
    colors = set([pal[im.getpixel((i,j))] for i in range(w) for j in range(h)])
    return len(colors - set([0x8000, 0])) != 0

(pim, pal) = GDprep.pal555(fg, 16)
sprvals = []
palettes = GDprep.PALETTE16AS
for x in range(8, pim.size[0]-8, 16):
    slice = pim.crop((x, 0, x + 16, pim.size[1]))
    bars = [slice.crop((0, y, 16, y + 1)) for y in range(pim.size[1])]
    nb = [isforegnd(b, pal) for b in bars]
    y0 = nb.index(True)
    y1 = slice.size[1] - nb[::-1].index(True)
    for y in range(y0, y1, 16):
        tile = slice.crop((0, y, 16, y + 16))
        (pg, sprpal) = imageram.add(array.array('B', tile.tostring()), 16)
        sprval = x + (y << 16) + (pg << 25) + (palettes[sprpal] << 12)
        sprvals.append(sprval)
        bgcolor = bg64.getpixel((0,0))
        bg64.paste(Image.new("RGBA", (16,16), bgcolor), (x,y))
while len(sprvals) < 256:
    sprval = 400 + (400 << 16)
    sprvals.append(sprval)

gd.wrstr(gameduino.RAM_SPR, array.array('L', sprvals))
gd.wrstr(gameduino.RAM_SPRIMG, imageram.used())

gd.fill(0, 0, 8192)
font8x8 = array.array('B', open("../graphics/font8x8").read())
stretch = [
  0x00, 0x03, 0x0c, 0x0f,
  0x30, 0x33, 0x3c, 0x3f,
  0xc0, 0xc3, 0xcc, 0xcf,
  0xf0, 0xf3, 0xfc, 0xff ]
for i in range(768):
    b = font8x8[i]
    h = stretch[b >> 4];
    l = stretch[b & 0xf];
    gd.wr(0x1000 + (16 * ord(' ')) + (2 * i), h);
    gd.wr(0x1000 + (16 * ord(' ')) + (2 * i) + 1, l);
for i in range(0x20, 0x80):
    gd.wr16(gameduino.RAM_PAL + 8 * i + 0, gameduino.TRANSPARENT);
    gd.wr16(gameduino.RAM_PAL + 8 * i + 6, gameduino.RGB(255,255,255));

if 1:
    # bg64.paste(GDprep.alphamask(Image.open("oh_60.png")), (0,256))
    bg64.paste(GDprep.alphamask(Image.open("OpenHardwareLogo36.png").convert("RGBA")), (0,256))
    bg64.paste(GDprep.alphamask(Image.open("v10.png")), (352,264))
    # bg64.paste(Image.open("excamera.png"), (248,264))
    (picdata, chrdata, paldata) = GDprep.encode(bg64)
    nchars = len(chrdata) / 16
    print "nchars", nchars
    xlat = range(0,32) + range(128,256)
    gd.wrstr(gameduino.RAM_PIC, array.array('B', [xlat[x] for x in picdata]))
    for c in range(nchars):
        xc = xlat[c]
        gd.wrstr(gameduino.RAM_CHR + 16 * xc, chrdata[16 * c:16 * c + 16])
        gd.wrstr(gameduino.RAM_PAL + 8 * xc, paldata[4 * c:4 * c + 4])

    # gd.microcode(open("../j1firmware/reload.binle").read())
    # time.sleep(2)

    gd.fill(0x3400, 0, 256)
    for (i, (f, a)) in enumerate(GDprep.spectrum("thx.txt", cutoff = 64, volume = 255)):
        gd.wr32(0x3400 + (4 * i), int(4 * f) | (a << 16) | (a << 24))
    for (i, (f, a)) in enumerate(GDprep.spectrum("maid1.txt", cutoff = 64, volume = 255)):
        gd.wr32(0x3500 + (4 * i), int(4 * f) | (a << 16) | (a << 24))
    for (i, (f, a)) in enumerate(GDprep.spectrum("maid2.txt", cutoff = 64, volume = 255)):
        gd.wr32(0x3600 + (4 * i), int(4 * f) | (a << 16) | (a << 24))

# Each palette is 32 bytes, so room for 64 palettes
def pal2rgba(p):
    return (((p >> 10) & 0x1f) * 8, ((p >> 5) & 0x1f) * 8, (p & 0x1f) * 8, (p >> 15) * 255)

pal[15] = gameduino.RGB(36,0,0)
rgbas = [pal2rgba(p) for p in pal]
print rgbas
print "STARTING"

for i in range(64):
    bright = math.pow(min(1.0, i / 63.), 2.6)
    print i, bright
    # modulated = [gameduino.RGB(int(r * t), int(g * t), int(b * t)) | ((a&1)<<15) for (r,g,b,a) in rgbas]
    final = []
    for j in range(16):
        r,g,b,a = rgbas[j]
        (h,s,v) = colorsys.rgb_to_hsv(r/255., g/255., b/255.)
        r,g,b = colorsys.hsv_to_rgb(h, s, v * bright)
        final.append(gameduino.RGB(int(255 * r), int(255 * g), int(255 * b)) | ((a&1)<<15))
    # gd.wrstr(gameduino.PALETTE16A, array.array('H', final))
    # gd.wr16(gameduino.BG_COLOR, final[15])
    gd.wrstr(gameduino.RAM_SPRPAL + 32 * i, array.array('H', final))
    # time.sleep(1 / 72.)
    # time.sleep(1)

def rjust(y, s):
    gd.putstr(49 - len(s), y, s)
if 0:
    rjust(33, "MANUFACTURING TEST ROM");
    rjust(34, "NOT FOR SALE");
    svn = subprocess.Popen("svnversion", stdout=subprocess.PIPE).stdout.read().strip()
    rjust(35, "svn " + svn)
    rjust(36, "(c) gameduino.com 2011");

"""
Gameduino
was made
using lots
of free and
Open Source
software,
including:

Gimp
Inkscape
Python
vim
Audacity
gforth
subversion
latex
Sphinx
Arduino

"""

def unhex(s):
    return array.array('B', [int(n,16) for n in s.split()]).tostring()

messages = [
"Happy birthday to my son, Zakery Clarke, love dad.",
"Mighty oaks from little acorns; Pursue your passions. --jjohn",
"Congratulations to Michael and Melonee on your wedding",
"Watterott electronic - www.watterott.com",
unhex("53 61 72 65 76 69 61 6E 2B 50 4B 20 28 32 30 31 32 29 3A 1B 4B 49 54 58 49 5A 48 4F 52 55 5A 4F 5E 16 5F 5E 57 52 59 5E 49 5A 4F 5E 16 5C 5E 55 5E 49 5A 4F 5E 16 52 57 57 4E 56 52 55 5A 4F 5E"),
"Tammy: Thanks for being the best wife ever. Love, Roy.",
"! Happy Hacking and Retro Gaming to all, from The CowboyCoder !",
"@BM5k @devfu @gangplank @heatsynclabs",
"GabyRocks.com & TeaganRocks.com",
"Never too late to have a life, Never too late to change one.",
"Special thanks to Russell Holt",
"Project backed by Derek Dukes",
]
assert len(messages) == 12

messages += [" (C) Gameduino.com 2011 ".center(64, '-')]

for i,m in enumerate(messages):
    gd.putstr(0, 38 + 2 * i, m.ljust(64))

for i in range(len(messages),12):
    gd.putstr(0, 40 + 2 * i, "0.........1.........2.........3.........4.........5.........6...")

gd.microcode(open("../j1firmware/cold.binle").read())
open("cold.dump", "w").write(gd.memory())

# time.sleep(20)
# gd.wr(0x2899, 0x73)
time.sleep(20)
