class MitosisPy(StepperPy, Field3DChangeWatcherPy):
    def __init__(self, _changeWatcher):
        Field3DChangeWatcherPy.__init__(self, _changeWatcher)

        self.mitosisPlugin = MitosisSimplePlugin()
        self.doublingVolume = 50
        self.mitosisPlugin.setDoublingVolume(self.doublingVolume)
        self.mitosisPlugin.init(self.changeWatcher.sim)
        self.mitosisPlugin.turnOn(
        )  #has to be called after init to make sure vectors are allocated
        self.counter = 0
        self.mitosisFlag = 0
        #self.childCell
        #self.parentCell
    def setPotts(self, potts):
        self.mitosisPlugin.setPotts(potts)

    def field3DChange(self):
        if self.changeWatcher.newCell and self.changeWatcher.newCell.volume > self.doublingVolume:
            print "BIG CELL I WILL DO MITOSIS"
            self.mitosisPlugin.field3DChange(self.changeWatcher.changePoint,
                                             self.changeWatcher.newCell,
                                             self.changeWatcher.newCell)
            self.mitosisPlugin.setMitosisFlag(1)

    def step(self):
        mitosisDoneFlag = False
        if self.mitosisPlugin.getMitosisFlag():
            self.mitosisFlag = self.mitosisPlugin.doMitosis()
            self.childCell = self.mitosisPlugin.getChildCell()
            self.parentCell = self.mitosisPlugin.getParentCell()
            self.updateAttributes()
            self.mitosisPlugin.setMitosisFlag(0)

    def updateAttributes(self):
        print "self.parentCell.type % 2=", self.parentCell.type % 2
        if self.parentCell.type % 2:
            self.childCell.type = 2
            #self.childCell.type=self.parentCell.type
        else:
            self.childCell.type = 1
class MitosisPy (StepperPy,Field3DChangeWatcherPy):
    def __init__(self,_changeWatcher):
        Field3DChangeWatcherPy.__init__(self,_changeWatcher)

        self.mitosisPlugin=MitosisSimplePlugin()
        self.doublingVolume=50
        self.mitosisPlugin.setDoublingVolume(self.doublingVolume)        
        self.mitosisPlugin.init(self.changeWatcher.sim)
        self.mitosisPlugin.turnOn() #has to be called after init to make sure vectors are allocated
        self.counter=0
        self.mitosisFlag=0
        #self.childCell
        #self.parentCell
    def setPotts(self,potts):
        self.mitosisPlugin.setPotts(potts)
    def field3DChange(self):
        if self.changeWatcher.newCell and self.changeWatcher.newCell.volume>self.doublingVolume:
            print "BIG CELL I WILL DO MITOSIS"
            self.mitosisPlugin.field3DChange(self.changeWatcher.changePoint,self.changeWatcher.newCell,self.changeWatcher.newCell)
            self.mitosisPlugin.setMitosisFlag(1)
            

    def step(self):
        mitosisDoneFlag=False
        if self.mitosisPlugin.getMitosisFlag():
            self.mitosisFlag=self.mitosisPlugin.doMitosis()
            self.childCell=self.mitosisPlugin.getChildCell()
            self.parentCell=self.mitosisPlugin.getParentCell()
            self.updateAttributes()
            self.mitosisPlugin.setMitosisFlag(0)

    def updateAttributes(self):
        print "self.parentCell.type % 2=",self.parentCell.type % 2
        if self.parentCell.type % 2:
            self.childCell.type=2
            #self.childCell.type=self.parentCell.type
        else:
            self.childCell.type=1
