


class LabPis:
    """ Point in Lab Space | e.g. Point of a pipette tip"""
    default_x = 0
    default_y = 0
    default_z = 0
    default_e = 0       # e.g piston position
    default_id = 0

    def __init__(self, x=default_x,y=default_y,z=default_z,id=default_id,e=default_e):
        self.x = x
        self.y = y
        self.z = z
        self.e = e
        self.id = id

    def __str__(self) -> str:
        return(f'<id= {self.id}|x={self.x}|y={self.y}|z={self.z}|e={self.e}>')

class LabPip(LabPis):
    default_vol = 1000      # pipette volume
    default_top = 20        # piston top position
    default_hub = 10        # piston max hub
    default_fe = 2000       # speed piston

    def __init__(self, x=LabPis.default_x, y=LabPis.default_y, z=LabPis.default_z, id=LabPis.default_id, e=LabPis.default_e,
                vol=default_vol,hub=default_hub,fe=default_fe,top=default_top):
        super().__init__(x=x, y=y, z=z, id=id, e=e)
        self.vol = vol
        self.fe = fe
        self.hub = hub
        self.top = top
    
    def __str__(self) -> str:
        return super().__str__()[:-1]+f'|top={self.top}|hub={self.hub}|vol={self.vol}|fe={self.fe}>'

    def sendE(self):
        return f'<G1 P{self.e} F{self.fe}>\n'
    
    def sendXYZ(self):
        return f'<G1 X{self.x} Y{self.y} Z{self.z} F{self.fe}>\n'

    def go_top(self):
        self.e=self.top
        return self.sendE() 

    def get_tip(self,l):
        self.x = l[0]
        self.y = l[1]
        self.z = l[2]
        return self.go_top() + self.sendXYZ()

    def up(self):
        self.z = 0
        return self.sendXYZ()
        

class LabPipBlock():
    """ Pipettenblock description 
            x_offset, y_offset of first tip,
            z for take a tip,
            number of rows and columns,
            deltax,deltay space between first and last tips
            """

    def __init__(self,xoffset,yoffset,z,anz,rows,deltax,deltay):
        self.xoffset = xoffset
        self.yoffset = yoffset
        self.anz = anz
        self.rows = rows
        self.columns = anz / rows
        self.deltax = deltax
        self.deltay = deltay
        self.z = z
        self.akt = 0
    
    def next(self):
        if self.akt == self.anz:
            return f'No more tips !!'
        else :
            r = self.anz / self.rows
            m = self.akt % r    # column
            c = self.akt // r   # row
            self.akt += 1
            x = self.xoffset + (m * self.deltax/self.columns)
            y = self.yoffset + (c * self.deltay/self.rows)
            return x,y,self.z

    

#Job 100myl of A in Vial 1
#v1 = LabPis(200,200,100,21)
#a1 = LabPis(100,100,100,1)
#p1 = LabPis()
if __name__ == '__main__':
    lpb = LabPipBlock(16,1,78,20,5,116,86)
    pip = LabPip(vol=500)
    pip.fe =5000
    for i in range(20):
        print(pip.get_tip(lpb.next()))
