import serial
import sys
import os
import time
from Tkinter import Tk, Label
from PIL import ImageTk, Image

layerHeight = 0.1  # In mm
dipHeight = 2 # In mm
exposureTime = 1500  # In msec
sliceFolder = "/Users/andreasbastian/Dropbox/adsk/Ember/top down DLP/skullimages" # name of the file with all the images
modelHeight = 21.35  # In mm
shutterSpeed = 100  # In mm/min
shutterClosePosition = 0
shutterOpenPosition = -0.2
dropSpeed = 500  # In mm/min
riseSpeed = 100  # In mm/min
#gcodez = open('/Users/cappie/Downloads/gcodez/run.gcode', 'wr') # uncomment this line to write file
imageWindow = Tk()
gcodez = serial.Serial('/dev/tty.usbmodemfa131', 250000)  # comment this line to write to file
gcodez.timeout = 2  # comment this line to write to file
time.sleep(5)  # wait until motorboard is ready


def relativeMode():
    gcodez.write('G91\n')
    if gcodez is serial.Serial():
        print "relative:", gcodez.readline()


def absoluteMode():
    gcodez.write('G90\n')
    if isinstance(gcodez, serial.serialposix.Serial):
        print "absolute:", gcodez.readline()


def openShutter():
    absoluteMode()
    gcodez.write('G1 E%0.2f F%d\n' % (shutterOpenPosition, shutterSpeed))
    if isinstance(gcodez, serial.serialposix.Serial):
        print "open:", gcodez.readline()
        time.sleep(motorTransitTime(abs(shutterOpenPosition), shutterSpeed))


def closeShutter():
    absoluteMode()
    gcodez.write('G1 E%0.2f F%d\n' % (shutterClosePosition, shutterSpeed))
    if isinstance(gcodez, serial.serialposix.Serial):
        print "close:", gcodez.readline()
        time.sleep(motorTransitTime(abs(shutterOpenPosition), shutterSpeed))


def dip():
    relativeMode()
    gcodez.write('G1 Z-%0.2f F%d\n' % (dipHeight, dropSpeed))
    if isinstance(gcodez, serial.serialposix.Serial):
        print "dip:", gcodez.readline()
        time.sleep(motorTransitTime(dipHeight, dropSpeed))
    riseHeight = dipHeight - layerHeight
    gcodez.write('G1 Z%0.2f F%d\n' % (riseHeight, riseSpeed))
    if isinstance(gcodez, serial.serialposix.Serial):
        print "rise:", gcodez.readline()
        time.sleep(motorTransitTime(riseHeight, riseSpeed))


def pause(wait):
    beforePause = time.time()
    gcodez.write('G4 P%d\n' % wait)
    if isinstance(gcodez, serial.serialposix.Serial):
        while True:
            if (time.time() - beforePause) >= wait/1000.0:
                print "pause:", gcodez.readline()
                break


def motorTransitTime(distance, speed):
    return ((float(distance)/float(speed))*60.0)


def nextSlice(slice):
    img = ImageTk.PhotoImage(Image.open(slice))
    label = Label(image=img)
    label.image = img
    label.pack()
    imageWindow.update()
    print slice


def main():
    print gcodez.read(gcodez.inWaiting())
    imageWindow.overrideredirect(True)
    imageWindow.attributes("-fullscreen", True)
    for step in xrange(1, int((modelHeight/layerHeight))+1):
        closeShutter()
        nextSlice('%s/slice_%d.png' % (sliceFolder, step))
        dip()
        openShutter()
        pause(exposureTime)
    closeShutter()
    time.sleep(2)
    imageWindow.destroy()
    gcodez.close()

if __name__ == "__main__":
    try:
        main()
    except KeyboardInterrupt:
        print 'Interrupted'
        try:
            imageWindow.destroy()
            gcodez.close()
            sys.exit(0)
        except SystemExit:
            os._exit(0)
