'''
Created on Jun 14, 2012

@author: manuel
'''


class SyringePump(object):
    '''
    This is an abstract class that declares the functions available
    to control a syringe pump of any brand
    '''
    _units = ['mL/hr', 'mL/min', 'uL/hr', 'uL/min']
    _directions = ['STOP', 'INFUSION', 'WITHDRAWAL']

    def __init__(self):
        '''
        constructor
        '''
        raise NotImplementedError("Constructor needs to be implemented")

    def __del__(self):
        '''
        Destructor to cleanly close the serial object if need
        '''
        raise NotImplementedError()

    def start(self):
        '''
        starts the pump with the parameters defined beforehand
        '''
        raise NotImplementedError()

    def stop(self):
        '''
        stops the pump
        '''
        raise NotImplementedError()

    def reverse(self):
        '''
        reverse the flow of the pump (if available)
        '''
        raise NotImplementedError()

    def isRunning(self):
        '''
        returns True if the pump is running (infusion or withdrawing)
        and False if it is stopped
        '''
        raise NotImplementedError()

    def clearAccumulatedVolume(self):
        '''
        resets to 0 the volume of liquid pumped
        '''
        raise NotImplementedError()

    def clearTargetVolume(self):
        '''
        clears the target volume for the pump. This should put the pump in
        continuous injection mode
        '''
        raise NotImplementedError()

    def setDirection(self, inValue):
        '''
        defines the direction that the pump will run.
        inValue is an int representation of the directions that the pump is capable of running in
        '''
        raise NotImplementedError()

    def setSyringeDiameter(self, inValue):
        '''
        defines the diameter of the syringe in mm
        '''
        raise NotImplementedError()

    def setRate(self, inValue, inUnits):
        '''
        sets the rate of the pump
        optionally, one can also change the units (see set units)
        '''
        raise NotImplementedError()

    def setTargetVolume(self, inValue):
        '''
        puts the pump in fixed amount mode and defines the volume
        after which it will stop pumping
        '''
        raise NotImplementedError()

    def getDiameter(self):
        '''
        returns the current diameter (in mm) of the syringe
        '''
        raise NotImplementedError()

    def getRate(self):
        '''
        returns the current rate of pumping as a float
        '''
        raise NotImplementedError()

    def getUnits(self):
        '''
        return the current units as an int
        '''
        raise NotImplementedError()

    def getAccumulatedVolume(self):
        '''
        returns the amount of liquid pumped so far as a float. Units might vary
        '''
        raise NotImplementedError()

    def getTargetVolume(self):
        """
        returns the target volume for the pump as a float. Units might vary
        """
        raise NotImplementedError()

    def getTargetUnits(self):
        """
        returns the units for the target volume as a string
        """
        raise NotImplementedError()

    def getDirection(self):
        """
        returns the current direction of the pump as an int
        """
        raise NotImplementedError()

    def getPossibleUnits(self):
        """
        returns an array of the possible units accepted by this pump
        """
        raise NotImplementedError()


class SyringePumpException(Exception):
    pass


class valueOORException(SyringePumpException):
    pass


class unknownCommandException(SyringePumpException):
    pass


class pumpNotRunningException(SyringePumpException):
    pass


class pumpNotStoppedException(SyringePumpException):
    pass


class pumpInvalidAnswerException(SyringePumpException):
    pass


class invalidCommandException(SyringePumpException):
    pass


class unforseenException(SyringePumpException):
    pass
