"""
Drag Behavior
=============

The :class:`~kivy.uix.behaviors.drag.DragBehavior`
`mixin <https://en.wikipedia.org/wiki/Mixin>`_ class provides Drag behavior.
When combined with a widget, dragging in the rectangle defined by the
:attr:`~kivy.uix.behaviors.drag.DragBehavior.drag_rectangle` will drag the
widget.

Example
-------

The following example creates a draggable label::

    from kivy.uix.label import Label
    from kivy.app import App
    from kivy.uix.behaviors import DragBehavior
    from kivy.lang import Builder

    # You could also put the following in your kv file...
    kv = '''
    <DragLabel>:
        # Define the properties for the DragLabel
        drag_rectangle: self.x, self.y, self.width, self.height
        drag_timeout: 10000000
        drag_distance: 0

    FloatLayout:
        # Define the root widget
        DragLabel:
            size_hint: 0.25, 0.2
            text: 'Drag me'
    '''


    class DragLabel(DragBehavior, Label):
        pass


    class TestApp(App):
        def build(self):
            return Builder.load_string(kv)

    TestApp().run()

"""

__all__ = ('DragBehavior', )

from kivy.clock import Clock
from kivy.properties import NumericProperty, ReferenceListProperty
from kivy.config import Config
from kivy.metrics import sp
from functools import partial

# When we are generating documentation, Config doesn't exist
_scroll_timeout = _scroll_distance = 0
if Config:
    _scroll_timeout = Config.getint('widgets', 'scroll_timeout')
    _scroll_distance = Config.getint('widgets', 'scroll_distance')


class DragBehavior(object):
    '''
    The DragBehavior `mixin <https://en.wikipedia.org/wiki/Mixin>`_ provides
    Drag behavior. When combined with a widget, dragging in the rectangle
    defined by :attr:`drag_rectangle` will drag the widget. Please see
    the :mod:`drag behaviors module <kivy.uix.behaviors.drag>` documentation
    for more information.

    .. versionadded:: 1.8.0
    '''

    drag_distance = NumericProperty(_scroll_distance)
    '''Distance to move before dragging the :class:`DragBehavior`, in pixels.
    As soon as the distance has been traveled, the :class:`DragBehavior` will
    start to drag, and no touch event will be dispatched to the children.
    It is advisable that you base this value on the dpi of your target device's
    screen.

    :attr:`drag_distance` is a :class:`~kivy.properties.NumericProperty` and
    defaults to the `scroll_distance` as defined in the user
    :class:`~kivy.config.Config` (20 pixels by default).
    '''

    drag_timeout = NumericProperty(_scroll_timeout)
    '''Timeout allowed to trigger the :attr:`drag_distance`, in milliseconds.
    If the user has not moved :attr:`drag_distance` within the timeout,
    dragging will be disabled, and the touch event will be dispatched to the
    children.

    :attr:`drag_timeout` is a :class:`~kivy.properties.NumericProperty` and
    defaults to the `scroll_timeout` as defined in the user
    :class:`~kivy.config.Config` (55 milliseconds by default).
    '''

    drag_rect_x = NumericProperty(0)
    '''X position of the axis aligned bounding rectangle where dragging
    is allowed (in window coordinates).

    :attr:`drag_rect_x` is a :class:`~kivy.properties.NumericProperty` and
    defaults to 0.
    '''

    drag_rect_y = NumericProperty(0)
    '''Y position of the axis aligned bounding rectangle where dragging
    is allowed (in window coordinates).

    :attr:`drag_rect_Y` is a :class:`~kivy.properties.NumericProperty` and
    defaults to 0.
    '''

    drag_rect_width = NumericProperty(100)
    '''Width of the axis aligned bounding rectangle where dragging is allowed.

    :attr:`drag_rect_width` is a :class:`~kivy.properties.NumericProperty` and
    defaults to 100.
    '''

    drag_rect_height = NumericProperty(100)
    '''Height of the axis aligned bounding rectangle where dragging is allowed.

    :attr:`drag_rect_height` is a :class:`~kivy.properties.NumericProperty` and
    defaults to 100.
    '''

    drag_rectangle = ReferenceListProperty(drag_rect_x, drag_rect_y,
                                           drag_rect_width, drag_rect_height)
    '''Position and size of the axis aligned bounding rectangle where dragging
    is allowed.

    :attr:`drag_rectangle` is a :class:`~kivy.properties.ReferenceListProperty`
    of (:attr:`drag_rect_x`, :attr:`drag_rect_y`, :attr:`drag_rect_width`,
    :attr:`drag_rect_height`) properties.
    '''

    def __init__(self, **kwargs):