class MitosisPyPluginBase(StepperPy,Field3DChangeWatcherPy):
    def __init__(self,_simulator,_changeWatcherRegistry,_stepperRegistry):

        Field3DChangeWatcherPy.__init__(self,_changeWatcherRegistry)
        self.simulator=_simulator
        self.mitosisPlugin=MitosisSimplePlugin()
        self.mitosisPlugin.setPotts(self.simulator.getPotts())        
        self.mitosisPlugin.init(self.changeWatcher.sim)
        self.mitosisPlugin.turnOn() #has to be called after init to make sure vectors are allocated        
        self.counter=0
        self.mitosisFlag=0
        _changeWatcherRegistry.registerPyChangeWatcher(self)
        _stepperRegistry.registerPyStepper(self)
        self.directionalMitosisFlagSet=[1,0,0]
        self.useOrientationVectorMitosis=False
        self.nx=1.0
        self.ny=0.0
        self.nz=0.0        
    
    def setPotts(self,potts):
        self.mitosisPlugin.setPotts(potts)
        
    def setDoublingVolume(self,_doublingVolume):
        self.doublingVolume=_doublingVolume;
        self.mitosisPlugin.setDoublingVolume(self.doublingVolume)
    def setDivisionAlongMajorAxis(self):
        self.directionalMitosisFlagSet=[0,1,0]
    def setDivisionAlongMinorAxis(self):
        self.directionalMitosisFlagSet=[0,0,1]
    def setNondirectionalDivision(self):
        self.directionalMitosisFlagSet=[1,0,0]        
    def setMitosisOrientationVector(self,_nx,_ny,_nz):
        self.useOrientationVectorMitosis=True    
        self.nx=_nx
        self.ny=_ny
        self.nz=_nz
    def unsetMitosisOrientationVector(self):
        self.useOrientationVectorMitosis=False    
        
    # these functions show how to extract semiminor axis. MItosis can be done  along major, minor or user specified axis
    # once you know directions of principal axec of cells you may do custom mitosis along vector derived using principal orientation vectors
    def getSemiminorVectorXY(self):        
         orientationVectors=self.mitosisPlugin.getOrientationVectorsMitosis2D_xy(self.changeWatcher.newCell)
         
         print "orientationVectors.semiminorVec=",orientationVectors.semiminorVec.x,",",orientationVectors.semiminorVec.y,",",orientationVectors.semiminorVec.z
         print "orientationVectors.semimajorVec=",orientationVectors.semimajorVec.x,",",orientationVectors.semimajorVec.y,",",orientationVectors.semimajorVec.z
         
         return orientationVectors.semiminorVec
         
    def getSemiminorVectorXY(self):        
         orientationVectors=self.mitosisPlugin.getOrientationVectorsMitosis2D_xy(self.changeWatcher.newCell)
         
         print "orientationVectors.semiminorVec=",orientationVectors.semiminorVec.x,",",orientationVectors.semiminorVec.y,",",orientationVectors.semiminorVec.z
         print "orientationVectors.semimajorVec=",orientationVectors.semimajorVec.x,",",orientationVectors.semimajorVec.y,",",orientationVectors.semimajorVec.z
         
         return orientationVectors.semimajorVec
        
    def field3DChange(self):
    
        self.newCell=self.changeWatcher.getNewCell()        
        if self.newCell and self.newCell.volume>self.doublingVolume:
        
            self.changePoint=self.changeWatcher.getChangePoint()
            self.mitosisPlugin.field3DChange(self.changePoint, \
            self.newCell, \
            self.newCell)
            self.mitosisPlugin.setMitosisFlag(1)

            
    def step(self):
        mitosisDoneFlag=False
        if self.mitosisPlugin.getMitosisFlag():
            if self.useOrientationVectorMitosis:

                mitosisDoneFlag=self.mitosisPlugin.doDirectionalMitosisOrientationVectorBased(self.nx,self.ny,self.nz)
            else:             
                if self.directionalMitosisFlagSet[0]:
                    mitosisDoneFlag=self.mitosisPlugin.doMitosis()
                    
                if self.directionalMitosisFlagSet[1]:#do mitosis along major Axis
                    self.mitosisPlugin.setDivideAlongMajorAxis()
                    # right before doing mitosis you may want to calculate division axis based on orientatin of principal axes. This is the place where you would do these calculations
                    # self.getSemiminorVectorXY()
                    
                    mitosisDoneFlag=self.mitosisPlugin.doDirectionalMitosis()
                    
                if self.directionalMitosisFlagSet[2]:#do mitosis along minor Axis
                    self.mitosisPlugin.setDivideAlongMinorAxis()
                    mitosisDoneFlag=self.mitosisPlugin.doDirectionalMitosis()
            self.childCell=self.mitosisPlugin.getChildCell()
            self.parentCell=self.mitosisPlugin.getParentCell()
            
            if mitosisDoneFlag:
                self.updateAttributes()
            self.mitosisPlugin.setMitosisFlag(0)
            
    def updateAttributes(self):
        self.childCell.targetVolume=self.parentCell.targetVolume
        self.childCell.lambdaVolume=self.parentCell.lambdaVolume
        self.childCell.type=self.parentCell.type
