#!/usr/bin/env python

import sys
import struct
import subprocess
import StringIO
import time
import threading
import Queue
import wave
import exceptions
import os
import pickle
import binascii

import serial
import Image
import ImageFont
import ImageDraw

from Cheetah.Template import Template
TProdG = Template.compile(file="prod-g.html")

import gameduino.sim as gdsim
import gameduino

speed = 115200

font = ImageFont.truetype("graphics/eurostile/Eurostile_Bold.ttf", 21);
fontL = ImageFont.truetype("graphics/eurostile/Eurostile_Bold.ttf", 28);

from dymo import Dymo

# echo -n 'http://gameduino.com/g5e242b6d520fc1' | dmtxwrite -et -d7 -m24 -sr -o foo.png
# os.system("killall multimon")
# time.sleep(2)

def mkdmtx(url):
    p = subprocess.Popen("dmtxwrite -et -d7 -m12 -sr".split(), stdin=subprocess.PIPE, stdout=subprocess.PIPE)
    p.stdin.write(url.lower())
    p.stdin.close()
    png = StringIO.StringIO()
    png.write(p.stdout.read())
    png.seek(0)
    return Image.open(png)

def gen_label(serial):
    dim = 280
    def cnt(w):
        return (dim - w) / 2
    im = Image.new("L", (dim,dim), 255)
    url = "http://gameduino.com/g" + serial
    dmtx = mkdmtx(url)
    # dmtx.save("x.png")
    im.paste(dmtx, (0,0))
    draw = ImageDraw.Draw(im)
    part1 = url[:21].upper()
    part2 = url[21:].upper()
    (w,h) = draw.textsize(part1, font=font)
    draw.text((cnt(w), dmtx.size[1]), part1, font=font, fill=0)
    (w,_) = draw.textsize(part2, font=fontL)
    draw.text((cnt(w), dmtx.size[1] + (4 * h) / 3), part2, font=fontL, fill=0)
    logo = Image.open("gdlogo-mono.png").convert("L")
    im.paste(logo, (cnt(logo.size[0]), dim - 15 - logo.size[1]))
    if False:
        for x in range(0, dim, 2):
            im.putpixel((x, 0), 0)
            im.putpixel((x, dim-1), 0)
            im.putpixel((0, x), 0)
            im.putpixel((dim-1, x), 0)
    return im

def print_label(im):
    im1 = im.point([0] * 128 + [255] * 128, "1")
    p = subprocess.Popen("lpr -P Dymo-Label-Printer -l".split(), stdin=subprocess.PIPE)
    d = Dymo(p.stdin)
    d.reset()
    d.setlabellength(im1.size[0])
    d.image(im1)
    p.stdin.close()

def gen_screenshot(dna):
    gd = gdsim.Gameduino()
    gd.ascii()
    gd.putstr(0, 0, "Manufacturing setup")
    gd.putstr( 0, 6, "Serial")
    gd.putstr(10, 6, dna)
    gd.putstr( 0, 8, "loading")
    gd.putstr(10, 8, 40 * chr(127))
    gd.putstr( 0, 10, "verifying")
    gd.putstr(10, 10, "Flash loaded OK")
    gd.putstr(10, 12, "Assets loaded")

    def show_stripes():
      y = 5;
      def atxy(x, y):
        return 64 * y + x
      for i in range(32):
        gd.wr16(gameduino.RAM_PAL + (0x80 + i) * 8, gameduino.RGB(8 * i, 0, 0));
        gd.wr16(gameduino.RAM_PAL + (0xa0 + i) * 8, gameduino.RGB(0, 8 * i, 0));
        gd.wr16(gameduino.RAM_PAL + (0xc0 + i) * 8, gameduino.RGB(0, 0, 8 * i));
        gd.wr(atxy(i, y + 24), 0x80 + i);
        gd.wr(atxy(i, y + 25), 0xa0 + i);
        gd.wr(atxy(i, y + 26), 0xc0 + i);

      gd.putstr(0, y + 28, "R");
      gd.putstr(0, y + 29, "G");
      gd.putstr(0, y + 30, "B");
      gd.putstr(4, y + 31, "0");
      gd.putstr(8, y + 31, "1");
      gd.putstr(16, y + 31, "2");

      gd.wr(atxy(4, y + 28), 0x80 + 4);
      gd.wr(atxy(8, y + 28), 0x80 + 8);
      gd.wr(atxy(16, y + 28), 0x80 + 16);

      gd.wr(atxy(4, y + 29), 0xa0 + 4);
      gd.wr(atxy(8, y + 29), 0xa0 + 8);
      gd.wr(atxy(16, y + 29), 0xa0 + 16);

      gd.wr(atxy(4, y + 30), 0xc0 + 4);
      gd.wr(atxy(8, y + 30), 0xc0 + 8);
      gd.wr(atxy(16, y + 30), 0xc0 + 16);
    show_stripes()
    return gd.im()

