"""----------------------------------------"""
"""|LEAP MOTION AND PICAXE MICROCONTROLLER|"""
"""----------------------------------------"""

#this is the port number of your serial port
portNumber = 4

#use this line if you're running Linux:
#port = '/dev/ttyUSB' + str(portNumber - 1)

#otherwise, use this line if you're running Windows:
port = portNumber - 1

"""-----IMPORTANT! YOU DO NOT NEED TO EDIT ANYTHING BELOW THIS LINE!------"""
"""-----------------------------------------------------------------------"""

import Leap, sys, thread, time, serial
from Leap import CircleGesture, KeyTapGesture, ScreenTapGesture, SwipeGesture

#setup serial port interface and kill any action
ser = serial.Serial()
if not("/dev/ttyUSB" in str(port)):
    print("Connecting to serial port COM" + str(port) + "...")
else:
    print("Connecting to serial port " + str(port) + "...")
ser.port = port
ser.baudrate = 4800
ser.open()

#serial data variables
serDataL = "0"
serDataR = "0"
serDataOld = "00"

class LeapMotionListener(Leap.Listener):
    fingerNames = ["Thumb", "Index", "Middle", "Ring", "Pinky"]
    boneNames = ["Metacarpal", "Proximal", "Intermediate", "Distal"]
    stateNames = ["STATE_INVALID", "STATE_START", "STATE_UPDATE", "STATE_END"]

    def on_init(self, controller):
        print("Initialized Leap Motion libraries!")
        
    def on_connect(self, controller):
        print("Leap Motion sensor connected!")

        controller.enable_gesture(Leap.Gesture.TYPE_CIRCLE);
        controller.enable_gesture(Leap.Gesture.TYPE_KEY_TAP);
        controller.enable_gesture(Leap.Gesture.TYPE_SCREEN_TAP);
        controller.enable_gesture(Leap.Gesture.TYPE_SWIPE);

    def on_disconnect(self, controller):
        print("Leap Motion sensor disconnected.")

    def on_exit(self, controller):
        #stop PICAXE activity, then close serial port
        if serDataOld != "00":
            print "00   0"
        ser.write("0")
        ser.close()
        print("Done.")

    def on_frame(self, controller):
        frame = controller.frame()

        if not len(frame.hands) < 1:
            for hand in frame.hands:
                global serDataL, serDataR, serDataOld

                #is hand left or right?
                handType = "Left Hand" if hand.is_left else "Right Hand"

                #define normal, direction, pitch, roll, and yaw
                normal = hand.palm_normal
                direction = hand.direction
                pitch = (direction.pitch + Leap.RAD_TO_DEG)
                roll = (direction.roll + Leap.RAD_TO_DEG)
                yaw = (direction.yaw + Leap.RAD_TO_DEG)

                if hand.is_left:
                    #middle position
                    if pitch <= 57.7 and pitch >= 57.2:
                        serDataL = "0"
                    #forward position
                    elif pitch <= 57.2:
                        serDataL = "1"
                    #back position
                    elif pitch >= 57.7:
                        serDataL = "2"
                else:
                    #middle position
                    if pitch <= 57.7 and pitch >= 57.2:
                        serDataR = "0"
                    #forward position
                    elif pitch <= 57.2:
                        serDataR = "1"
                    #back position
                    elif pitch >= 57.7:
                        serDataR = "2"

                #decipher positions, then send one char serial data to PICAXE
                serData = serDataL + serDataR
                if serData != serDataOld:
                    if serData == "00":
                        serDC = "0"
                        
                    elif serData == "10":
                        serDC = "1"
                        
                    elif serData == "20":
                        serDC = "2"
                        
                    elif serData == "01":
                        serDC = "3"

                    elif serData == "02":
                        serDC = "4"
                        
                    elif serData == "11":
                        serDC = "5"
                        
                    elif serData == "21":
                        serDC = "6"
                        
                    elif serData == "12":
                        serDC = "7"
                        
                    elif serData == "22":
                        serDC = "8"

                    #print data and send to PICAXE    
                    print serData + "   " + serDC
                    ser.write(serDC)
                    serDataOld = serData

        #if there aren't any visible hands, stop PICAXE activity
        elif len(frame.hands) < 1:
            if not serDataOld == "00":
                ser.write("0")
                print "00   0"
                serDataOld = "00"

def main():
    listener = LeapMotionListener()
    controller =  Leap.Controller()

    controller.add_listener(listener)

    print(" ")
    print("Press ENTER to quit")
    print(" ")
    try:
        sys.stdin.readline()
        
    except KeyboardInterrupt:
        pass
    
    finally:
        controller.remove_listener(listener)

if __name__ == "__main__":
    main()
