'''
1. silences the pronunciation of "<" and ">" in key combinations such as <Ctrl><Alt>K
2. annouces a specific task and its currently-associated shortcut at the same time
3. informs the user the enter a new shortcut when pressed Enter

@author: Andy Shi
@organization: UNC Chapel Hill
@copyright: Copyright (c) 2007, Andy Shi
@license: BSD

All rights reserved. This program and the accompanying materials are made 
available under the terms of the BSD which is available at
http://www.opensource.org/licenses/bsd-license.php
'''
# import useful modules for Perks
import Perk, Task, AEConstants
from POR import POR
from i18n import bind, _

# metadata describing this Perk
__uie__ = dict(kind='perk', tier='gnome-keybinding-properties', all_tiers=False)

# to support translation of strings in this Perk, uncomment the following line
# and provide the proper domain and path to your translation file
# _ = bind(domain, locale_dir)

class keyboard_binding(Perk.Perk):
  '''
  This perk registers the classes that handle gnome keybinding dialog.
  '''
  def init(self):
    self.registerTask(HandleErrorWindows('error window'))
    self.registerTask(HandleNewAngleBrackets('new angle brackets'))
    self.registerTask(HandleExistingAngleBrackets('old angle brackets'))
    self.registerTask(HandleGeneralAnnouncement('general announcement'))
    self.registerTask(EnterNewShortcut('new shortcut'))
    self.registerTask(ReadPerkName('read perk name'))
    kbd = self.getInputDevice(None, 'keyboard')
    self.addInputModifiers(kbd, kbd.AEK_CAPS_LOCK)
    self.registerCommand(kbd, 'read perk name', False, 
                         [kbd.AEK_CAPS_LOCK, kbd.AEK_A])
    self.registerCommand(kbd, 'general announcement', False,
                         [kbd.AEK_CAPS_LOCK, kbd.AEK_H])
    self.registerCommand(kbd, 'new shortcut', True,
                         [kbd.AEK_ENTER])
                         
  def getDescription(self):
    return _('Applies to gnome-keybinding-properties by default.')

class ReadPerkName(Task.InputTask):
  '''
  Example Task that announces the name of this Perk.
  '''
  def execute(self, **kwargs):
    self.stopNow()
    self.sayInfo(text='keyboard_binding handling an input gesture')

class HandleGeneralAnnouncement(Task.InputTask):
  '''
  Tell users how to define a new shortcut
  '''
  def execute(self, **kwargs):
    por = self.getRootAcc()
    announcement = self.getAccFromPath(por, 0,0,0,1,1)
    self.stopNow()
    self.inhibitMayStop()
    self.sayItem(announcement)

class HandleErrorWindows(Task.ViewTask):
  '''
  Inform the users when an error window pops up
  '''
  def executeGained(self, por, **kwargs):
    if self.hasAccRole('alert', por):
      self.doTask('read all')
      self.blockNTasks(1, Task.SelectorTask)
      return False

class HandleNewAngleBrackets(Task.CaretTask):
  '''
  Read the new shortcut with all angle brackets removed
  '''
  def executeDeleted(self, por, text, text_offset, **kwargs):
    self.inhibitMayStop()
    self.blockNTasks(1, Task.FocusTask)
    return False
  def executeInserted(self, por, text, text_offset, **kwargs):
    text = text.replace('<', '')
    text = text.replace('>', '-')
    self.inhibitMayStop()
    self.sayInfo(text=text)
    self.blockNTasks(1, Task.FocusTask)
    self.blockNTasks(1, Task.SelectorTask)
    return False

class HandleExistingAngleBrackets(Task.SelectorTask):
  '''
  Remove the angle brackets and replace with a dash between Control, Alt, Shift, and other keys
  '''
  def executeActive(self, por, text, **kwargs):
    # check if the selected text is a defined shortcut, excluding special cases
    bracketFound = False
    for n in text:
      if (n == '<' or n == '>'):
        bracketFound = True
        break
      else:
        bracketFound = False
    # contains at least a pair of '<,>'
    if bracketFound == True:
      pPOR = self.getPrevItem()
      pText = self.getAccName(pPOR)
      # removes all occurrences of '<' and '>'
      text = text.replace('<', '')
      text = text.replace('>', '-')
      self.inhibitMayStop()
      self.sayItem(text=pText)
      self.sayInfo(text=text)
      self.blockNTasks(1, Task.FocusTask)
      return False
    # contains no '<' or '>'
    else:
      # special shortcuts
      # add more here
      if (text == 'Disabled' or 
          text == 'XF86AudioPause' or
          text == 'XF86AudioStop' or
          text == 'XF86AudioPrev' or
          text == 'XF86AudioNext' or
          text == 'XF86AudioPlay' or
          text == 'Print' or
          text == 'Tab'):
        pPOR = self.getPrevItem()
        pText = self.getAccName(pPOR)
        # POR at the section title
        if (pText == 'Desktop' or 
            pText == 'Sound' or
            pText == 'Window Management'):
          self.inhibitMayStop()
          self.sayItem(text=pText)
          self.blockNTasks(1, Task.FocusTask)
          return False
        else:
          self.inhibitMayStop()
          self.sayItem(text=pText)
          self.sayInfo(text=text)
          self.blockNTasks(1, Task.FocusTask)
          return False
      # POR at the section title
      elif (text == 'Action' or
            text == 'Shortcut' or
            text == 'Desktop' or
            text == 'Sound' or
            text == 'Window Management'):
        self.inhibitMayStop()
        self.sayItem(text=text)
        self.blockNTasks(1, Task.FocusTask)
        return False
      # POR within the dialog
      else:
        nPOR = self.getNextItem()
        nText = self.getAccName(nPOR)
        nText = nText.replace('<', '')
        nText = nText.replace('>', '-')
        self.inhibitMayStop()
        self.sayItem(text=text)
        self.sayInfo(text=nText)
        self.blockNTasks(1, Task.FocusTask)
        return False

class EnterNewShortcut(Task.InputTask):
  '''
  When pressed enter, announce the phrase New Accerlerator.
  '''
  def execute(self, **kwargs):
    self.stopNow()
    self.inhibitMayStop()
    self.sayItem(text='New Accelerator')
