#
# This file is part of GNU Enterprise.
#
# GNU Enterprise is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2, or (at your option) any later version.
#
# GNU Enterprise is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with program; see the file COPYING. If not,
# write to the Free Software Foundation, Inc., 59 Temple Place
# - Suite 330, Boston, MA 02111-1307, USA.
#
# Copyright 2002-2007 Free Software Foundation
#
# FILE:
# ScrollBar.py
#
# DESCRIPTION:
#
# NOTES:
#


import math
import string
import curses

from constants import *
from Control import Control
from Button import Button

class ScrollBar(Control):
  """
    horizontal only :-(
  """
  def __init__(self, Parent, SBName, Y, X, W, **properties):
    Control.__init__(self,Parent,SBName,**properties)
    self.CANGETFOCUS = 1
    self.H = 1
    self.W = W
    self.Y = Y
    self.X = X
    self.PARENT = Parent
    self.SetMethod("SYSPAINT", self.Paint)
    self.SetMethod("SYSRUN",self.Run)
    self.SetMethod("GOTFOCUS", self.__GotFocus)
    self.SetMethod("LOSTFOCUS", self.__LostFocus)
    self.SetMethod("CLICK", self._ChangePos)
    self._max = 1
    self._val = 0
    self.stepsize = 1
    self.__initButtons()

  def __initButtons(self):
    if string.find(str(self.__class__), '.ScrollBar') != -1:
      Y = self.Y
      X = self.X
      W = self.W
      Parent = self.PARENT
      self.rightarrow = Button(Parent,'rightarrow',Y,X+W - 3,3,'>')
      self.rightarrow.SetMethod("CLICK",self._Inc)
      Parent.AddControl(self.rightarrow)
      self.left2arrow = Button(Parent,'left2arrow',Y,X+W - 6,3,'<')
      self.left2arrow.SetMethod("CLICK",self._Dec)
      Parent.AddControl(self.left2arrow)
      self.leftarrow = Button(Parent,'leftarrow',Y,X,3,'<')
      self.leftarrow.SetMethod("CLICK",self._Dec)
      Parent.AddControl(self.leftarrow)

  def __GotFocus(self,v1,v2,v3):
    self.FOCUS = 1
    self.Paint(None,None,None)
    return 1

  def __LostFocus(self,v1,v2,v3):
    self.FOCUS = 0
    self.Paint(None,None,None)
    return 1

  def Run(self, v1,v2,v3):
    if v1 :
      self.ExecMethod("CLICK", self, v2, v3)
    Container = self.PARENT.Screen()
    global BACKWARDS
    while 1:
      ch = Container.GetChar()
      if self.PARENT.BreakOrder(ch) :
        return
      if ch in (Container.TokNextField, Container.TokDownArrow, Container.TokUpArrow):
        BACKWARDS = 0
        if ch == Container.TokUpArrow:
          BACKWARDS = 1
        return
      elif ch == Container.TokLeftArrow:
        self._Dec(None,None,None)
      elif ch == Container.TokRightArrow:
        self._Inc(None, None, None)

  def _ChangePos(self,arg1,arg2,newX):
    X = newX - self.start
    if X >= (self.WorkingArea-1):
      val = self._max
    else:
      val = float(X) / self.stepsize
      val = int(math.ceil(val))
    self.Set(val)
    self._Action()

  def Init(self, Max):
    self._max = Max
    self._val = 0
    self.WorkingArea = float(self.W-9)
    self.start = 3
    self.UsedSpace = int(math.floor(self.WorkingArea / float(self._max)))
    self.stepsize = self.WorkingArea / self._max
    if self.UsedSpace < 1:
      self.UsedSpace = 1
    self.Paint(None,None,None)

  def Paint(self,v1,v2,v3):
    ## TODO: This is all wrong... it only partially supports _X
    Pos = int(math.ceil(float(self._val) * (self.stepsize))) + self.start + self.X
    Screen = self.PARENT.Screen()
    Screen.AutoRefresh = 0
    # clear the bar region in reverse standard-color
    self.SetColor(1)
    self.LoLight()
    for i in range(0, int(self.WorkingArea)):
      Screen.PutAt(self.Y, self.start + i + self.X, ' ', curses.A_REVERSE)
    # correct position
    if Pos >= (self.WorkingArea + self.start):
      Pos = (self.start + self.WorkingArea)
    elif Pos < (self.start + self.UsedSpace):
      Pos = self.start + self.UsedSpace
    # draw the handle hilight
    if self.FOCUS:
      self.SetColor(3)
    else:
      self.SetColor(2)
    self.LoLight()
    for i in range(0, self.UsedSpace):
      Screen.PutAt(self.Y, (Pos - self.UsedSpace) + i, ' ', curses.A_REVERSE)
    Screen.AutoRefresh = 1
    Screen.Refresh()

  def Dec(self,arg1,arg2,arg3):
    if self._val > 0:
      self._val -= 1
    self.Paint(None,None,None)

  def _Dec(self, arg1,arg2,arg3):
    self.Dec(None,None,None)
    self._Action()

  def Inc(self,arg1,arg2,arg3):
    if self._val < self._max:
      self._val += 1
    self.Paint(None,None,None)

  def _Inc(self, arg1,arg2,arg3):
    self.Inc(None,None,None)
    self._Action()

  def Set(self,newVal):
    if newVal < 0:
      newVal = 0
    elif newVal > self._max:
      newVal =self._max 
    self._val = newVal
    self.Paint(None,None,None)

  def __del__(self):
    Parent = self.PARENT
    Parent.DelControl(self.rightarrow)
    Parent.DelControl(self.leftarrow)
    Parent.DelControl(self.left2arrow)

  def _Action(self):
    action = self.GetMethod("CHANGED")
    if action != None:
      apply(action,(self._val,self._max,None))


