#!/usr/bin/python
# -*- coding: utf-8 -*-

from .. import parts

class WaitsPart(parts.Part):

    def until(self, method, message = None, timeout = None):
        return self.driver.wrap_outer(
            lambda: self.driver._wait(timeout = timeout).until(
                lambda *args: self.driver.wrap_inner(method, *args),
                message = message or "Method was not validated"
            )
        )

    def redirected_to(
        self,
        url,
        params = None,
        fragment = None,
        starts_with = False,
        message = None,
        timeout = None
    ):
        return self.until(
            lambda d: self.logic.at_url(
                url,
                params = params,
                fragment = fragment,
                starts_with = starts_with
            ),
            message = message or "Expecting the page to be '%s' but is '%s'" % (
                url,
                self.driver.current_url
            ),
            timeout = timeout
        )

    def tab_count(self, tab_count, message = None, timeout = None):
        return self.until(
            lambda d: self.driver.tab_count == tab_count,
            message = message or "Expecting the number of browser tabs to be '%s' but is '%s'" % (
                tab_count,
                self.driver.tab_count
            ),
            timeout = timeout
        )

    def has_src(self, selector, url, params = None, ensure = False):
        element = self.waits.visible(selector, ensure = ensure)
        return self.waits.until(
            lambda d: self.logic.has_src(element, url, params = params),
            "'src' attribute was not the expected one"
        )

    def visible(
        self,
        selector,
        text = None,
        ensure = True,
        message = None,
        timeout = None
    ):
        return self.until(
            lambda d: self._get_element(
                selector,
                text = text,
                timeout = timeout,
                displayed = True,
                visible = ensure
            ),
            message = message or "Element '%s' not found or not visible" % selector,
            timeout = timeout
        )

    def not_visible(
        self,
        selector,
        text = None,
        ensure = False,
        message = None,
        timeout = None
    ):
        return self.until(
            lambda d: not self._get_element(
                selector,
                text = text,
                timeout = timeout,
                displayed = True,
                visible = ensure
            ),
            message = message or "Element '%s' was found and is visible" % selector,
            timeout = timeout
        )

    def _get_element(
        self,
        selector,
        text = None,
        timeout = None,
        displayed = True,
        visible = True
    ):
        condition = None
        if text:
            condition = self._build_condition(
                lambda e, s: self.logic.has_text(e, s, text),
                description = "text='%s'" % text
            )
        element = self.logic.get(selector, condition = condition)
        if not element: return None
        if displayed:
            try: self.driver.scroll_to(element)
            except Exception: return None
            result = element.is_displayed()
            if not result: return None
        if visible:
            try: self.driver.ensure_visible(element, timeout = timeout)
            except Exception: return None
        return element

    def _build_condition(self, callable, description = None):
        callable._description = description
        return callable
