################################################################
#
#   Bell Runner - Exit
#
################################################################

from pygame import Rect
from albow.resource import get_image, get_sound
from albow.image_array import get_image_array
from albow.controls import TextField
from level import Item
from notes import NotesField, pitches_to_notes, notes_to_pitches

score_image = get_image("score.png")
note_images = get_image_array("note.png", (2, 2))
open_sound = get_sound("door_open.ogg")

score_left_width = 25
score_right_width = 20
score_height = score_image.get_height()
score_clearance = 10

note_baseline = 7
note_advance = 10
note_line_spacing = 3
note_head_offset = 3


class Exit(Item):

	resource_prefix = "exits"
	layer_name = 'gadgets'
	filename_suffix = "-closed.png"
	editable = True
	is_exit = True

	open = False
	sequence_done = 0

	def __init__(self, rect, image_name):
		Item.__init__(self, rect, image_name)
		self.open_image_name = image_name.replace("closed", "open")
		self.sequence = []
	
	def reset(self):
		self.open = False
		self.sequence_done = 0
	
	def create_edit_fields(self, fields):
		fields.append(('sequence', "Bell Sequence", NotesField(200)))
	
	def load_edit_fields(self, fields):
		fields.sequence.set_text(pitches_to_notes(self.sequence))
	
	def unload_edit_fields(self, fields):
		self.sequence = notes_to_pitches(fields.sequence.get_text())

	def current_image_name(self):
		if self.open:
			return self.open_image_name
		else:
			return self.image_name

	def draw(self, surf):
		Item.draw(self, surf)
		n = len(self.sequence) 
		dr = Rect(0, 0,
			score_left_width + n * note_advance + score_right_width,
			score_height)
		dr.centerx = self.rect.centerx
		dr.bottom = self.rect.top - score_clearance
		sr = Rect(0, 0, dr.width - score_right_width, score_height)
		surf.blit(score_image, dr, sr)
		sr = Rect(score_image.get_width() - score_right_width, 0,
			score_right_width, score_height)
		surf.blit(score_image, (dr.right - score_right_width, dr.top), sr)
		x = dr.left + score_left_width
		y0 = dr.bottom - note_baseline
		k = self.sequence_done
		r = note_images.get_rect()
		for i, p in enumerate(self.sequence):
			flip = p > 4
			note_image = note_images[flip, i < k]
			y = y0 - p * note_line_spacing
			if flip:
				r.topleft = (x, y - note_head_offset)
			else:
				r.bottomleft = (x, y + note_head_offset)
			surf.blit(note_image, r)
			x += note_advance

	def bell_rung(self, pitch):
		seq = self.sequence
		n = len(seq)
		if n > 0:
			i = self.sequence_done
			if i < n:
				if seq[i] == pitch:
					i += 1
					if i == n:
						self.open = True
						open_sound.play()
				else:
					i = 0
					if seq[i] == pitch:
						i += 1
				self.sequence_done = i

	def actor_nearby(self, level, actor):
		if self.open and actor is level.player:
			rect = self.rect
			r = Rect(rect.left, rect.bottom - 10, rect.width, 11)
			if r.collidepoint(actor.position):
				level.level_completed()
