module PageHelpers
  module Drag
    private

    # Private: Drags one element to another element with a specified percentage offset (defaults at 0)
    #
    # element_1 - Element to drag
    # element_2 - Element to drag the first element to
    # x_offset - Extra percent offset to move horizontally relative to distance between elements
    # y_offset - Extra percent offset to move vertically relative to distance between elements
    #
    # Example
    #
    # drag_with_additional_movement(first_drag_handle_element, second_drag_handle_element, 0, 0.1)
    #
    # This will drag the first handle to the second handle location,
    # plus an extra 10% movement along the y-axis
    #
    # Returns nothing
    def drag_with_additional_movement(element_1, element_2, x_offset = 0, y_offset = 0)
      first_element = element_1.element
      second_element = element_2.element

      y_distance = execute_script(y_coord_script, second_element) - \
                   execute_script(y_coord_script, first_element)
      x_distance = execute_script(x_coord_script, second_element) - \
                   execute_script(x_coord_script, first_element)

      click_and_drag(
        first_element,
        x_distance * (1 + x_offset),
        y_distance * (1 + y_offset)
      )
    end

    def click_and_drag(element, x_distance, y_distance)
      element.fire_event("onmousedown")
      driver = browser.driver
      driver.action.click_and_hold(element.wd).perform
      sleep 2
      driver.action.move_by(x_distance, y_distance).perform
      sleep 2
      element.fire_event("onmouseup")
    end

    def x_coord_script
      y_coord_script.sub(".top", ".left")
                    .sub(".bottom", ".right")
                    .sub(".pageYOffset", ".pageXOffset")
                    .gsub(".scrollTop", ".scrollLeft")
                    .gsub(".clientTop", ".clientLeft")
    end

    def y_coord_script
      <<-JS
        function getCoord(el) {
          var rect = el.getBoundingClientRect();
          var body = document.body
          var docElem = document.documentElement

          var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop
          var clientTop = docElem.clientTop || body.clientTop || 0

          var top  = rect.top +  scrollTop - clientTop
          var bottom = rect.bottom + scrollTop - clientTop

          return Math.round((top + bottom)*0.5)
        }
        return getCoord(arguments[0]);
      JS
    end
  end
end
