#
# $Id: data.py,v 1.1.1.1 2003/03/22 05:15:49 dbelan2 Exp $
#
# Data structures to store the model.
#
# $Log: data.py,v $
# Revision 1.1.1.1  2003/03/22 05:15:49  dbelan2
# Initial import of all public_html on www.cs.mcgill.ca.
#
# Revision 1.10  2001/10/01 20:49:53  dbelan2
# Removed printing of debuging info.
#
# Revision 1.9  2001/10/01 03:05:41  hchen19
# bug fixed in calcOutput() of class Adder and class Divider
#
# Revision 1.7  2001/09/27 17:55:56  hchen19
# Bug fixed: caclOutput() of some blocks
#
# Revision 1.6  2001/09/23 23:31:07  dbelan2
# - Old constructors commented out.
# - Bug fix in one calcOutput().
#
# Revision 1.5  2001/09/22 00:32:18  dbelan2
# Added Relay class, commented out Output class.
#
# Revision 1.4  2001/09/20 21:05:11  dbelan2
# Added __str__() method.
#
# Revision 1.3  2001/09/20 18:14:09  dbelan2
# Basic simulator running.  No cycle test.  Output is updated.
# But still need to test if output OK.
#
# Revision 1.2  2001/09/20 17:34:08  dbelan2
# - syntax errors fixed in several calcOutput()
# - changed init() to take name
#
# Revision 1.1  2001/09/20 15:57:07  dbelan2
# Basic data structure design, may need improvement.
#
#
#

# The most general class representing a block in the system
class Block:

    #  def __init__(name = None, inputs = None, outputs = None):
    def __init__(self, name = ''):
        self.name = name
        self.inputs, self.outputs = [], []
        self.output_value = 0
        self.v = None   # v is Vertex associated

    def addInput(self, input):
        self.inputs.append(input)

    def addOutput(self, output):
        self.outputs.append(output)

    def calcOutput(self):
        pass

    def __str__(self):
        return self.name

    #def getOutputValue():
    #    return self.output_value

    #def setOutputValue(value):
    #    self.output_value = value


#class WeightedSum:
#

#step_size = 0

class Adder(Block):

    def __init__(self, name):
        Block.__init__(self, name)

    def calcOutput(self):
        #self.output_value = 
        #pass
        self.output_value=self.inputs[0].output_value+self.inputs[1].output_value

class Integrator(Block):

    def __init__(self, name):
        Block.__init__(self, name)

    def getIC(self):
        # assuming its input1
        for obj in self.inputs:
            if isinstance(obj, Constant):
                return obj.value
        return None  # return 0?

    def calcOutput(self, step_size):
        self.output_value = self.output_value + step_size * self.inputs[1].output_value
        #print self.output_value, self.name

class Negator(Block):
    def __init__(self, name):
        Block.__init__(self, name)

    def calcOutput(self):
        self.output_value = -self.inputs[0].output_value


class Multiplier(Block):
    def __init__(self, name):
        Block.__init__(self, name)

#    def __init__(self, inputs, outputs):
#        Block.__init__(self, None, inputs, outputs)

    def calcOutput(self):
        self.output_value = self.inputs[0].output_value * self.inputs[1].output_value
        

class Divider(Block):
    def __init__(self, name):
        Block.__init__(self, name)

    def calcOutput(self):
        self.output_value=self.inputs[0].output_value/self.inputs[1].output_value
#    def __init__(self, inputs, outputs):
#        Block.__init__(self, None, inputs, outputs)


#    def calcOutput(self, inputs, outputs):
#        self.output_value = self.inputs[1] / self.inputs[2]


# Is a constant a block?
class Constant(Block):
    # put a doc string
    def __init__(self, name):
        Block.__init__(self, name)
        self.value = 0

#    def __init__(self, value, outputs):
#        self.value = value
#        Block.__init__(self, None, None, outputs)

    def calcOutput(self):
        self.output_value = self.value


class Relay(Block):
    def __init__(self, name):
        Block.__init__(self, name)

    def calcOutput(self):
        # relay the value to all outputs
        for output in self.outputs:
            output.output_value = self.inputs[0].output_value
            
## Note: no Output object in simclasses?
## class Output(Block):
##     def __init__(self, name):
##         Block.__init__(self, name)

##     #def __init__(self, inputs):
##     #    Block.__init__(self, None, inputs, None)

##     def calcOutput(self):
##         self.output_value = self.inputs[0]
##         print 'time =  , output = ' + `self.output_value`


class Model:

    def __init__(self):
        self.blocks = []

#    def addBlock(self, block):
#        self.blockList.append(block)

#    def getBlocks(self):
#        return blockList
    







