# -*- coding: utf-8 -*-

__author__ = 'm_beloborodko@wargaming.net'

from time import sleep
from _ctypes import COMError

import win32con
import win32api
from win32gui import GetParent
from uisoup import uisoup, TooSaltyUISoupException
from uisoup.interfaces.i_element import IElement  # noqa

from wgc_helpers.winapi_helper import WinApi
from wgc_client.ui.elements.abstract_element import AbstractElement
from wgc_core.config import WGCConfig
from wgc_core.exceptions import WGCException


class NativeElement(AbstractElement):

    @property
    def _window(self):
        """
        Property for initialized WGC window.
        """
        if self.window_handle:
            window = uisoup.get_window(self.window_handle)
        else:
            hwnd = WinApi.get_top_level_window(
                WGCConfig.application.wgc_window_title_name, 'Chrome_WidgetWin_0')
            window = uisoup.get_window(hwnd)
        return window

    @property
    def _win_element(self):
        """
        Property for UISoup element.

        :rtype: IElement
        """
        try:
            element = self._window.find(
                c_name=self.selector, only_visible=False)
        except (WindowsError, TooSaltyUISoupException, COMError):
            sleep(.6)
            element = self._window.find(
                c_name=self.selector, only_visible=False)
        return element

    @property
    def parent_window_hwnd(self):
        """
        Retrieves a handle to the specified window's parent or owner.

        :rtype: int.
        :return: HWND
        """
        return GetParent(self._win_element._hwnd)

    def click(self, wait_response=True, timeout=10, index=0, ignore_exc=False):
        """
        :param bool ignore_exc: variable not used.
        :param int timeout: time to wait response, for
        native element is absent.
        :param bool wait_response: ignored for NativeElement.
        :param int index: index of web element in list for Native elements
        not used.
        """
        x, y, w, h = self.hover_on_element()
        x += w / 2
        y += h / 2
        x, y = int(x), int(y)
        win32api.SetCursorPos((x, y))
        sleep(.25)
        try:
            win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, x, y, 0, 0)
            sleep(.8)
            win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, x, y, 0, 0)
        except WindowsError:
            sleep(1)
            win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, x, y, 0, 0)
            sleep(.8)
            win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, x, y, 0, 0)

    def double_click(self):
        self.hover_on_element()
        try:
            self._win_element.double_click(x_offset=None, y_offset=None)
        except WindowsError:
            sleep(1)
            self._win_element.double_click(x_offset=None, y_offset=None)

    @property
    def is_element_displayed(self, index=None):
        result = False
        try:
            if self._win_element:
                result = self._win_element.is_visible
        except (TooSaltyUISoupException, WindowsError, COMError,
                AttributeError, IndexError):
            pass
        return result

    def get_bounding_client_rect(self, index=0):
        return

    @property
    def is_checkbox_checked(self):
        return self._win_element.is_checked

    @property
    def is_element_present(self):
        result = False
        try:
            hwnd = WinApi.get_top_level_window(
                WGCConfig.application.wgc_window_title_name, 'Chrome_WidgetWin_0')
            handle = self.window_handle or hwnd
            if uisoup.is_window_exists(handle):
                result = self._window.is_object_exists(c_name=self.selector)
        except (TooSaltyUISoupException, WindowsError, COMError, IndexError):
            pass
        return result

    def get_text(self):
        return self._win_element.acc_value

    get_value = get_text

    def get_html_text(self):
        raise WGCException('Element of NativeElement class doesn\'t have '
                           'HTML text.')

    def set_text(self, text, index=0):
        return self._win_element.set_value(text)

    def react_set_text(self, text, index=0):
        raise WGCException('Element of NativeElement class doesn\'t have '
                           'attributes.')

    def get_attribute(self, attribute_name, index=0):
        raise WGCException('Element of NativeElement class doesn\'t have '
                           'attributes.')

    def get_property_value(self, attribute_name, index=0):
        raise WGCException('Element of NativeElement class doesn\'t have '
                           'attributes.')
    
    def get_style_value(self, attribute_name, index=0):
        raise WGCException('Element of NativeElement class doesn\'t have '
                           'attributes.')

    def trigger_event(self, event, params=None, index=0):
        raise WGCException('Element of NativeElement class doesn\'t handle '
                           'events.')

    def get_elements_count(self):
        # always only one element can be selected for native element
        return 1

    def hover_on_element(self):
        # offset is needed to click on center of element.
        x, y, w, h = self._win_element.acc_location
        uisoup.mouse.move(x + int(w / 2), y + int(h / 2), smooth=False)
        return x, y, w, h

    def get_element_color(self):
        # as for now we didn't resolving colors for native elements
        return

    def get_element_background_color(self):
        # as for now we didn't resolving colors for native elements
        return

    def set_checkbox_state(self, state):
        raise NotImplementedError

    def set_focus(self):
        self._win_element.set_focus()

    def scroll_to(self):
        raise NotImplementedError

    def mouseenter_on_element(self):
        raise NotImplementedError

    def mouseover_on_element(self):
        raise NotImplementedError

    def mouseleave_on_element(self):
        raise NotImplementedError
