import brlapi
import AEOutput

__uie__ = dict(kind='device')

class BrlAPIStyle(AEOutput.StyleFlyweight):
  '''
  Overrides the base L{AEOutput.Style.StyleFlyweight} class to provide style
  settings relative to the default style for this device.
  '''
  pass

  def getSettings(self):
    pass

class BrlAPIStyleDefault(AEOutput.StyleDefault):
  '''
  Overrides the base L{AEOutput.Style.StyleDefault} class, filling in 
  fields for supported style properties with their appropriate values.
  '''
  pass

  def getSettings(self):
    pass

class BrlAPIDevice(AEOutput.Braille):
  
  USE_THREAD = False
  DEFAULT_STYLE = BrlAPIStyleDefault
  FLYWEIGHT_STYLE = BrlAPIStyle

  def init(self):
    '''
    Initializes the braille interface.
    
    @raise AEOutput.InitError: When the device can not be initialized
    '''
    self.outbuf = []
    self.brlconn = None
    
    try:
      self.brlconn = brlapi.Connection()
      # TODO: might not be best place to enter tty.  
      self.brlconn.enterTtyMode()
    except:  #ConnectionError, OperationError
      # raise AEOutput.InitError
      pass
    
  def createDistinctStyles(self, num_groups, num_layers):
    '''
    Creates distinct styles following the guidelines set forth in the base
    class. 
    
    @param num_groups: Number of sematic groups the requestor would like to
      represent using distinct styles
    @type num_groups: integer
    @param num_layers: Number of content origins (e.g. output originating from
      a background task versus the focus) the requestor would like to represent
      using distinct styles
    @type num_layers: integer   
    @return: Styles
    @rtype: list of L{AEOutput.Style}
    ''' 
    styles = []
    for i in xrange(num_groups*num_layers):
      s = BrlAPIStyle(self.default_style)
      styles.append(s)
    return styles
  
  def close(self):
    '''
    Closes the braille device.
    '''
    # TODO: how to close connection ?
    self.brlconn.leaveTtyMode()
    
    self.outbuf = []
    self.brlconn = None
    
  def sendString(self, text, style):
    '''
    Adds the given string to the text to be output to braille device.

    @param text: String to buffer on the device
    @type text: string
    @param style: Style with which this string should be output; None means no
      style change should be applied
    @type style: integer
    '''
    self.outbuf.append(text)
  
  def sendTalk(self, style=None):
    '''
    Begins output of the buffered text.
    
    @param style: Ignored
    @type style: L{AEOutput.Style}
    '''
    self.brlconn.writeText(''.join(self.outbuf))
    self.outbuf = []
    
  def isActive(self):
    '''
    Indicates whether the device has text waiting to be output.

    @return: True if the braille device has text to be output, False otherwise
    @rtype: boolean
    '''
    if len(self.outbuf) > 0:
      return True
    else:
      return False
  
  def sendStop(self, style=None):
    '''
    Stops braille output immediately.
    
    @param style: Ignored
    @type style: L{AEOutput.Style}
    '''
    self.outbuf = []

    # TODO: leavetty?
    
  def addIndexListener(self, bogus):
    pass