


from tkinter.constants import X


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,vol=default_vol,hub=default_hub,fe=default_fe,top=default_top):
        super().__init__()
        self.vol = float(vol)
        self.fe = float(fe)
        self.hub = float(hub)
        self.top = float(top)
        self.aktvol = 0
    
    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 sendXY(self):
        return f'<G1 X{self.x} Y{self.y} F{self.fe}>\n'

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

    def get_tip(self,l):
        self.up()
        self.x = l[0]
        self.y = l[1]
        self.z = l[2]
        return self.sendXY()

    def go_down(self):
        self.e = self.top + self.hub
        return self.sendE()

    def amIdown(self):
        if self.e == self.top +self.hub :
            return True
        else:
            return False

    def up(self):
        return f'<G1 Z0 F{self.fe}>\n'

    def down(self):
        return f'<G1 Z{self.z} F{self.fe}>\n'
    
    def setXY(self,l):
        self.x=l[0]
        self.y=l[1]
    
    def setZ(self,z):
        self.z = z

    def getVol(self):
        return self.aktvol
    
    def setVol(self,v):
        self.aktvol =v
    
    def setVolMax(self):
        self.aktvol = self.vol
        self.e = self.top

    def dispenseVol(self,vol):
        ok = True
        if self.aktvol >= vol :
            self.aktvol = self.aktvol - vol
            dx = (self.hub * vol)/self.vol
            self.e = self.e + dx
        else:
            ok = False
        return ok

    def clearVol(self):
        self.dispenseVol(self.aktvol)
        


    

        

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 two tips
            """

    def __init__(self,xoffset,yoffset,z,rows,cols,deltax,deltay):
        self.xoffset = float(xoffset)
        self.yoffset = float(yoffset)
        self.rows = int(rows)
        self.columns = int(cols)
        self.anz = self.rows * self.columns
        self.deltax = float(deltax)
        self.deltay = float(deltay)
        self.z = float(z)
  
        self.akt = 0
    
    
    def next(self):
        if self.akt == self.anz:
            print(f'akt ={self.akt} anz= {self.anz}')
            return f'No more tips !!'
        else :
            self.akt += 1
            r = (self.akt -1) % self.columns
            c = (self.akt -1) // self.columns
            x = self.xoffset + (r * self.deltax)
            y = self.yoffset + (c * self.deltay)
            print(f'x={x} y= {y} akt= {self.akt}')
            return x,y,self.z

    def same(self):
        r = (self.akt -1) % self.columns
        c = (self.akt -1) // self.columns
        x = self.xoffset + (r * self.deltax)
        y = self.yoffset + (c * self.deltay)
        print(f'x={x} y= {y} akt= {self.akt}')
        return x,y,self.z

    def say_ok(self):
        print(self.anz)

class LabReactBlock(LabPipBlock):

    def __init__(self, xoffset, yoffset, z, rows, cols, deltax, deltay):
        super().__init__(float(xoffset), float(yoffset),float(z), int(rows), int(cols), float(deltax), float(deltay))
    

class ChemLoc():
    """ Chemikalien Lokation zloc location of surface
        vol of chemical
        change of surface per ml """

    def __init__(self,xloc,yloc,zloc,vol,deltaz,chemvol):
        self.xloc = float(xloc)
        self.yloc = float(yloc)
        self.zloc = float(zloc)
        self.vol = float(vol)
        self.deltaz = float(deltaz)
        self.chemvol = float(chemvol)

    def getXY(self):
        return self.xloc,self.yloc

    def load(self,ml):
        if self.vol > ml:
            z = self.zloc 
            self.zloc = self.zloc + self.deltaz*ml
            self.vol = self.vol - ml
            return z
        else:
            return 0




    
#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,4,6,108,86)
    pip = LabPip(vol=500)
    pip.fe =5000
    for i in range(20):
        print(pip.get_tip(lpb.next()))
