# -*- Mode: Python; tab-width: 4 -*-

from fifo import fifo

class output_fifo:
	
	EMBEDDED	= 'embedded'
	EOF			= 'eof'
	TRIGGER		= 'trigger'

	def __init__ (self):
		# containment, not inheritance
		self.fifo = fifo()
		self._embedded = None

	def push_embedded (self, fifo):
		# push embedded fifo
		fifo.parent = self # CYCLE
		self.fifo.push ((self.EMBEDDED, fifo))

	def push_eof (self):
		# push end-of-fifo
		self.fifo.push ((self.EOF, thunk))

	def push_trigger (self, thunk):
		self.fifo.push ((self.TRIGGER, thunk))

	def push (self, item):
		# item should be a producer or string
		self.fifo.push (item)

	# 'length' is an inaccurate term.  we should
	# probably use an 'empty' method instead.
	def __len__ (self):
		if self._embedded:
			return len(self._embedded)
		else:
			return len(self.fifo)

	def first (self):
		if self._embedded:
			return self._embedded.first()
		else:
			return self.fifo.first()

	def pop (self):
		if self._embedded:
			return self._embedded.pop()
		else:
			result = self.fifo.pop()
			# check for special items in the front
			if len(self.fifo):
				front = self.fifo.first()
				if type(front) is type(()):
					# special
					kind, value = front
					if kind is self.EMBEDDED:
						self._embedded = value
					elif kind is self.EOF:
						# break the cycle
						parent = self.parent
						self.parent = None
						# pop from parent
						parent.pop()
					elif kind is self.TRIGGER:
						# call the trigger thunk
						value()
					# remove the special
					self.fifo.pop()
			# return the originally popped result
			return result
