""" list controls for pudding """

__revision__ = '$Revision: 0.1 $'

import soya

import soya.pudding as pudding
import soya.pudding.core
import soya.pudding.control
import soya.pudding.container

class HighlightText( soya.pudding.control.Label ):
  def __init__( self, parentWidget, text ):
    soya.pudding.control.Label.__init__( self, parentWidget, text )

  def highlight( self, enabled ):
    if enabled:
      self.color = ( 1.00, 1.00, 1.00, 1.00 )
    else:
      self.color = ( 0.5, 0.5, 0.5, 1.00 )

def limit( number, maxSize, minSize ):
  return max( minSize, min( maxSize, number ) )

class ListBox( pudding.core.Control, pudding.core.InputControl):
  """ Simple List.

  Value may be set with mouse scroll wheel or by clicking in the list.
  If the top object is selected the list is scrolled up,
  selecting the last object in the list scrolls it down.
  """

  def __get_value__(self):
    return self._value

  def __set_value__(self, val):
    self._value = val

    if self.value < self.min: 
      self.value = self. min
    elif self.value > self.max:
      self.value = self.max 

    self.on_set_value()

  value = property(__get_value__, __set_value__)

  def __init__(self, parentWidget, maxObjects, objectStringList, **kwargs):
    ''' create a list of strings, maxObjects define number of lines in the list to show strings
    the objectStingList is a list of strings to be shown in the list, to be mouse-wheel selectable
    the width and size has to be defined on init
    '''

    pudding.core.Control.__init__(self, parentWidget, **kwargs)
    pudding.core.InputControl.__init__(self)

    if maxObjects < 3:
      print "listbox::__init__ : WARNING using lower values for a listbox may cause problems"
    self.maxObjects = maxObjects
    monospaceFont = soya.Font(soya.pudding.sysfont.SysFont('freemono, couriernew'), 15,15 )
    self.textHeight = monospaceFont.get_print_size('X')[0]

    # not yet used, could dynamically set the box size depending on text / list
    height = self.textHeight * self.maxObjects * 2 + 3

    self.containerBox = soya.pudding.control.Box( parentWidget, height=kwargs['height'], width=kwargs['width'] )
    self.containerBox.z_index = -1
    self.container = soya.pudding.container.VerticalContainer( parentWidget, height=kwargs['height'], width=kwargs['width'] )
    self.objectStringList = objectStringList

    self.listText = list()
    for i in xrange( self.maxObjects ):
      self.listText.append( HighlightText( self.container, "" ) )
      self.listText[-1].font = monospaceFont

    self.startObject = 0
    self.activeObject = 0

    self.update()

  def update( self ):
    # update visible list on screen
    i = self.startObject
    for c in self.listText:
      if i < len(self.objectStringList):
        c.visible = True
        c.label = self.objectStringList[i]
        if i == self.activeObject:
          c.highlight( True )
        else:
          c.highlight( False )
        i += 1
      else:
        c.visible = False
        c.label = ''

  def on_mouse_down(self, x, y, button):
    if button == 4:
      # scoll button up
      self.activeObject -= 1
      if self.activeObject < 0:
        self.activeObject = 0
    elif button == 5:
      # scroll button down
      self.activeObject += 1
    elif button == 1:
      # select with mouse
      obj = int((y/self.textHeight)/2 + self.startObject) # why / 2 ???
      self.activeObject = obj

    # active object max not be bigger then amout of objects and smaller then 0
    self.activeObject = limit( self.activeObject, len( self.objectStringList ) - 1, 0 )
    # move visible part of list depending on active Object
    self.startObject = limit( self.startObject, self.activeObject - 1, self.activeObject - ( self.maxObjects - 2 ) )
    # limit startObject from 0 to length of strings - showedStrings
    self.startObject = limit( self.startObject, len( self.objectStringList ) - self.maxObjects, 0 )
    # bugfix for list length 1
    if self.maxObjects == 1:
      self.startObject = self.activeObject
    self.update()

    return True

  def get_selected_item_number( self ):
    return self.activeObject

  def get_selected_item_name( self ):
    return self.objectStringList[ self.activeObject ]

  def clear_all_items( self ):
    self.objectStringList = []

  def add_item( self, itemName ):
    self.objectStringList.append( itemName )
    self.update()

  def remove_item( self, itemName ):
    self.objectStringList.remove( itemName )
    self.update()

  def set_list_lenght( self, length ):
    self.maxObjects = length

  def process_event(self, event):
    return pudding.core.InputControl.process_event(self, event)

  def on_set_value(self):
    pass

