#!/usr/bin/python

#   Copyright (C) 2002-2003 Yannick Gingras <ygingras@ygingras.net>
#   Copyright (C) 2002-2003 Vincent Barbin <vbarbin@openbeatbox.org>

#   This file is part of Open Beat Box.

#   Open Beat Box 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 of the License, or
#   (at your option) any later version.

#   Open Beat Box 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 Open Beat Box; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

from qt import *
from OBBWidget import OBBWidget
from StretchFrame import StretchFrame
from OBBFuncts import *

class OBBSlider(StretchFrame):
    def __init__( self,
                  framePixSet,
                  handlePixSet,
                  parent=None,
                  x=0,
                  y=0,
                  orientation="x",
                  stretchPoint=30,
                  stretchSize=50,
                  wantedSize=100,
                  handleXOffset=6,
                  handleYOffset=4,
                  minRange=0,
                  maxRange=100,
                  defaultValue=0):
        StretchFrame.__init__( self,
                               framePixSet,
                               parent,
                               x,
                               y,
                               orientation,
                               stretchPoint,
                               stretchSize,
                               wantedSize )

        self.pendingHandleMouseEvent = 0

        self.handle = OBBWidget( handlePixSet,
                                 self,
                                 handleXOffset,
                                 handleYOffset )

        self.maxHandleX = self.width() - self.handle.width() - handleXOffset
        self.minHandleX = handleXOffset
        self.minRange = minRange
        self.maxRange = maxRange
        self.defaultValue = defaultValue
        self.value = defaultValue
        self.connect( self.handle,
                      PYSIGNAL("beingPressed(e)"),
                      self.processHandleClick )
        self.connect( self.handle,
                      PYSIGNAL("beingHovered(e)"),
                      self.processHandleMove )
        self.connect( self.handle,
                      PYSIGNAL("beingReleased(e)"),
                      self.processHandleRelease )
        self.connect( self,
                      PYSIGNAL("beingHovered(e)"),
                      self.processMouseMove )
        self.connect( self,
                      PYSIGNAL("beingDblClicked(e)"),
                      self.processDblClick )
        self.connect( self,
                      PYSIGNAL("beingWheeled(e)"),
                      self.processWheel)
        self.connect( self.handle,
                      PYSIGNAL("beingWheeled(e)"),
                      self.processWheel)

        self.setValue(self.defaultValue, 1)


    def pos2Range(self, handleX):
        """returns an interger inside range"""
        rangeX = 1.0 * (self.maxHandleX - self.minHandleX)
        rangeValue = 1.0 * (self.maxRange - self.minRange)
        return int((((handleX - self.minHandleX) / rangeX) \
            * rangeValue) + self.minRange) + (handleX > self.minHandleX)


    def range2Pos(self, value):
        """returns an interger inside range"""
        rangeX = 1.0 * (self.maxHandleX - self.minHandleX)
        rangeValue = 1.0 * (self.maxRange - self.minRange)
        return int((((value - self.minRange) / rangeValue) \
            * rangeX) + self.minHandleX)


    def setValue(self, value, emit=0):
        """sets slider to wanted value"""
        if value < self.minRange:
            value = self.minRange
        if value > self.maxRange:
            value = self.maxRange

        newX = self.range2Pos(value)
        self.handle.move( newX,
                          self.handle.y)
        if self.value != value:
            self.value = value
            self.emit( PYSIGNAL("valueChanged(int)"),
                       (self.value,))
        debug("Slider value to %d" % value)


    def processHandleClick(self, e):
        self.pendingHandleMouseEvent = 1
        self.captureMouse(self.dropHandleMouseCapture)
        self.handleEventOffset = e.pos().x() - self.handle.x
        self.startGrab(self.handle)


    def processMouseMove(self, e):
        if self.pendingHandleMouseEvent:
            mappedEvent = self.mapMouseEvent(e)
            self.processHandleMove(mappedEvent)


    def processHandleMove(self, e):
        if self.pendingHandleMouseEvent:
            newX = e.pos().x() - self.handleEventOffset
            if self.minHandleX <= newX <= self.maxHandleX:
                self.handle.move( newX,
                                  self.handle.y)
                self.emit( PYSIGNAL("valueChanging(int)"),
                           (self.pos2Range(newX),))
            elif newX < self.minHandleX:
                self.handle.move( self.minHandleX,
                                  self.handle.y)
                self.emit( PYSIGNAL("valueChanging(int)"),
                           (self.pos2Range(self.minHandleX),))
            elif newX > self.maxHandleX:
                self.handle.move( self.maxHandleX,
                                  self.handle.y)
                self.emit( PYSIGNAL("valueChanging(int)"),
                           (self.pos2Range(self.maxHandleX),))
            else:
                raise Exception("I have no clue where the handle is !")


    def processHandleRelease(self, e):
        if self.pendingHandleMouseEvent:
            newX = e.pos().x() - self.handleEventOffset
            if newX < self.minHandleX:
                newX = self.minHandleX
            if newX > self.maxHandleX:
                newX = self.maxHandleX
            self.setValue(self.pos2Range(newX), 1)


    def processDblClick(self, e):
        self.setValue(self.defaultValue, 1)


    def dropHandleMouseCapture(self):
        self.setValue(self.pos2Range(self.handle.x), 1)
        self.pendingHandleMouseEvent = 0


    def processWheel(self, event):
        if event.delta() < 0:
            inc = -2
        else:
            inc =  2
            
        self.setValue(self.value + inc, 1)
