
import curses, moves, pimobj

class Player (pimobj.Object):

	def __init__( s, world, x, y, stwin ):
		s.world = world
		s.x = x
		s.y = y
		s.stwin = stwin
		s.world.add_obj( s, x, y )
		s.stwin.box()
		s.curr_obj = 0
		s.holdings = []
		s.key_handlers = {
			curses.KEY_UP: (s.handle_move, moves.up),
			curses.KEY_RIGHT: (s.handle_move, moves.rt),
			curses.KEY_LEFT: (s.handle_move, moves.lt),
			curses.KEY_DOWN: (s.handle_move, moves.dn),
			ord(' '): (s.handle_pick, None),
			ord('a'): (s.handle_drop, None),

			ord('z'): (s.handle_play, 0),
			ord('s'): (s.handle_play, 1),
			ord('x'): (s.handle_play, 2),
			ord('d'): (s.handle_play, 3),
			ord('c'): (s.handle_play, 4),
			ord('v'): (s.handle_play, 5),
			ord('g'): (s.handle_play, 6),
			ord('b'): (s.handle_play, 7),
			ord('h'): (s.handle_play, 8),
			ord('n'): (s.handle_play, 9),
			ord('j'): (s.handle_play, 10),
			ord('m'): (s.handle_play, 11),
			ord(','): (s.handle_play, 12),
			ord('l'): (s.handle_play, 13),
			ord('.'): (s.handle_play, 14),

			ord('1'): (s.handle_change, 0),
			ord('2'): (s.handle_change, 1),
			ord('3'): (s.handle_change, 2),
			ord('4'): (s.handle_change, 3),
			ord('5'): (s.handle_change, 4),
			ord('6'): (s.handle_change, 5),
			ord('7'): (s.handle_change, 6),
			ord('8'): (s.handle_change, 7)
		}

	def handle_keypress( s, key ):
		try:
			handler, arg = s.key_handlers[key]
			handler(arg)
			return True
		except KeyError: return False

	def handle_move( s, d ):
		try: s.x, s.y = moves.move_in_world( s, s.world, s.x, s.y, d )
		except moves.NonPermeable: pass

	def handle_pick( s, ignore ):
		pickables = [ obj for obj in s.world.objs_at( s.x, s.y )
				if obj.pickable( s ) ]
		if not pickables: s.handle_drop( None )
		for o in pickables:
			s.world.rm_obj( o, s.x, s.y )
			o.move_notify( None, None )
		s.holdings.extend( pickables )
		s.draw_holdings()

	def handle_drop( s, ignore ):
		try: obj = s.holdings[s.curr_obj]
		except IndexError: return
		del s.holdings[s.curr_obj]
		if s.curr_obj >= len( s.holdings ): s.curr_obj = 0
		s.world.add_obj( obj, s.x, s.y )
		obj.move_notify( s.x, s.y )
		s.draw_holdings()

	def handle_play( s, pitch ):
		try: obj = s.holdings[s.curr_obj]
		except IndexError: return
		obj.play( pitch )
		s.draw_holdings()

	def handle_change( s, idx ):
		if idx >= len( s.holdings ): return
		s.curr_obj = idx
		obj = s.holdings[s.curr_obj].collide( s, moves.dot )
		s.draw_holdings()

	def draw_holdings( s ):
		s.stwin.erase()
		s.stwin.box()
		max_y, max_x = s.stwin.getmaxyx()
		for idx in range( min( len( s.holdings ), max_y - 2 )):
			row = idx + 1
			o = s.holdings[idx]
			s.stwin.addstr( row, 1, "%d%s" %
					( row, [ '.', '!' ][idx==s.curr_obj] ))
			o.draw( s.stwin, 4, row )

	# object methods

	def pickable( s, obj ):
		return False

	def permeable( s, obj ):
		return obj.pickable( s )

	def draw( s, scr, x, y ):
		scr.addch( y, x, '@', curses.A_BOLD )

