private boolean processTouch(int action, MotionEvent e, boolean sensorMode) {
    switch (action) {
      case MotionEvent.ACTION_DOWN:
        if (mCurrentTouchState == TouchState.INIT) {
          mInitX = (int) e.getX();
          mInitY = (int) e.getY();
          if (sensorMode) {
            return true;
          }
          mCurrentTouchState = TouchState.DRAG_ONE;
          mPreviousX1 = e.getX();
          mPreviousY1 = e.getY();
          return true;
        }
      case MotionEvent.ACTION_POINTER_DOWN:
        if (sensorMode) {
          return true;
        }
        if (mCurrentTouchState == TouchState.DRAG_ONE) {
          mCurrentTouchState = TouchState.DRAG_TWO;
          mPointerIndex = e.getActionIndex();
          mPreviousX1 = e.getX();
          mPreviousY1 = e.getY();
          mPreviousX2 = e.getX(mPointerIndex);
          mPreviousY2 = e.getY(mPointerIndex);
          return true;
        }
      case MotionEvent.ACTION_MOVE:
        if (sensorMode) {
          return true;
        }
        if (mCurrentTouchState == TouchState.DRAG_ONE) {
          float currentX = e.getX();
          float currentY = e.getY();
          float deltaX = currentX - mPreviousX1;
          float deltaY = currentY - mPreviousY1;

          float radsPerPixel = mStarMapperRenderer.mFovYRad / mStarMapperRenderer.mScreenHeight;
          changeMapX(-deltaX * radsPerPixel);
          changeMapY(-deltaY * radsPerPixel);

          mStarMapperRenderer.mLookX = mUser.getLookX();
          mStarMapperRenderer.mLookY = mUser.getLookY();
          mStarMapperRenderer.mLookZ = mUser.getLookZ();
          mStarMapperRenderer.mUpX = mUser.getNormalX();
          mStarMapperRenderer.mUpY = mUser.getNormalY();
          mStarMapperRenderer.mUpZ = mUser.getNormalZ();

          mPreviousX1 = currentX;
          mPreviousY1 = currentY;
          return true;
        } else if (mCurrentTouchState == TouchState.DRAG_TWO) {
          float currentX1 = e.getX();
          float currentY1 = e.getY();
          float currentX2 = e.getX(mPointerIndex);
          float currentY2 = e.getY(mPointerIndex);
          float deltaX1 = currentX1 - mPreviousX1;
          float deltaY1 = currentY1 - mPreviousY1;
          float deltaX2 = currentX2 - mPreviousX2;
          float deltaY2 = currentY2 - mPreviousY2;

          float radsPerPixel = mStarMapperRenderer.mFovYRad / mStarMapperRenderer.mScreenHeight;
          changeMapX(-((deltaX1 + deltaX2) / 2) * radsPerPixel);
          changeMapY(-((deltaY1 + deltaY2) / 2) * radsPerPixel);

          float vPreviousX = mPreviousX1 - mPreviousX2;
          float vPreviousY = mPreviousY1 - mPreviousY2;
          float vCurrentX = currentX1 - currentX2;
          float vCurrentY = currentY1 - currentY2;

          /* Need a 'stretch' function here for field of view once zoom is implemented */
          float vectorRatio =
              (float)
                  Math.sqrt(
                      (vCurrentX * vCurrentX + vCurrentY * vCurrentY)
                          / (vPreviousX * vPreviousX + vPreviousY * vPreviousY));
          mStarMapperRenderer.mFovYRad =
              mZoomer.zoomBy(mStarMapperRenderer.mFovYRad, 1.0f / vectorRatio);
          mStarMapperRenderer.mUpdatePerspective = true;

          double anglePrevious = Math.atan2(vPreviousX, vPreviousY);
          double angleCurrent = Math.atan2(vCurrentX, vCurrentY);
          float angleDelta = (float) (anglePrevious - angleCurrent);

          rotate(angleDelta);

          mStarMapperRenderer.mLookX = mUser.getLookX();
          mStarMapperRenderer.mLookY = mUser.getLookY();
          mStarMapperRenderer.mLookZ = mUser.getLookZ();
          mStarMapperRenderer.mUpX = mUser.getNormalX();
          mStarMapperRenderer.mUpY = mUser.getNormalY();
          mStarMapperRenderer.mUpZ = mUser.getNormalZ();

          mPreviousX1 = currentX1;
          mPreviousY1 = currentY1;
          mPreviousX2 = currentX2;
          mPreviousY2 = currentY2;
          return true;
        }
      case MotionEvent.ACTION_UP:
        int last_X = (int) e.getX();
        int last_Y = (int) e.getY();
        int dx = Math.abs(last_X - mInitX);
        int dy = Math.abs(last_Y - mInitY);
        if (dx <= 20 && dy <= 20) {
          for (Label label : mStarMapperRenderer.mLabelManager.LabelSet) {
            int xll = label.screenPos_xll;
            int yll = label.screenPos_yll;
            int xur = label.screenPos_xur;
            int yur = label.screenPos_yur;
            LabelTypeEnum type = label.getType();
            if (label.isOnScreen()
                && xll <= mInitX
                && xur >= mInitX
                && yll <= mInitY
                && yur >= mInitY
                && type != LabelTypeEnum.GRID) {
              String name = label.getText().replaceAll(" ", "_");
              String URL = "http://en.wikipedia.org/wiki/" + name;
              if (type == LabelTypeEnum.CONSTELLATION
                  || type == LabelTypeEnum.STAR
                  || type == LabelTypeEnum.PLANET) {
                URL = URL + "_(" + label.getType().name().toLowerCase() + ")";
              }
              Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(URL));
              startActivity(browserIntent);
              // Toast.makeText(this, label.getText(), Toast.LENGTH_SHORT).show();
            }
          }
        }
        if (sensorMode) {
          return true;
        }
        if (mCurrentTouchState != TouchState.INIT) {
          mCurrentTouchState = TouchState.INIT;
          return true;
        }
      case MotionEvent.ACTION_POINTER_UP:
        if (sensorMode) {
          return true;
        }
        if (mCurrentTouchState == TouchState.DRAG_TWO) {
          mCurrentTouchState = TouchState.INIT;
        }
    }
    return false;
  }