# -*- coding: utf-8 -*-
from kivy.animation import Animation
from kivy.clock import Clock
from kivy.core.window import Window
from kivy.lang import Builder
from kivy.metrics import dp
from kivy.properties import OptionProperty, NumericProperty, StringProperty, \
    BooleanProperty, ListProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.relativelayout import RelativeLayout

Builder.load_string("""
#: import Window kivy.core.window.Window
<SlidingPanel>
    orientation: 'vertical'
    size_hint_x: None
    width: Window.width - dp(56) if Window.width - dp(56) < dp(320) else dp(320)
    x: -1 * self.width if self.side == 'left' else Window.width

<PanelShadow>
    canvas:
        Color:
            rgba: root.color
        Rectangle:
            size: root.size
""")


class PanelShadow(BoxLayout):
    color = ListProperty([0, 0, 0, 0])


class SlidingPanel(BoxLayout):
    anim_length_close = NumericProperty(0.3)
    anim_length_open = NumericProperty(0.3)
    animation_t_open = StringProperty('out_sine')
    animation_t_close = StringProperty('out_sine')
    side = OptionProperty('left', options=['left', 'right'])

    _open = False

    def __init__(self, **kwargs):
        super(SlidingPanel, self).__init__(**kwargs)
        self.width = Window.width - dp(56) if Window.width - dp(56) < dp(320) else dp(320)
        self.shadow = PanelShadow()
        Clock.schedule_once(lambda x: Window.add_widget(self.shadow,89), 0)
        Clock.schedule_once(lambda x: Window.add_widget(self,90), 0)

    def toggle(self):
        Animation.stop_all(self, 'x')
        Animation.stop_all(self.shadow, 'color')
        if self._open:
            if self.side == 'left':
                target_x = -1 * self.width
            else:
                target_x = Window.width

            sh_anim = Animation(duration=self.anim_length_open,
                                t=self.animation_t_open,
                                color=[0, 0, 0, 0])
            sh_anim.start(self.shadow)
            self._get_main_animation(duration=self.anim_length_close,
                                     t=self.animation_t_close,
                                     x=target_x,
                                     is_closing=True).start(self)
            self._open = False
        else:
            if self.side == 'left':
                target_x = 0
            else:
                target_x = Window.width - self.width
            Animation(duration=self.anim_length_open, t=self.animation_t_open,
                      color=[0, 0, 0, 0.5]).start(self.shadow)
            self._get_main_animation(duration=self.anim_length_open,
                                     t=self.animation_t_open,
                                     x=target_x,
                                     is_closing=False).start(self)
            self._open = True

    def _get_main_animation(self, duration, t, x, is_closing):
        return Animation(duration=duration, t=t, x=x)

    def on_touch_down(self, touch):
        # Prevents touch events from propagating to anything below the widget.
        super(SlidingPanel, self).on_touch_down(touch)
        if self.collide_point(*touch.pos) or self._open:
            return True

    def on_touch_up(self, touch):
        super(SlidingPanel, self).on_touch_up(touch)
        if not self.collide_point(touch.x, touch.y) and self._open:
            self.toggle()
        return True
