'''
Defines a L{Perk} for the GNOME Terminal.

@author: Peter Parente
@author: Brett Clippingdale
@author: Eitan Isaacson
@author: Scott Haeger
@author: Luiz Rocha
@organization: IBM Corporation
@copyright: Copyright (c) 2005, 2007 IBM Corporation
@license: The BSD License

All rights reserved. This program and the accompanying materials are made 
available under the terms of the BSD license which accompanies
this distribution, and is available at
U{http://www.opensource.org/licenses/bsd-license.php}
'''
import Perk, Task
import AEConstants
from POR import POR
from i18n import bind, _

__uie__ = dict(kind='perk', tier='gnome-terminal', all_tiers=False)

class GTerminalPerk(Perk.Perk):
  '''
  '''
  def init(self):
    '''
    '''
    # set an audio device as the default output
    self.setPerkIdealOutput('audio')

    # registering tasks
    self.registerTask(HandleTerminalCaret('gterm read caret'))

    # chain to other tasks
    self.chainTask('gterm read caret', AEConstants.CHAIN_AROUND, 'read caret')

    # initialize little nice cool perk variables
    self.actions = {None: 'move', False: 'delete', True: 'insert'}
    self.move_keys = ['Left', 'Right']
    self.delete_keys = ['Delete', 'BackSpace']
    self.ret_key = 'Return'
    self.last_key = None
    self.prev_key = None

  def getName(self):
    return _('GNOME Terminal')

  def getDescription(self):
    return _('Improve general accessibility of the GNOME Terminal.')

class HandleTerminalCaret(Task.CaretTask):
  '''
  '''
  def execute(self, por, text, text_offset, added, **kwargs):
    '''
    '''
    # handling only terminal events
    if not self.hasAccRole('terminal') or None in self.getLastKey():
      return False

    # last key pressed in gterm is our current key
    self.perk.last_key = self.getLastKey()

    # propagate to chained tasks by default
    propagate = True

    if self.perk.actions[added] == 'insert':
      # if the current key is a Return, the terminal is probably responding to
      # some user input. the avalanche of events gterm sends might break the
      # speech output. inhibit the next stop to prevent this.
      if self.perk.last_key[1] == self.perk.ret_key:
        self.inhibitMayStop()
        propagate = True
      else:
        propagate = True
    elif self.perk.actions[added] == 'move':
      # ignore "bundled" move events from the terminal. we'll react only when
      # a move key is pressed
      if (not self.perk.last_key[1] in self.perk.move_keys or
          self.perk.prev_key[1] == self.perk.ret_key):
        # do not propagate
        propagate = False
      else:
        # move key pressed, let BasicSpeech handle it
        propagate = True
    elif self.perk.actions[added] == 'delete':
      # ignore "bundled" delete events received from gterm. react only when a
      # delete (delete/backspace) key was pressed
      if (not self.perk.last_key[1] in self.perk.delete_keys or
          self.perk.prev_key[1] == self.perk.ret_key):
        # do not propagate
        propagate = False
      else:
        # delete key pressed, let BasicSpeech handle it
        propagate = True
    else:
      # propagate and let BasicSpeechPerk handle anything we missed here
      propagate = True

    # store keyboard input for future comparisons
    self.perk.prev_key = self.perk.last_key
    # return True to let BasicSpeechPerk act on the event too or False to end
    # event handling here
    return propagate