# printlabel("56AD428756A42C")
# sys.exit(0)

qtone  = Queue.Queue()
qserial  = Queue.Queue()

def dmtxlisten():
    cmd = "/home/jamesb/multimon/bin-i686/multimon -a DTMF".split()
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    file = p.stdout
    anything = False
    while True:
        line = file.readline()
        if not line:
            time.sleep(.1)
        else:
            if not anything:
                anything = True
                print "multimon running"
            if line.startswith("DTMF: "):
                code = line[6]
                if code == '*':
                    code = 'E'
                if code == '#':
                    code = 'F'
                qtone.put((code, time.time()))

class DMTXlistener(threading.Thread):
    daemon = True
    def run(self):
        dmtxlisten()

class DMTXjoiner(threading.Thread):
    daemon = True
    def run(self):
        serial = ""
        while True:
            try:
                (code, t) = qtone.get(True, 0.4)
                serial += code
            except Queue.Empty:
                if len(serial) == 14:
                    qserial.put(serial)
                serial = ""

audios = []
class Recorder(threading.Thread):
    daemon = True
    def run(self):
        p = open("/home/jamesb/echo", "r")
        while True:
            l = p.read(256)
            if l:
                audios.append(l)

t = Recorder()
t.start()

t = DMTXlistener()
t.start()

t = DMTXjoiner()
t.start()

while len(audios) < 100:
    print "waiting for audio stream..."
    time.sleep(.1)

# What goes on the web page:
#   photo of board
#   image of label
#   recording of audio
log = open("log", "w")
print ">>>"
ser = serial.Serial(sys.argv[1], speed)
line = ""
slug = "=====>"
producing = True
while True:
    line = ser.readline()
    log.write(line)
    line = line.rstrip()
    print line
    if len(line) > 15 and line[14] == '%':
        f = line.split('%')
        dna = f[0]
        if f[1] == 'T':
            audios = []
            started = time.time()
            print slug, "Start testing", dna
            dirname = "prod/g" + dna
            try:
                os.mkdir(dirname)
            except exceptions.OSError:
                pass
            if producing:
                os.system("./takephoto prod/g%s &" % dna)
            zif = False
        elif f[1] == 'I':
            zif = struct.unpack("<HL", binascii.a2b_hex(f[2]))
        elif f[1] == 'F':
            revision = f[2]
            flashid = f[3]
            if producing:
                while True:
                    serial = qserial.get()
                    if serial == dna:
                        break
            print slug, "PASS %s %.2fs" % (dna, time.time() - started)
            print
            w = wave.open(dirname + "/sample.wav", "w")
            w.setnchannels(1)
            w.setframerate(22050)
            w.setsampwidth(2)
            w.writeframes("".join(audios))
            w.close()

            label = gen_label(dna)
            label.save(dirname + "/label.png")
            if producing:
                print_label(label)
            gen_screenshot(dna).save(dirname + "/screenshot.png")

            facts = {
                # 'prodrun' : "1117e",  # original 100 from Seeed
                # 'prodrun' : "1121p", # Gold Phoenix
                'prodrun' : "1123e",    # 400 from Seeed
                'tester' : "james",
                'revision' : revision,
                'teststand' : "A",
                'serial' : dna,
                't0' : started,
                't1' : time.time(),
                'flashid' : flashid
            }
            if zif:
                facts['zif_count'] = zif[0]
                facts['zif_t0'] = zif[1]
            pickle.dump(facts, open(dirname + "/facts.pickle", "w"))
            pg = TProdG()
            pg.searchList().append(facts)
            open("prod/g%s/index.html" % dna, "w").write(str(pg))


    line = ""
