/**
   * Actions a Pull Event
   *
   * @return true if the Event has been handled, false if there has been no change
   */
  private void pullEvent() {
    final int newScrollValue;
    final int itemDimension;
    final float initialMotionValue, lastMotionValue;

    switch (getPullToRefreshScrollDirection()) {
      case HORIZONTAL:
        initialMotionValue = mInitialMotionX;
        lastMotionValue = mLastMotionX;
        break;
      case VERTICAL:
      default:
        initialMotionValue = mInitialMotionY;
        lastMotionValue = mLastMotionY;
        break;
    }

    switch (mCurrentMode) {
      case PULL_FROM_END:
        newScrollValue = Math.round(Math.max(initialMotionValue - lastMotionValue, 0) / FRICTION);
        itemDimension = getFooterSize();
        break;
      case PULL_FROM_START:
      default:
        newScrollValue = Math.round(Math.min(initialMotionValue - lastMotionValue, 0) / FRICTION);
        itemDimension = getHeaderSize();
        break;
    }

    setHeaderScroll(newScrollValue);

    if (newScrollValue != 0 && !isRefreshing()) {
      float scale = Math.abs(newScrollValue) / (float) itemDimension;
      switch (mCurrentMode) {
        case PULL_FROM_END:
          mFooterLayout.onPull(scale);
          break;
        case PULL_FROM_START:
        default:
          mHeaderLayout.onPull(scale);
          break;
      }

      if (mState != State.PULL_TO_REFRESH && itemDimension >= Math.abs(newScrollValue)) {
        setState(State.PULL_TO_REFRESH);
      } else if (mState == State.PULL_TO_REFRESH && itemDimension < Math.abs(newScrollValue)) {
        setState(State.RELEASE_TO_REFRESH);
      }
    }
  }