

"""
Module with input and output int bit addresssable classes.

Loosely based on Castironpi's BitSet code

"""




class inbits(object):
	"""
	This is an 8 bit int of more or less addressable bits.
	"""

	def __init__ (self, io, value = 0, position = 0, *args ):
		"""This constructs the int that keeps the bits,
		   and makes a getter function for each named bit from *args,
		   so that we can retreive them by instance.bitname(),
		   as well as by bool = instance[index_position]
		   The position argument is the the card number.
		   The value is the initial byte start value.
		"""

		self.io = io
		self.value = value		# this is the overall byte value
		self.position = position
		for i,name in enumerate(args):
			def __getbit__(idx = i):
#	Real i/o code has to be added here to read the right byte - we read the pseudoports
				return self.__getitem__(idx)
			self.__dict__[name] = __getbit__

	def __setitem__( self, index, value ):
		"""Here we can set a bit based on its position."""

		self.value = ord(self.io.inputs[self.position])
		if value:
			self.value |= (1 << index)
		else:
			self.value &= ~ (1 << index)

	def __getitem__( self, index ):
		"""This retreives a bit based on its position."""

		self.value = ord(self.io.inputs[self.position])
		return 1 if self.value & (1<< index ) else 0

	def __repr__( self ):
		self.value = ord(self.io.inputs[self.position])
		return repr( self.value )



class outbits(object):
	"""
	This is an 8 bit int of more or less addressable bits.
	"""

	def __init__ (self, io, value = 0, position = 0, *args ):
		"""This constructs the int that keeps the bits,
		   and makes a setter function for each named bit from *args,
		   so that we can set them by instance.bitname(bool),
		   as well as by instance[index_position] = bool
		   io is the module (prolly gpio) that does the actual i/o
		   value is the initial value to set the byte to.
		   position is the card number in the list.
		"""

		self.io = io
		self.value = value
		self.position = position
		for i,name in enumerate(args):
			def __setbit__(value,idx = i):
				self.__setitem__(idx,value)
#	Real i/o code here to write the right byte out  - we set the pseudoport up
			self.__dict__[name] = __setbit__

	def __setitem__( self, index, value ):
		"""Here we can set a bit based on its position."""

		self.value = self.io.outputs[self.position]
		if value:
			self.value |= (1 << index)
		else:
			self.value &= ~ (1 << index)
		self.io.outputs[self.position] = self.value

	def __getitem__( self, index ):
		"""This retreives a bit based on its position."""

		self.value = self.io.outputs[self.position]
		return 1 if self.value & (1<< index ) else 0

	def __repr__( self ):
		self.value = self.io.outputs[self.position]
		return repr( self.value )



if __name__== '__main__':

	import time

	import gpio as io

#	err = io.initialise_par_io(2,2,0.001)
	err = io.initialise_ser_io(2,2,0.001)
	io.outputs = [0,0]
	in0  = inbits(io,0,0,'b0','b1','b2','b3','b4','b5','b6','b7')
	out0 = outbits(io,0,0,'b0','b1','b2','b3','b4','b5','b6','b7')
	in1  = inbits(io,0,1,'b0','b1','b2','b3','b4','b5','b6','b7')
	out1 = outbits(io,0,1,'b0','b1','b2','b3','b4','b5','b6','b7')

	inputs = io.inputs

	while True:
		start_time = time.time()
		io.outputs = [0,0]
		io.input_alert = 0
		time.sleep(0.5)
		out0[0] = 1
		out1[7] = 1
		time.sleep(0.5)
		out0[1] = 1
		out1[6] = 1
		time.sleep(0.5)
		out0[2] = 1
		out1[5] = 1
		time.sleep(0.5)
		out0[3] = 1
		out1[4] = 1
		time.sleep(0.5)
		out0[4] = 1
		out1[3] = 1
		time.sleep(0.5)
		out0[5] = 1
		out1[2] = 1
		time.sleep(0.5)
		out0[6] = 1
		out1[1] = 1
		time.sleep(0.5)
		out0[7] = 1
		out1[0] = 1
		time.sleep(0.5)
		out0[0] = 0
		out1[7] = 0
		time.sleep(0.5)
		out0[1] = 0
		out1[6] = 0
		time.sleep(0.5)
		out0[2] = 0
		out1[5] = 0
		time.sleep(0.5)
		out0[3] = 0
		out1[4] = 0
		time.sleep(0.5)
		out0[4] = 0
		out1[3] = 0
		time.sleep(0.5)
		out0[5] = 0
		out1[2] = 0
		time.sleep(0.5)
		out0[6] = 0
		out1[1] = 0
		time.sleep(0.5)
		out0[7] = 0
		out1[0] = 0
		print
		print 'That took',time.time()-start_time,'seconds'
		if io.input_alert:
			print 'inputs have changed to:',in0,in1
		else:
			print 'inputs are:',in0,in1

