'''
map manager
Bed and Bunk

'''

call BB(object):
    def at(self,x,y):
        '''
        return all tag under x,y in the grid
        '''
        raise NotImplementedError()

    def sym(self,x,y):
        '''
        return unique top symbol under x,y in the grid
        '''
        raise NotImplementedError()

class Bed(object):
    '''
    handle one defenition
    '''
	def __init__(self,bedDict={}):
		self._bedDict = bedDict
		self._grid = bedDict['grid'] if 'grid' in bedDict else []
		self._legend = bedDict['legend'] if 'legend' in bedDict else []
		self._x = bedDict['x'] if 'x' in bedDict else 0
		self._y = bedDict['y'] if 'y' in bedDict else 0

	def at(self,x,y):
		'''
		return all tag linked to all symbol found in cell
		where x and y match
		'''
		return [	tag
				for yy,row in enumerate(self._grid)
				for xx,cell in enumerate(row)
				for pillow in self._legend
				for tag in pillow['tag']
				if xx == x-self._x
				and yy == y-self._y
				and cell == pillow['symbol']
			]

	def sym(self,x,y):
		if y in range(len(self._grid)) and x in range(len(self._grid[y])):
			return self._grid[y][x]
		return ' '

class Bunk(object):
    '''
    handle a list of definition
    '''
	def __init__(self,bedDictLst=[]):
		self._bedDictLst = [	Bed(bedDict) 
					for bedDict in bedDictLst	]

	def at(self,x,y):
		return [	tag
				for bed in self._bedDictLst
				for tag in bed.at(x,y)
			]

	def sym(self,x,y):
		for bed in self._bedDictLst:
			c = bed.sym(x,y)
			if c != ' ':
				return c
		return ' '

class Sheet(object):
    '''
    handle non destrutive change to anonther BB
    '''
	def __init__(self,bed,changeLst=[]):
		self._bed = bed
		self._change = change

	def at(self,x,y):
		taglst = [	tag
				for change in self._change
				for tag in change['tag']
				if change['x'] == x
				and change['y'] == y 	]
		if not taglst:
			taglst = self._bed.at(x,y)
		return taglst

def sprite(bed,x,y,w,h):
    '''
    extract one sprite using sym function
    '''
	return [	[	bed.sym(xx,yy)
				for xx in range(x,x+w)	]
			for yy in range(y,y+h)	]

if __name__ == '__main__':
	sample = {
		'grid' : [
			"#####",
			"#   #",
			"# ~ #",
			"#  t#",
			"#####"
		],
		'legend' : [
			{
				'symbol' : '#',
				'tag' : ['wall','impassable']
			},
			{
				'symbol' : '~',
				'tag' : ['water','slipery']
			},
			{
				'symbol' : 't',
				'tag' : ['tree']
			}
		]
	}

	sample2 = [
		sample,
		{
			'x' : 1,
			'y' : 1,
			'grid' : [
				"...",
				"...",
				"..."
			],
			'legend' : [
				{
					'symbol' : '.',
					'tag' : ['floor']
				}
			]
		}
	]

	bed = Bed(sample)
	print(bed.at(-1,-1))
	print(bed.at(0,0))
	print(bed.at(1,1))
	print(bed.at(2,2))
	print(bed.at(3,3))
	print(bed.at(4,4))
	print(bed.at(5,5))

	bunk = Bunk(sample2)
	print(bunk.at(-1,-1))
	print(bunk.at(0,0))
	print(bunk.at(1,1))
	print(bunk.at(2,2))
	print(bunk.at(3,3))
	print(bunk.at(4,4))
	print(bunk.at(5,5))

	for line in sprite(bunk,0,0,5,5):
		print line
