#!/usr/bin/python
# -*- coding: utf-8 -*-
"""\
    Simple g-code streaming lib for EngraveCube
"""
import serial, sys , time


## E3Sender class
#
# CLasse per lo streaming di comandi G-Code al firmware dell'EngraveCube.
class E3Sender(object):

    baudRate = None

    serialPort = None

    serialConn = None

    gcodeList = []

    nextGcodeLine = 0

    altOnKo = False

    ## Costruttore di classe
    #
    # Inizializza la connessione seriale verso sulla porta ed al baud rate
    # specificato.
    def __init__(self, port, baudRate = 9600):
        self.serialPort = port
        self.baudRate = 9600
        self.serialConn = serial.Serial(port, baudRate)

        # Waiting for welcome message from E3
        welcomeMsg = self.serialConn.readline()
        print "E3-Sender.__init__: " + welcomeMsg
    # End __init__

    ## removeComment Rimuove dallo stream le righe di commento.
    #
    # Maggiori dettigli
    def removeComment(self, gcodeString):
        if (gcodeString.find(';')==-1):
            return gcodeString
        else:
            return gcodeString[:gcodeString.index(';')]

    # End removeComment

    ## runGcode - Esegue la riga dello stream gcode specificata o la prossima.
    #
    # Maggiori dettigli
    def runGcode(self, gcodeLineIndex = 0):

        if not gcodeLineIndex:
            gcodeLineIndex = self.nextGcodeLine

        fwmOut = list()

        # If all the gcodeLine have been processed, return false
        if gcodeLineIndex == len(self.gcodeList):
            # self.nextGcodeLine += 1
            return False

        gcodeLine = self.removeComment(self.gcodeList[gcodeLineIndex])
        gcodeLine = gcodeLine.strip() # Strip all EOL characters for streaming

        print "E3-Sender: LN " + str(gcodeLineIndex) + " : " + gcodeLine


        if  (gcodeLine.isspace()==False and len(gcodeLine)>0) :
            # print 'Sending: ' + l
            # s.write(l + '\n') # Send g-code block
            self.serialConn.write(gcodeLine + '\r\n') # Send g-code block

            e3Debug = True
            while e3Debug :
                fwmOut.append(self.serialConn.readline())
                print ' : ' + fwmOut[-1].strip()

                if fwmOut[-1].startswith(">>"):
                    e3Debug = False

        self.nextGcodeLine += 1
        return True

    # End runGcode

    def runAll(self):
        while self.runGcode():
            pass
        print "Engraving Job Completed"
        sys.exit()
    # End runAll

# End class E3Sender

if __name__ == '__main__':
    import argparse

    parser = argparse.ArgumentParser()

    # Defining parametes options
    parser.add_argument('file', help='Gcode file to stream')

    parser.add_argument('-p','--port',help='Input USB port',required=True)

    parser.add_argument('-b','--baud',help='Baud rate',required=True)

    #Check the arguments
    args = parser.parse_args()

    if not (args.file):
        #Print help
        parser.print_help()
        #Exit out with no action message
        parser.error('No action requested')
    else:
        ## show values ##
        print ("USB Port: %s" % args.port )
        print ("Baud rate: %s" % args.baud )
        print ("Gcode file: %s" % args.file )

        print "\n ------------------------------ \n"

        # Wait for user imput to send G-code
        raw_input("  Press <Enter> to send G-Code.")

        # Creating Gcode sender and estabilishing serial connection.
        sender = E3Sender(args.port, args.baud)

        # Opening Gcode file

        # Extracting Gcode lines from file and pushing them to thesender.
        sender.gcodeList = list(open(args.file, "r"))

        # while sender.runGcode():
        #     pass

        sender.runAll()

# END __main__
