'''
This LSR perk is for the Gnome Magnifier (magnifier).

@author: George Kraft IV <gk4@austin.ibm.com>
@organization: IBM Corp
@copyright: Copyright (c) 2006 IBM Corp
@license: CPL

All rights reserved. This program and the accompanying materials are made 
available under the terms of the CPL which is available at
U{http://opensource.org}
'''
# import useful modules for Perks
import Perk, Task
import ORBit, bonobo
from POR import POR
from i18n import bind, _

ORBit.load_typelib('GNOME_Magnifier')
import GNOME.Magnifier

# metadata describing this Perk
__uie__ = dict(kind='perk', tier=None, all_tiers=True)

MAGNIFIER_IID   = "OAFIID:GNOME_Magnifier_Magnifier:0.9"
MAGNIFIER_OBJ   = "GNOME/Magnifier/Magnifier"
MIN_FACTOR      = 1.0
MAX_FACTOR      = 16.0
MAG_STEP        = 1.0


# 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 GnomeMagnifierState(Perk.PerkState):
  '''
  Settings for the Gnome Magnifier (magnifier).
  http://bugzilla.gnome.org/show_bug.cgi?id=358183
  '''

  RunMag = False
  FullScreen = False
  MouseTrack = True
  Zoom = 4
  ZoomMin = 1
  ZoomMax = 16

  def getSettings(self):
    g = self._newGroup()
    g.newBool('RunMag', _('Start Magnifier'),
       _('Start magnifier with screen reader.'))
    g.newBool('FullScreen', _('Full Screen'),
       _('Magnify in full screen mode.'))
    g.newBool('MouseTrack', _('Track Mouse'),
       _('Magnifier is to track mouse movement.'))
    g.newRange('Zoom', _('Zoom Factor'), self.ZoomMin, self.ZoomMax, 1,
       _('Change the magnification zoom factor.'))

    return g

class GnomeMagPerk(Perk.Perk):
  '''
  Example Perk template. Use this file as a way to get started writing your 
  own Tasks and creating your own keyboard bindings. The getDescription method
  should be changed to return a translated description of this Perk. The 
  description should include a statement of which Tiers this Perk applies to
  by default.
  '''

  STATE=GnomeMagnifierState

  def init(self):
    print 'GnomeMagPerk Initialized'

    self.initialize()
    self.registerTask(IncreaseZoom('increase zoom'))
    self.registerTask(DecreaseZoom('decrease zoom'))
    self.registerTask(HandleFocusChange('default focus'))
    self.registerTask(HandleSelectorChange('default selector'))
    self.registerTask(HandleCaretChange('default caret'))
    self.registerTask(MouseTrack())

    kbd = self.getInputDevice('Keyboard')
    self.addInputModifiers(kbd, kbd.AEK_ALT_L, kbd.AEK_SHIFT_L, 
       kbd.AEK_ALT_R, kbd.AEK_SHIFT_R) 

    pairs = [[kbd.AEK_ALT_L, kbd.AEK_SHIFT_L], [kbd.AEK_ALT_R, kbd.AEK_SHIFT_R]]

    for pair in pairs:
      self.registerCommand(kbd, 'increase zoom', False,pair+[kbd.AEK_UP])
      self.registerCommand(kbd, 'decrease zoom', False,pair+[kbd.AEK_DOWN])
                         
  def getDescription(self):
    return _('Gnome Magnifier.')

  def initialize(self):
    '''
    Initialize the Magnifier AT.
    '''
   
    orb = ORBit.CORBA.ORB_init()
   
    # get a reference to the gnome Accessibility registry
    data = bonobo.activation.activate_from_id(MAGNIFIER_IID)
   
    if data is None:
      raise RuntimeError('Could not activate:', MAGNIFIER_IID)
   
    self.mag = bonobo.get_object(MAGNIFIER_IID, MAGNIFIER_OBJ)
   
    zoomRegions = self.mag.getZoomRegions()
   
    for z in zoomRegions:
      self.zoom = z
   
    self.roi = self.zoom.getROI();
    '''
    http://bugzilla.gnome.org/show_bug.cgi?id=359071
    pb = self.zoom.getProperties()
    bonobo.pbclient_set_boolean(pb, "mouse-follow", True)
    http://bugzilla.gnome.org/show_bug.cgi?id=358189
    '''

  def close(self):
    '''
    Shutdown the Magnifier AT.
    http://bugzilla.gnome.org/show_bug.cgi?id=359113
    FIXEME: rename "close()" when the above referenced bug is fixed.
    '''

    if self.mag is None:
      return

    self.mag.clearAllZoomRegions()
    self.mag.dispose()

    self.mag = None

class HandleFocusChange(Task.FocusTask):
  '''
  This will handle focus change POR.
  '''

  def executeGained(self, **kwargs):
    '''
    self.say(text='Magnifier handle focus change please')
    '''

class HandleCaretChange(Task.CaretTask):
  '''
  This will handle caret change POR.
  '''

  def execute(self, **kwargs):
    '''
    self.say(text='Magnifier handle caret change please')
    '''

class HandleSelectorChange(Task.SelectorTask):
  '''
  This will handle selector change POR.
  '''

  def execute(self, **kwargs):
    '''
    self.say(text='Magnifier handle selector change please')
    '''

class IncreaseZoom(Task.InputTask):
  '''
  Increase the zoom factor.
  '''

  def execute(self, **kwargs):

    if self.perk.mag is None:
      return

    (magX, magY) = self.perk.zoom.getMagFactor()
    magX = magX + MAG_STEP
    magY = magY + MAG_STEP
    if ((magX <= MAX_FACTOR) and (magY <= MAX_FACTOR)):
      if not self.perk.zoom.setMagFactor(magX, magY):
        RuntimeError(_('Could not increase magnification.'))

class DecreaseZoom(Task.InputTask):
  '''
  Decrease the zoom factor.
  '''

  def execute(self, **kwargs):

    if self.perk.mag is None:
      return

    (magX, magY) = self.perk.zoom.getMagFactor()
    magX = magX - MAG_STEP
    magY = magY - MAG_STEP
    if ((magX >= MIN_FACTOR) and (magY >= MIN_FACTOR)):
      if not self.perk.zoom.setMagFactor(magX, magY):
        RuntimeError(_('Could not increase magnification.'))


class MouseTrack(Task.MouseTask):
  '''
  Used when magnifier should follow pointer.
  '''

  def execute(self, kind, pos, button, **kwargs):
    '''
    Execute on each mouse event, for now we only look at cursor movements.
    '''

    if kind != self.MOVE:
      return True

    x, y = pos

    self.perk.roi = self._centerROI(x, y)

    self.perk.zoom.setROI(self.perk.roi)
    return True

  def _centerROI (self, x, y):      
    w = self.perk.roi.x2 - self.perk.roi.x1
    h = self.perk.roi.y2 - self.perk.roi.y1

    return GNOME.Magnifier.RectBounds (x - w/2,
                                       y - h/2,
                                       x + w - w/2,
                                       y + h - h/2)
