import tofu, soya, soya.sdlconst as sdlconst, soya.tofu4soya as tofu4soya, soya._soya, soya.widget as widget, soya.opengl as opengl
import balazar_brothers, balazar_brothers.sound, balazar_brothers.globdef as globdef

class Bubble(widget.Label):
  def __init__(self, master = None, pos = 0, text = None, color = None):
    widget.Label.__init__(self, master, text, color = color)
    
    self.position   = soya.Point()
    self.discussion = None
    self.pos        = pos
    
    if   pos == -1: self.resize_style = [ 'parent left',         'parent top', ('percent width', 0.33)]
    elif pos ==  0: self.resize_style = [("percent left", 0.335), 'parent top', ('percent width', 0.33)]
    else:           self.resize_style = [("percent left", 0.67 ), 'parent top', ('percent width', 0.33)]
    
  def build_display_list(self):
    self.height = self.font.wordwrap(self._text, self.width - 10)[1] + 15.0
    opengl.glColor4f(*self._color)
    self._font.draw_area(self._text, self.left + 5, self.top + 3, 0.0, self.width - 10, self.height, self._align)
    
  def render(self):
    if not self.discussion: return
    
    opengl.glPushMatrix()
    opengl.glTranslatef(self.left, self.top, 0.0)
    
    soya.DEFAULT_MATERIAL.activate()
    opengl.glEnable(opengl.GL_BLEND)
    opengl.glColor4f(1.0, 1.0, 1.0, 0.9)
    opengl.glBegin(opengl.GL_POLYGON)
    opengl.glVertex2i(0, 0)
    
    if self.pos == -1:
      opengl.glVertex2f(0.0              , self.height)
    else:
      opengl.glVertex2f(0.0              , self.height - 15.0)
      opengl.glVertex2f(5.0              , self.height -  5.0)
      opengl.glVertex2f(15.0             , self.height)
      
    if self.pos ==  1:
      opengl.glVertex2f(self.width       , self.height)
    else:
      opengl.glVertex2f(self.width - 15.0, self.height)
      opengl.glVertex2f(self.width - 5.0 , self.height -  5.0)
      opengl.glVertex2f(self.width       , self.height - 15.0)
      
    opengl.glVertex2f(self.width, 0.0)
    opengl.glEnd()
    
    if self.discussion.character:
      self.position.__init__(self.discussion.character, 0.0, 2.6, 0.0)
      x, y = tofu.GAME_INTERFACE.camera.coord3d_to_2d(self.position)
      
      opengl.glBegin(opengl.GL_TRIANGLES)
      opengl.glVertex2f(self.width * 0.55, self.height)
      opengl.glVertex2f(self.width * 0.45, self.height)
      opengl.glColor4f(1.0, 1.0, 1.0, 0.1)
      opengl.glVertex2f(x - self.left, max(y, self.height + 20.0) - self.top)
      opengl.glEnd()
      opengl.glDisable(opengl.GL_BLEND)
      
    opengl.glPopMatrix()
    
    widget.Label.render(self)


class Discussion(object):
  def __init__(self, gettext_key, characters = {}, radius = 5.0):
    self.gettext_key = gettext_key
    self.text        = _(gettext_key)
    self.validable   = 0
    self.characters  = characters
    self.radius      = radius
    
    from balazar_brothers.character import Balazar, RedBalazar
    
    names = gettext_key[:-2].split("_")
    self.character = self._find_character(names[-1])
    if isinstance(self.character, Balazar):
      self.npc = self._find_character(names[-2])
      self.validable = 1
      if isinstance(self.character, RedBalazar): self.text = self.text + u"\n\n" + _("__press_left_shift__" )
      else:                                      self.text = self.text + u"\n\n" + _("__press_right_shift__")
    else:
      self.npc = self.character
      
    if self.validable:
      self.replies = []
      self.character.current_discussion = self
    else:
      self.replies = self.find_replies()
      
  def _find_character(self, name):
    if   name == "None":                return None
    elif name == "npc" :                return self.npc
    elif self.characters.has_key(name): return self.characters[name]
    else:
      for i in soya.IDLER.scenes[0].recursive():
        if (getattr(i, "name", "") == name) or (i.__class__.__name__ == name): return i

  def can_say(self):
    can_say = getattr((self.npc or self), "can_say_" + self.gettext_key, None)
    if can_say: return can_say()
    return 1
  
  def show(self):
    if not tofu.GAME_INTERFACE.traveling.characters: return
    
    if   self.character == tofu.GAME_INTERFACE.traveling.characters[ 0]: self.bubble = tofu.GAME_INTERFACE.left_bubble
    elif self.character == tofu.GAME_INTERFACE.traveling.characters[-1]: self.bubble = tofu.GAME_INTERFACE.right_bubble
    else:                                                                self.bubble = tofu.GAME_INTERFACE.middle_bubble
    self.bubble.discussion = self
    self.bubble.text       = self.text
    
    soya.IDLER.scenes[0].listener.reset()
    
    for reply in self.replies:
      reply.show()
      #self.character.doer.action_done(DiscussionState(self, reply.gettext_key))
      
  def hide(self):
    self.bubble.discussion = None
    self.bubble = None
    if self.character and (self.character.current_discussion is self):
      self.character.current_discussion = None
      
  def begin_round(self):
    if self.npc:
      for character in tofu.GAME_INTERFACE.traveling.characters:
        if character.distance_to(self.npc) > self.radius + 0.1:
          self.bubble.hide()
          
  def find_replies(self):
    if   hasattr(self.character, "have_said%s" % self.gettext_key): replies = getattr(self.character, "have_said%s" % self.gettext_key)(self) or []
    elif hasattr(self.npc,       "have_said%s" % self.gettext_key): replies = getattr(self.npc      , "have_said%s" % self.gettext_key)(self) or []
    else:                                                           replies = []
    
    nb_ = self.gettext_key.count("_") + 1
    start = self.gettext_key[:-1]
    
    for key in globdef.translator._catalog.keys():
      if key.startswith(start) and (key.count("_") == nb_):
        replies.append(Discussion(key, self.characters, self.radius))
        
    return replies
  
  def on_validate(self):
    if self.validable and tofu.GAME_INTERFACE:
      if tofu.GAME_INTERFACE.left_bubble  .discussion: tofu.GAME_INTERFACE.left_bubble  .discussion.hide()
      if tofu.GAME_INTERFACE.middle_bubble.discussion: tofu.GAME_INTERFACE.middle_bubble.discussion.hide()
      if tofu.GAME_INTERFACE.right_bubble .discussion: tofu.GAME_INTERFACE.right_bubble .discussion.hide()
      
    for reply in self.find_replies():
      self.character.start_discussion(reply.gettext_key)
      
      
  def can_say___help5_None__(self): return isinstance(self.characters["owner"], balazar_brothers.character.BlueBalazar)
  
