from copy import copy
from inspect import stack


class Adjacent(object):
    def parent(self, **kwargs):
        """
        Returns parent element of current element
        :rtype: watir_snake.elements.elements.Element

        :Example:

        browser.text_field(name='new_user_field_name').parent() == browser.fieldset    #=> True
        """
        kwargs['index'] = kwargs.get('index', 0)
        return self._xpath_adjacent('ancestor::', **kwargs)

    def preceding_sibling(self, **kwargs):
        """
        Returns preceding sibling element of current element
        :rtype: watir_snake.elements.elements.Element

        :Example:

        browser.text_field(name='new_user_first_name').preceding_sibling(index=1) == browser.legend
        #=> True
        """
        kwargs['index'] = kwargs.get('index', 0)
        return self._xpath_adjacent('preceding-sibling::', **kwargs)

    previous_sibling = preceding_sibling

    def preceding_siblings(self, **kwargs):
        """
        Returns collection of preceding sibling elements of current element
        :rtype: watir_snake.element_collection.ElementCollection

        :Example:

        len(browser.text_field(name='new_user_first_name').preceding_siblings)    #=> 3
        """
        if 'index' in kwargs:
            raise ValueError('#previous_siblings can not take an index value')
        return self._xpath_adjacent("preceding-sibling::", **kwargs)

    previous_siblings = preceding_siblings

    def following_sibling(self, **kwargs):
        """
        Returns following sibling element of current element
        :rtype: watir_snake.elements.elements.Element

        :Example:

        browser.text_field(name='new_user_first_name').following_sibling(index=2) == \
            browser.text_field(id='new_user_last_name')    #=> True
        """
        kwargs['index'] = kwargs.get('index', 0)
        return self._xpath_adjacent('following-sibling::', **kwargs)

    next_sibling = following_sibling

    def following_siblings(self, **kwargs):
        """
        Returns collection of following sibling elements of current element
        :rtype: watir_snake.element_collection.ElementCollection

        :Example:

        len(browser.text_field(name='new_user_first_name').following_siblings)    #=> 52
        """
        if 'index' in kwargs:
            raise ValueError('#following_siblings can not take an index value')
        return self._xpath_adjacent('following-sibling::', **kwargs)

    next_siblings = following_siblings

    @property
    def child(self, **kwargs):
        """
        Returns element of direct child of current element
        :rtype: watir_snake.elements.elements.Element

        :Example:

        browser.form(id='new_user').child == browser.fieldset    #=> True
        """
        kwargs['index'] = kwargs.get('index', 0)
        return self._xpath_adjacent('', **kwargs)

    @property
    def children(self, **kwargs):
        """
        Returns collection of elements of direct children of current element
        :rtype: watir_snake.element_collection.ElementCollection

        :Example:

        browser.select_list(id='new_user_languages').children == \
            browser.select_list(id='new_user_languages').options.to_list    #=> True
        """
        if 'index' in kwargs:
            raise ValueError('#children can not take an index value')
        return self._xpath_adjacent('', **kwargs)

    # private

    def _xpath_adjacent(self, direction='', **kwargs):
        from .elements.html_elements import HTMLElement, HTMLElementCollection
        import watir_snake

        kwargs = copy(kwargs)
        index = kwargs.pop('index', None)
        tag_name = kwargs.pop('tag_name', '')
        if not kwargs:
            caller = stack()[1][3]
            raise AttributeError('unsupported locators: {} for #{} method'.format(kwargs, caller))

        if index:
            klass = watir_snake.tag_to_class.get(tag_name) if tag_name else HTMLElement
            klass(self, xpath="./{}{}[{}]".format(direction, tag_name or '*', index + 1))
        else:
            klass = watir_snake.tag_to_class('{}_collection'.format(tag_name)) if tag_name else \
                HTMLElementCollection
            klass(self, xpath="./{}{}".format(direction, tag_name or '*'))

@@ -2525,30 +2525,16 @@
 blings%0A%0A
-    @property%0A
     def 
@@ -2548,32 +2548,32 @@
 elf, **kwargs):%0A
+
         %22%22%22%0A    
@@ -2891,22 +2891,8 @@
 s)%0A%0A
-    @property%0A
     
@@ -3716,20 +3716,16 @@
      if 
-not 
 kwargs:%0A
@@ -3969,32 +3969,39 @@
 ent%0A            
+return 
 klass(self, xpat
@@ -3992,31 +3992,35 @@
 klass(self, 
+%7B'
 xpath
-=%22
+': '
 ./%7B%7D%7B%7D%5B%7B%7D%5D%22.
@@ -4017,17 +4017,17 @@
 %7B%7D%7B%7D%5B%7B%7D%5D
-%22
+'
 .format(
@@ -4064,16 +4064,17 @@
 dex + 1)
+%7D
 )%0A      
@@ -4225,24 +4225,31 @@
             
+return 
 klass(self, 
@@ -4252,22 +4252,26 @@
 lf, 
+%7B'
 xpath
-=%22
+': '
 ./%7B%7D%7B%7D
-%22
+'
 .for
@@ -4301,10 +4301,11 @@
  or '*')
+%7D
 )%0A

fix adjacent for child/children