/**
   * Recalculate camera per row preference for the following situations: 1. If it won't influence
   * others and the current user only has one or two cameras, reset the value to be 1. 2. If current
   * user only has one or two cameras, but the device has other accounts logged in, keep the value
   * as it was without overriding it. 3. If the current user has more than two cameras, adjust the
   * value of camera per row to be a proper number based on screen size.
   *
   * @return The recalculated value of camera per row
   */
  public int recalculateCameraPerRow() {
    int totalCameras = AppData.evercamCameraList.size();
    boolean isInfluencingOtherUser = false;
    ArrayList<AppUser> userList = new EvercamAccount(this).retrieveUserList();
    if (userList.size() > 1) {
      isInfluencingOtherUser = true;
    }

    if (totalCameras != 0 && totalCameras <= 2) {
      if (!isInfluencingOtherUser) {
        PrefsManager.setCameraPerRow(this, 1);
        return 1;
      } else {
        return PrefsManager.getCameraPerRow(this, 2);
      }
    } else {
      int screenWidth = readScreenWidth(this);
      int maxCamerasPerRow = 3;
      int minCamerasPerRow = 1;
      if (screenWidth != 0) {
        maxCamerasPerRow = screenWidth / 350;
      }

      int oldCamerasPerRow = PrefsManager.getCameraPerRow(this, 2);
      if (maxCamerasPerRow < oldCamerasPerRow && maxCamerasPerRow != 0) {
        PrefsManager.setCameraPerRow(this, maxCamerasPerRow);
        return maxCamerasPerRow;
      } else if (maxCamerasPerRow == 0) {
        return minCamerasPerRow;
      }
      return oldCamerasPerRow;
    }
  }
  @Override
  public void onStop() {
    super.onStop();

    if (AppData.defaultUser != null) {
      usernameOnStop = AppData.defaultUser.getUsername();
    }

    showOfflineOnStop = PrefsManager.showOfflineCameras(this);
  }
  private void launch() {
    int versionCode = Commons.getAppVersionCode(this);
    boolean isReleaseNotesShown = PrefsManager.isReleaseNotesShown(this, versionCode);

    if (versionCode > 0) {
      if (isReleaseNotesShown) {
        startApplication();
      } else {
        Intent act = new Intent(MainActivity.this, ReleaseNotesActivity.class);
        startActivity(act);
        this.finish();
      }
    }
  }
  /**
   * Add all camera views to the main grid page
   *
   * @param reloadImages reload camera images or not
   * @param showThumbnails show thumbnails that returned by Evercam or not, if true and if thumbnail
   *     not available, it will request latest snapshot instead. If false, it will request neither
   *     thumbnail nor latest snapshot.
   */
  public boolean addAllCameraViews(final boolean reloadImages, final boolean showThumbnails) {
    try {
      // Recalculate camera per row
      camerasPerRow = recalculateCameraPerRow();

      io.evercam.androidapp.custom.FlowLayout camsLineView =
          (io.evercam.androidapp.custom.FlowLayout) this.findViewById(R.id.cameras_flow_layout);

      int screen_width = readScreenWidth(this);

      int index = 0;

      for (final EvercamCamera evercamCamera : AppData.evercamCameraList) {
        // Don't show offline camera
        if (!PrefsManager.showOfflineCameras(this) && !evercamCamera.isActive()) {
          continue;
        }

        final LinearLayout cameraListLayout = new LinearLayout(this);

        int indexPlus = index + 1;

        if (reloadImages) evercamCamera.loadingStatus = ImageLoadingStatus.not_started;

        final CameraLayout cameraLayout = new CameraLayout(this, evercamCamera, showThumbnails);

        LinearLayout.LayoutParams params =
            new LinearLayout.LayoutParams(
                android.view.ViewGroup.LayoutParams.WRAP_CONTENT,
                android.view.ViewGroup.LayoutParams.WRAP_CONTENT);
        params.width =
            ((indexPlus % camerasPerRow == 0)
                ? (screen_width - (index % camerasPerRow) * (screen_width / camerasPerRow))
                : screen_width / camerasPerRow);
        params.width = params.width - 1; // 1 pixels spacing between cameras
        params.height = (int) (params.width / (1.25));
        params.setMargins(0, 0, 0, 0); // No spacing between cameras
        cameraLayout.setLayoutParams(params);

        cameraListLayout.addView(cameraLayout);

        camsLineView.addView(
            cameraListLayout, new io.evercam.androidapp.custom.FlowLayout.LayoutParams(0, 0));

        index++;

        new Handler()
            .postDelayed(
                new Runnable() {
                  @Override
                  public void run() {

                    Rect cameraBounds = new Rect();
                    cameraListLayout.getHitRect(cameraBounds);

                    Rect offlineIconBounds = cameraLayout.getOfflineIconBounds();
                    int layoutWidth = cameraBounds.right - cameraBounds.left;
                    int offlineStartsAt = offlineIconBounds.left;
                    int offlineIconWidth = offlineIconBounds.right - offlineIconBounds.left;

                    if (layoutWidth > offlineStartsAt + offlineIconWidth * 2) {
                      cameraLayout.showOfflineIconAsFloat = false;
                    } else {
                      cameraLayout.showOfflineIconAsFloat = true;
                    }
                  }
                },
                200);
      }

      if (refresh != null) refresh.setActionView(null);

      return true;
    } catch (Exception e) {
      Log.e(TAG, e.toString(), e);

      sendToMint(e);

      EvercamPlayApplication.sendCaughtException(this, e);
      CustomedDialog.showUnexpectedErrorDialog(CamerasActivity.this);
    }
    return false;
  }
 private boolean isOfflineSettingChanged() {
   return showOfflineOnStop != PrefsManager.showOfflineCameras(this);
 }