class MitosisPyPluginBase(StepperPy, Field3DChangeWatcherPy):
    def __init__(self, _simulator, _changeWatcherRegistry, _stepperRegistry):

        Field3DChangeWatcherPy.__init__(self, _changeWatcherRegistry)
        self.simulator = _simulator
        self.mitosisPlugin = MitosisSimplePlugin()
        self.mitosisPlugin.setPotts(self.simulator.getPotts())
        self.mitosisPlugin.init(self.changeWatcher.sim)
        self.mitosisPlugin.turnOn(
        )  #has to be called after init to make sure vectors are allocated
        self.counter = 0
        self.mitosisFlag = 0
        _changeWatcherRegistry.registerPyChangeWatcher(self)
        _stepperRegistry.registerPyStepper(self)
        self.directionalMitosisFlagSet = [1, 0, 0]
        self.useOrientationVectorMitosis = False
        self.nx = 1.0
        self.ny = 0.0
        self.nz = 0.0

    def setPotts(self, potts):
        self.mitosisPlugin.setPotts(potts)

    def setDoublingVolume(self, _doublingVolume):
        self.doublingVolume = _doublingVolume
        self.mitosisPlugin.setDoublingVolume(self.doublingVolume)

    def setDivisionAlongMajorAxis(self):
        self.directionalMitosisFlagSet = [0, 1, 0]

    def setDivisionAlongMinorAxis(self):
        self.directionalMitosisFlagSet = [0, 0, 1]

    def setNondirectionalDivision(self):
        self.directionalMitosisFlagSet = [1, 0, 0]

    def setMitosisOrientationVector(self, _nx, _ny, _nz):
        self.useOrientationVectorMitosis = True
        self.nx = _nx
        self.ny = _ny
        self.nz = _nz

    def unsetMitosisOrientationVector(self):
        self.useOrientationVectorMitosis = False

    # these functions show how to extract semiminor axis. MItosis can be done  along major, minor or user specified axis
    # once you know directions of principal axec of cells you may do custom mitosis along vector derived using principal orientation vectors
    def getSemiminorVectorXY(self):
        orientationVectors = self.mitosisPlugin.getOrientationVectorsMitosis2D_xy(
            self.changeWatcher.newCell)

        print "orientationVectors.semiminorVec=", orientationVectors.semiminorVec.x, ",", orientationVectors.semiminorVec.y, ",", orientationVectors.semiminorVec.z
        print "orientationVectors.semimajorVec=", orientationVectors.semimajorVec.x, ",", orientationVectors.semimajorVec.y, ",", orientationVectors.semimajorVec.z

        return orientationVectors.semiminorVec

    def getSemiminorVectorXY(self):
        orientationVectors = self.mitosisPlugin.getOrientationVectorsMitosis2D_xy(
            self.changeWatcher.newCell)

        print "orientationVectors.semiminorVec=", orientationVectors.semiminorVec.x, ",", orientationVectors.semiminorVec.y, ",", orientationVectors.semiminorVec.z
        print "orientationVectors.semimajorVec=", orientationVectors.semimajorVec.x, ",", orientationVectors.semimajorVec.y, ",", orientationVectors.semimajorVec.z

        return orientationVectors.semimajorVec

    def field3DChange(self):

        self.newCell = self.changeWatcher.getNewCell()
        if self.newCell and self.newCell.volume > self.doublingVolume:

            self.changePoint = self.changeWatcher.getChangePoint()
            self.mitosisPlugin.field3DChange(self.changePoint, \
            self.newCell, \
            self.newCell)
            self.mitosisPlugin.setMitosisFlag(1)

    def step(self):
        mitosisDoneFlag = False
        if self.mitosisPlugin.getMitosisFlag():
            if self.useOrientationVectorMitosis:

                mitosisDoneFlag = self.mitosisPlugin.doDirectionalMitosisOrientationVectorBased(
                    self.nx, self.ny, self.nz)
            else:
                if self.directionalMitosisFlagSet[0]:
                    mitosisDoneFlag = self.mitosisPlugin.doMitosis()

                if self.directionalMitosisFlagSet[
                        1]:  #do mitosis along major Axis
                    self.mitosisPlugin.setDivideAlongMajorAxis()
                    # right before doing mitosis you may want to calculate division axis based on orientatin of principal axes. This is the place where you would do these calculations
                    # self.getSemiminorVectorXY()

                    mitosisDoneFlag = self.mitosisPlugin.doDirectionalMitosis()

                if self.directionalMitosisFlagSet[
                        2]:  #do mitosis along minor Axis
                    self.mitosisPlugin.setDivideAlongMinorAxis()
                    mitosisDoneFlag = self.mitosisPlugin.doDirectionalMitosis()
            self.childCell = self.mitosisPlugin.getChildCell()
            self.parentCell = self.mitosisPlugin.getParentCell()

            if mitosisDoneFlag:
                self.updateAttributes()
            self.mitosisPlugin.setMitosisFlag(0)

    def updateAttributes(self):
        self.childCell.targetVolume = self.parentCell.targetVolume
        self.childCell.lambdaVolume = self.parentCell.lambdaVolume
        self.childCell.type = self.parentCell.type