﻿import ctypes
from DriverBase import *

class Homag(DriverBase):
    def __init__(self):
        super().__init__()
        # Homag specific data members
        self.ToolName = ''
        self.ToolNum = 0
        self.TC = False
        self.Spin = 0
        self.h = ''
        self.u = ''
        self.f = ''

    def v2S(self,a):
        return '{0:.4f}'.format(a)
    
    def setMode(self,a):
        return 'G0{0}'.format(a).strip()

    def mySetFeed(self,f):
        N = ''
        if ( f == 0):
            f = 2.0
        if (m_LastFeed !=  f): 
            m_Diez = 2
            N = " F" + self.complexV2S(f)
            m_Diez = 4
            m_LastFeed = f
        return N
        
    def writeHeaderIfNec(self):
        # the thickness of material is available just in the Rollfeed command, which is called after the startjob function
        # this is why I have created the StartJ flag, so i will know when release the startjob data. in a case of a drill job
        # the startcontour will not be called until there is a routing job, so the driver checks for the startj flag in the start contour
        # and in the drill function in order to write the header.
        s = ''
        if (self.StartJ):
            s = "[H"
            s += self.NL() + "VERSION=" + chr(34) + "4.0 Alpha" + chr(34)
            s += self.NL() + "WW="   + chr(34) + "6.0.18" + chr(34)
            s += self.NL() + "HP=" + chr(34) + "1" + chr(34)
            s += self.NL() + "IN="  + chr(34) + "0" + chr(34)
            s += self.NL() + "GX="  + chr(34) + "1" + chr(34)
            s += self.NL() + "BFS=" + chr(34) + "1" + chr(34)        
            s += self.NL() + "GY="  + chr(34) + "1" + chr(34)
            s += self.NL() + "GXY=" + chr(34) + "1" + chr(34)
            s += self.NL() + "UP="  + chr(34) + "0" + chr(34)
            s += self.NL() + "FM="  + chr(34) + "1" + chr(34) #0 stop where your at. 1 parking position dependent. 2 free motion. 3 maximum on table 4 is center 5 is minimum.   
            #0 => No clearance. 1 = > Clear ance to rear right(default). 2 = > Clear ance to rear left. 3 = > Clearance to front left. 4 = > Clear ance to front right
            s += self.NL() + "FW="   + chr(34) + "200" + chr(34)
            s += self.NL() + "ZS="   + chr(34) + "20" + chr(34)
            s += self.NL() + "HS="   + chr(34) + "0" + chr(34)
            s += self.NL() + "OP="   + chr(34) + "1" + chr(34)
            s += self.NL() + "MAT="   + chr(34) + "WEEKE" + chr(34)
            s += self.NL() + "DN="   + chr(34) + "STANDARD" + chr(34)
            s += self.NL() + "INCH="    + chr(34) + "0" + chr(34)
            s += self.NL() + "VIEW="    + chr(34) + "NOMIRROR" + chr(34)
            s += self.NL() + "ANZ="   + chr(34) + "1" + chr(34)
            s += self.NL() + "BES="   + chr(34) + "0" + chr(34)
            s += self.NL() + "ENT="   + chr(34) + "0" + chr(34)
            s += self.NL() + "_BSX="    + self.complexV2S(abs(self.m_jp.xMax - self.m_jp.xMin))
            s += self.NL() + "_BSY="    + self.complexV2S(abs(self.m_jp.yMax - self.m_jp.yMin))
            s += self.NL() + "_BSZ="    + self.complexV2S(self.Material)
            s += self.NL() + "_FNX="    + self.complexV2S(0)
            s += self.NL() + "_FNY="    + self.complexV2S(0)
            s += self.NL() + "_RNX="    + self.complexV2S(0)
            s += self.NL() + "_RNY="    + self.complexV2S(0)
            s += self.NL() + "_RNZ=0.0000" #   + self.complexV2S(self.Material)   # depth of material
            s += self.NL() + "_RX=" + self.complexV2S(abs(self.m_jp.xMax - self.m_jp.xMin)) # width of material
            s += self.NL() + "_RY=" + self.complexV2S(abs(self.m_jp.yMax - self.m_jp.yMin)) # height of material
            s += self.NL()
            s += self.NL()
            s += self.NL()
            
            s += "[001"
            s += self.NL() + "L="  + chr(34) + self.complexV2S(abs(self.m_jp.xMax - self.m_jp.xMin)) + chr(34)
            s += self.NL() + "KM=" + chr(34) + "LENGTH" + chr(34)
            s += self.NL() + "W="  + chr(34) + self.complexV2S(abs(self.m_jp.yMax - self.m_jp.yMin)) + chr(34)
            s += self.NL() + "KM=" + chr(34) + "WIDTH" + chr(34)
            s += self.NL() + "T="  + chr(34) + self.complexV2S(self.Material) + chr(34)
            s += self.NL() + "KM=" + chr(34) + "THICKNESS" + chr(34)
            s += self.NL()

            #Draw the plate
            s += self.NL() + "]1"
            s += self.NL() + "$E0"
            s += self.NL() + "KP NEST"
            s += self.NL() + self.setXYValue(self.m_jp.xMin, False, "X=") 
            s += self.NL() + self.setXYValue(self.m_jp.yMin, False, "Y=")
            s += self.NL() + "Z=" + self.complexV2S(self.Material)
            s += self.NL() + "KO=00"
            s += self.NL() + ".X=0.000000"
            s += self.NL() + ".Y=0.000000"
            s += self.NL() + ".Z=0.000000"
            s += self.NL() + ".KO=00" 
            s += self.NL()

            #First Line
            s += self.NL() + "$E1" 
            s += self.NL() + "KL" 
            s += self.NL() + self.setXYValue(self.m_jp.xMax, False, "X=") 
            s += self.NL() + self.setXYValue(self.m_jp.yMin, False, "Y=")
            s += self.NL() + ".X=0.000000"
            s += self.NL() + ".Y=0.000000"
            s += self.NL() + ".Z=0.000000"
            s += self.NL() + ".WI=0.000000"
            s += self.NL() + ".WZ=0.000000"
            s += self.NL()
        
            #Second Line
            s += self.NL() + "$E2" 
            s += self.NL() + "KL" 
            s += self.NL() + self.setXYValue(self.m_jp.xMax, False, "X=") 
            s += self.NL() + self.setXYValue(self.m_jp.yMax, False, "Y=")
            s += self.NL() + ".X=0.000000"
            s += self.NL() + ".Y=0.000000"
            s += self.NL() + ".Z=0.000000"
            s += self.NL() + ".WI=0.000000"
            s += self.NL() + ".WZ=0.000000"
            s += self.NL()
        
            #Third Line
            s += self.NL() + "$E3" 
            s += self.NL() + "KL"    
            s += self.NL() + self.setXYValue(self.m_jp.xMin, False, "X=") 
            s += self.NL() + self.setXYValue(self.m_jp.yMax, False, "Y=")
            s += self.NL() + ".X=0.000000"
            s += self.NL() + ".Y=0.000000"
            s += self.NL() + ".Z=0.000000"
            s += self.NL() + ".WI=0.000000"
            s += self.NL() + ".WZ=0.000000"  
            s += self.NL()

            #Fourth Line
            s += self.NL() + "$E4" 
            s += self.NL() + "KL" 
            s += self.NL() + self.setXYValue(self.m_jp.xMin, False, "X=")
            s += self.NL() + self.setXYValue(self.m_jp.yMin, False, "Y=")
            s += self.NL() + ".X=0.000000"
            s += self.NL() + ".Y=0.000000"
            s += self.NL() + ".Z=0.000000"
            s += self.NL() + ".WI=0.000000"
            s += self.NL() + ".WZ=0.000000"  
            s += self.NL()

            #Table definition. I had to move this to the header because if you did a job with only drilling this would not show up. I placed
            #here so that it will show on every job whether contour only, drilling only, or contour and drilling. This setction must only apear ONCE.

            self.u += self.NL() + "<100 "  + chr(92) + "Werkstck" + chr(92)  
            self.u += self.NL() + "LA="  + chr(34) + "L"  + chr(34) #complexV2S(abs(self.m_jp.xMax - self.m_jp.xMin)) + chr(34) #LA, BR, and DI in some cases can be static letters, otherwise they should use these formulas for calculating the values. 
            self.u += self.NL() + "BR="  + chr(34) + "W"  + chr(34) #complexV2S(abs(self.m_jp.yMax - self.m_jp.yMin)) + chr(34)
            self.u += self.NL() + "DI="  + chr(34) + "T"  + chr(34) #complexV2S(self.Material) + chr(34)  
            self.u += self.NL() + "FNX="  + chr(34) + "0"  + chr(34)
            self.u += self.NL() + "FNY="  + chr(34) + "0"  + chr(34)
            self.u += self.NL() + "RNX="  + chr(34) + "0"  + chr(34)
            self.u += self.NL() + "RNY="  + chr(34) + "0"  + chr(34)
            self.u += self.NL() + "RNZ="  + chr(34) + "0"  + chr(34)  #chr(34 + v2s(M.material) + chr(34 Removed this line and put in the offset
            self.u += self.NL() + "AX="  + chr(34) + "0"  + chr(34)
            self.u += self.NL() + "AY="  + chr(34) + "0"  + chr(34)
            self.u += self.NL()

        self.StartJ = False
        return s
        
    def initDrivers(self,cfg):
        super().initDrivers(cfg)
        self.m_model = self.m_cfg.model
        self.m_Diez = 4
        self.m_Zeros = 1
        self.blockNumber = 0
        self.m_FirstContour = 1
        self.m_LastTool = -1
        self.m_TChange  =  True
        self.m_Header = True
        self.m_firstTc = True
        self.m_LastCode = 0
        self.m_isParking = False
        self.m_end = False
        self.m_tapLine = ""
        self.m_toolC = "NOWRK"
        self.m_cnfPath = ""
        self.DeleteOutput = ""
        self.CountStart = 1
        self.Count = 0
        self.filepath = ""
        self.exepath = ""
        self.Material = 33
        self.dw = "0"
        self.StartJ = False
        
        return '' #"{0}".format(self.m_model)

    def startJob(self, Data): #Data not used here
        self.StartJ = True
        return ''
        
    def endJob(self, Data):
        #ej_data = ctypes.cast(Data, ctypes.POINTER(SEndJobData))
        s = self.u
        s += self.h
        s += self.f
        s += "!" + self.NL()
        return s
        
    def startContour(self, Data):
        sc_data = ctypes.cast(Data, ctypes.POINTER(SStartContourData))
        s = self.writeHeaderIfNec()
        self.Count = 0
        #this is the startpoint, the first drawXYZ call will have the same data, this is why I ignore the drawXYZ if count = 0.
        self.CountStart += 1

        s += self.NL() + "]" + f"{self.CountStart}"
        s += self.NL() + "$E0"
        s += self.NL() + "KP"
        s += self.NL() + self.setXYValue(sc_data.contents.targetX, False, "X=") 
        s += self.NL() + self.setXYValue(sc_data.contents.targetY, False, "Y=")
        s += self.NL() + self.setXYValue(sc_data.contents.depthZ,  False, "Z=")
        s += self.NL() + "KO=00"
        s += self.NL() + ".X=0.000000"  
        s += self.NL() + ".Y=0.000000" 
        s += self.NL() + ".Z=0.000000" 
        s += self.NL() + "." + "KO=00"
        s += self.NL()

        self.CountDraw = 0 # init the draw counter every startcontour
        
        self.FirstContour = True
        self.LastZ = -sc_data.contents.depthZ
        self.StartJ = False 
        return s

    def endContour(self, Data):
        ec_data = ctypes.cast(Data, ctypes.POINTER(SEndContourData))        
        s = ''
        
        #In this section of the driver if you need to find out what a particular value is Please refer to the mpr4x_format_us(4).pdf that is included in this driver folder. 
        self.h += self.NL() + "<105 " + chr(92) + "Konturfraesen" + chr(92)
        self.h += self.NL() + "EA="		+ chr(34) + self.ltos(self.CountStart)  + ":0" + chr(34)
        self.h += self.NL() + "MDA="		+ chr(34) + "SEN"		+ chr(34)
        self.h += self.NL() + "STUFEN="	+ chr(34) + "0"		+ chr(34)
        self.h += self.NL() + "BL="		+ chr(34) + "0"		+ chr(34)
        self.h += self.NL() + "WZS="		+ chr(34) + "1"		+ chr(34)
        self.h += self.NL() + "OSZI="		+ chr(34) + "0"		+ chr(34)
        self.h += self.NL() + "OSZVS="		+ chr(34) + "0"		+ chr(34)
        self.h += self.NL() + "ZSTART="	+ chr(34) + "0"		+ chr(34)
        self.h += self.NL() + "ANZZST="	+ chr(34) + "0"		+ chr(34)
        self.h += self.NL() + "RK="		+ chr(34) + self.m_toolC + chr(34) # this line has been comented out so that the tool compensation can be easily turned on.
        self.h += self.NL() + "EE="		+ chr(34) + self.ltos(self.CountStart) + ":" + self.ltos(self.CountDraw) + chr(34)
        self.h += self.NL() + "MDE="		+ chr(34) + "SEN_AB"	+ chr(34)
        self.h += self.NL() + "EM="		+ chr(34) + self.dw		+ chr(34) # I don't think I understsand this one, it can be 1 or 0
        self.h += self.NL() + "RI="		+ chr(34) + "1"		+ chr(34)
        self.h += self.NL() + "TNO="		+ chr(34) + self.ltos(self.ToolNum) + chr(34)				#"10" + cstr(m.ToolNum) + chr(34)
        self.h += self.NL() + "SM="		+ chr(34) + "1"		+ chr(34)	
        self.h += self.NL() + "S_A="		+ chr(34) + self.ltos(int(self.Spin)) + chr(34)

        m_Diez = 6 # Does this change the amount of decimal points?
        self.h += self.NL() + "F_="		+ chr(34) + self.ltos(int(self.LastFeed / 1000)) + chr(34) # Dividing the Feed by 1000 so that it will show in Meters per minute instead of MM per Minute.
        m_Diez = 4 # Change it back to normal amount

        self.h += self.NL() + "AB="		+ chr(34) + "0"		+ chr(34)
        self.h += self.NL() + "AF="		+ chr(34) + "0"		+ chr(34)
        self.h += self.NL() + "AW="		+ chr(34) + "0"		+ chr(34)
        self.h += self.NL() + "BW="		+ chr(34) + "0"		+ chr(34)
        self.h += self.NL() + "VLS="		+ chr(34) + "0"		+ chr(34)
        self.h += self.NL() + "VLE="		+ chr(34) + "0"		+ chr(34)
        self.h += self.NL() + "ZA="		+ chr(34) + "@0"		+ chr(34)	#for most Weeke machines I have found that this needs to be set at "@0"
        self.h += self.NL() + "SC="		+ chr(34) + "0"		+ chr(34)  
        self.h += self.NL() + "HP="		+ chr(34) + "0"		+ chr(34)
        self.h += self.NL() + "SP="		+ chr(34) + "0"		+ chr(34)
        self.h += self.NL() + "YVE="		+ chr(34) + "0"		+ chr(34)
        self.h += self.NL() + "WW="		+ chr(34) + "1,2,3"	+ chr(34)	# can leave out the WW record, it is auto generated
        self.h += self.NL() + "ASG="		+ chr(34) + "2"		+ chr(34)
        self.h += self.NL() + "KG="		+ chr(34) + "1"		+ chr(34)
        self.h += self.NL() + "RP="		+ chr(34) + "STANDARD" + chr(34)
        self.h += self.NL() + "RSEL="		+ chr(34) + "0"		+ chr(34)
        self.h += self.NL() + "RWID="		+ chr(34) + "0"		+ chr(34)
        self.h += self.NL() + "KAT="		+ chr(34) + "Frasen"	+ chr(34)
        self.h += self.NL() + "MNM="		+ chr(34) + "Frasen"	+ chr(34)
        self.h += self.NL() + "ORI="		+ chr(34) + ""			+ chr(34)
        self.h += self.NL() + "MX="		+ chr(34) + "0"		+ chr(34)
        self.h += self.NL() + "MY="		+ chr(34) + "0"		+ chr(34)
        self.h += self.NL() + "MZ="		+ chr(34) + "0"		+ chr(34)
        self.h += self.NL() + "MXF="		+ chr(34) + "1"		+ chr(34)
        self.h += self.NL() + "MYF="		+ chr(34) + "0"		+ chr(34)
        self.h += self.NL() + "MZF="		+ chr(34) + "1"		+ chr(34)
        self.h += self.NL() + "SYA="		+ chr(34) + "0"		+ chr(34)
        self.h += self.NL() + "SYV="		+ chr(34) + "0"		+ chr(34)
        self.h += self.NL()
	
        return s

    def drawArc(self, Data):
        da_data = ctypes.cast(Data, ctypes.POINTER(SDrawArcData))
        s = ''
        strDS = ''

        if (da_data.contents.direction == TArcDirection.PtArcCW): #added and extra =
            strDS = "DS=0"  
        else:
            strDS = "DS=1"  

        # This is where the drawing gets done for arcs

        self.CountDraw += 1
        s += self.NL() + "$E" + self.ltos(self.CountDraw)
        s += self.NL() + "KA"
        s += self.NL() + self.setXYValue(da_data.contents.targetX, False, "X=") 
        s += self.NL() + self.setXYValue(da_data.contents.targetY, False, "Y=")
        s += self.NL() + self.setXYValue(da_data.contents.targetZ,  False, "Z=")
        s += self.NL() + strDS
        s += self.NL() + self.setXYValue(da_data.contents.radius, False,  "R=")
        s += self.NL() + ".X=0.000"
        s += self.NL() + ".Y=0.000"
        s += self.NL() + ".Z=0.000"
        s += self.NL() + ".I=0.000"
        s += self.NL() + ".J=0.000"
        s += self.NL() + ".DS=0"
        s += self.NL() + ".R=0.000"
        s += self.NL() + self.setXYValue( ( (da_data.contents.startAngle + 90) * PID180), False, ".WI=")
        s += self.NL() + self.setXYValue( ( (da_data.contents.endAngle + 90) * PID180), False, ".WO=")
        s += self.NL() + self.setXYValue( 0, False, ".WAZ=")
        s += self.NL()

        self.LastFeed = da_data.contents.feed
        self.FirstContour = False
        return s

    def drawXYZ(self, Data):
        dxyz_data = ctypes.cast(Data, ctypes.POINTER(SDrawXYZData))
        s = ''
        if (not self.FirstContour):
            self.CountDraw += 1
            s += self.NL() + "$E" + self.ltos(self.CountDraw)
            s += self.NL() + "KL"
            s += self.NL() + self.setXYValue(dxyz_data.contents.targetX, False, "X=") 
            s += self.NL() + self.setXYValue(dxyz_data.contents.targetY, False, "Y=")
            s += self.NL() + self.setXYValue(dxyz_data.contents.targetZ,  False, "Z=") #These four lines were for a specific model of Weeke
            s += self.NL() + ".X=0.000000"  
            s += self.NL() + ".Y=0.000000"
            s += self.NL() + ".Z=0.000000"
            s += self.NL() + ".KO=00"
            s += self.NL()

        self.LastFeed = dxyz_data.contents.feed
        self.FirstContour = False
        return s

    def toolChange(self, Data):
        tc_data = ctypes.cast(Data, ctypes.POINTER(SToolChangeData))
        
        s = self.writeHeaderIfNec()

        self.ToolName = tc_data.contents.toolName
        self.ToolNum = tc_data.contents.toolNum	#' tools 1 2 3 are ouput as 201, 202, 203 ect...
        self.TC = True
        return s
        
    def rollFeed(self, Data):
        rf_data = ctypes.cast(Data, ctypes.POINTER(SRollFeedData))
        self.Material = rf_data.contents.panelLength
        if (self.Material == 0):
            self.Material = 33.0
        return ''
        
    def setSpin (self, Data):
        ss_data = ctypes.cast(Data, ctypes.POINTER(SSetSpinData))
        if (self.TC):
            self.Spin = ss_data.contents.spin		# todo: KM=commented out, wip
        return ''
        
    def drillType(self, Data):
        dt_data = ctypes.cast(Data, ctypes.POINTER(SDrillTypeData))
        DrillingZ = ((-dt_data.contents.targetZ - (self.Material)) * (-1))

        if (dt_data.contents.drilltype == 1): # let me know that  drill bank is on
            pass # todo : if drilltype is equal to 1 it means that we are using the drill bank
        elif (dt_data.contents.drilltype == 0):
            #  if drilltype is equal to 0 it means that we are using the drill function with no drill bank
            self.f += self.NL() + "<102  " + chr(92) + "BohrVert" + chr(92)
            self.f += self.NL() + "XA=" + chr(34) + '{0:.1f}'.format(dt_data.contents.targetX) + chr(34)
            self.f += self.NL() + "YA=" + chr(34) + '{0:.1f}'.format(dt_data.contents.targetY) + chr(34)
			
            #   This if statement is controlling the drilling depth function. WoodWOP has 2 main types of drilling LS slow-fast to depth, and LSL is slow - fast - slow
            #   all the way through the material. What we are doing below is saying if the drilling depth is equal to or greater than the material depth then output the LSL which is designed for 
            #   drilling all the way through the material, otherwise just use LS.
			
            if (DrillingZ >= self.Material):
                self.f += self.NL() + "BM=" + chr(34) + "LSL" + chr(34)
            else:
                self.f += self.NL() + "BM=" + chr(34) + "LS" + chr(34)

            #   IN the line below this is where we are solving the issue with the drills using Surface at top of plate in stead of surface at
            #   bottom of plate like the routing. We are taking the Z depth and subtracting the material depth to get the right number but then
            #   having to multiply it by -1 to return it to a possitive value. 
            self.f += self.NL() + "TI=" + chr(34) + self.complexV2S((-dt_data.contents.targetZ - (self.Material)) * (-1)) + chr(34)

            #   ****************************************************************** 
            self.m_Diez = 2  #was 6
            self.f += self.NL() + "DU=" + chr(34) + self.complexV2S(dt_data.contents.reserved1) + chr(34) # todo: this line is setting all the drill diam to 8, 
            self.m_Diez = 4
            #   it should take the value from data.radius which exists but is not 
            #   being supplied by EnRoute. Once implemented by EnRoute
            #   it should be replaced by this line...below
            #   self.f += self.NL() + "DU=" + chr(34) + v2s(data.Radius) + chr(34)


            self.f += self.NL() + "AN="	+  chr(34) + "1"	+ chr(34) 
            self.f += self.NL() + "MI="	+  chr(34) + "0"	+ chr(34)
            self.f += self.NL() + "S_="	+  chr(34) + "2"	+ chr(34)
            self.f += self.NL() + "AB="	+  chr(34) + "32"	+ chr(34)
            self.f += self.NL() + "WI="	+  chr(34) + "0"	+ chr(34)
            self.f += self.NL() + "ZT=" 	+  chr(34) + "0"	+ chr(34)
            self.f += self.NL() + "RM=" 	+  chr(34) + "0"	+ chr(34)
            self.f += self.NL() + "VW=" 	+  chr(34) + "0"	+ chr(34)
            self.f += self.NL() + "HP=" 	+  chr(34) + "0"	+ chr(34)
            self.f += self.NL() + "SP=" 	+  chr(34) + "0"	+ chr(34)
            self.f += self.NL() + "YVE="	+  chr(34) + "0"	+ chr(34)
            self.f += self.NL() + "WW=" 	+  chr(34) + "60,61,62,90,91,92,150,190" + chr(34)
            self.f += self.NL() + "ASG="	+  chr(34) + "2"	+ chr(34)
            self.f += self.NL() + "KAT="	+  chr(34) + "Bohren vertikal" + chr(34)
            self.f += self.NL() + "MNM="	+  chr(34) + "Bohren vertikal" + chr(34)
            self.f += self.NL() + "ORI="	+  chr(34) + ""	+ chr(34)
            self.f += self.NL() + "MX=" 	+  chr(34) + "0"	+ chr(34)
            self.f += self.NL() + "MY="	+  chr(34) + "0"	+ chr(34)
            self.f += self.NL() + "MZ="	+  chr(34) + "0"	+ chr(34)
            self.f += self.NL() + "MXF="	+  chr(34) + "1"	+ chr(34)
            self.f += self.NL() + "MYF="	+  chr(34) + "1"	+ chr(34)
            self.f += self.NL() + "MZF="	+  chr(34) + "1"	+ chr(34)
            self.f += self.NL() + "SYA="	+  chr(34) + "0"	+ chr(34)
            self.f += self.NL() + "SYV="	+  chr(34) + "0"	+ chr(34)   		
            self.f += self.NL() + "KO="	+  chr(34) + "00"	+ chr(34) 
            self.f += self.NL()

        return ''
        
    def message(self, Data):
        msg_data = ctypes.cast(Data, ctypes.POINTER(SMessageData))

        r = ""
        str1 = str(msg_data.contents.msg, 'utf-8')
            
        # Ezy Nest exes built after Nov2003 now have two Message calls, giving filepath and exepath like this:
        #	FILE=C:\MachiningOut\CCKNew_ManualG1.cnc
        #	APP=F:\Program Files\QuisineSoftware\Quisine Ezy Nest\Ezy Nest.
        #  so here we extract the two strings for use later
             
        r = str1[:5]
        # Here we are defining the toolcomp values. WoodWop does not use G41 G42, but instead uses WRKR and WRKL	
        Hold = 0

        if (str1[:2] == "TC"):
            if (str1.find("Right") > -1):
                self.m_toolC = "WRKR" #right toolcomp 
            elif (str1.find("Left") > -1): 
                self.m_toolC = "WRKL" #left toolcomp 
            else: 
                self.m_toolC = "NOWRK"
        elif (str1[:3] == "APP"): 
            Hold = str1.rfind('\\') # looking only for one \ 
            self.m_cnfPath = str1[4:Hold] # this path includes the / at the end
        
        if (r == "VER=5"):
            self.DeleteOutput = "true"
        elif (r == "VER=6"):
            self.DeleteOutput = "false"
            
        return ''

def createDriver():
    global drv
    drv = Homag()    
    return True
    
def processCommand(idCmd, Data):
    return drv.processCommand(idCmd, Data)