Decoupling the reorder logic from the CellLayout view

ReorderAlgorithm will now handle all the logic associated with the
reorder. Basically all the logic associated with a reorder in CellLayout
was copy and pasted into ReorderAlgorithm.java.

Test: atest TestReorderAlgorithm
Bug: 229292911
Change-Id: Ie096abc346bf705414e47452a42d1dec5be0a041
diff --git a/src/com/android/launcher3/MultipageCellLayout.java b/src/com/android/launcher3/MultipageCellLayout.java
index 6a518a7..12cb35d 100644
--- a/src/com/android/launcher3/MultipageCellLayout.java
+++ b/src/com/android/launcher3/MultipageCellLayout.java
@@ -23,11 +23,11 @@
 import android.view.View;
 
 import com.android.launcher3.celllayout.CellLayoutLayoutParams;
+import com.android.launcher3.celllayout.MulticellReorderAlgorithm;
+import com.android.launcher3.celllayout.ReorderAlgorithm;
 import com.android.launcher3.util.CellAndSpan;
 import com.android.launcher3.util.GridOccupancy;
 
-import java.util.function.Supplier;
-
 /**
  * CellLayout that simulates a split in the middle for use in foldable devices.
  */
@@ -36,8 +36,6 @@
     private final Drawable mLeftBackground;
     private final Drawable mRightBackground;
 
-    private View mSeam;
-
     private boolean mSeamWasAdded = false;
 
     public MultipageCellLayout(Context context) {
@@ -62,7 +60,6 @@
 
         mCountX = deviceProfile.inv.numColumns * 2;
         mCountY = deviceProfile.inv.numRows;
-        mSeam = new View(getContext());
         setGridSize(mCountX, mCountY);
     }
 
@@ -74,90 +71,18 @@
             cellX++;
         }
         int finalCellX = cellX;
-        return simulateSeam(
+        return ((MulticellReorderAlgorithm) createReorderAlgorithm()).simulateSeam(
                 () -> super.createAreaForResize(finalCellX, cellY, spanX, spanY, dragView,
                         direction, commit));
     }
 
     @Override
-    ItemConfiguration closestEmptySpaceReorder(int pixelX, int pixelY, int minSpanX, int minSpanY,
-            int spanX, int spanY) {
-        return removeSeamFromSolution(simulateSeam(
-                () -> super.closestEmptySpaceReorder(pixelX, pixelY, minSpanX, minSpanY, spanX,
-                        spanY)));
+    public ReorderAlgorithm createReorderAlgorithm() {
+        return new MulticellReorderAlgorithm(this);
     }
 
     @Override
-    protected ItemConfiguration findReorderSolution(int pixelX, int pixelY, int minSpanX,
-            int minSpanY, int spanX, int spanY, int[] direction, View dragView, boolean decX,
-            ItemConfiguration solution) {
-        return removeSeamFromSolution(simulateSeam(
-                () -> super.findReorderSolution(pixelX, pixelY, minSpanX, minSpanY, spanX, spanY,
-                        direction, dragView, decX, solution)));
-    }
-
-    @Override
-    public ItemConfiguration dropInPlaceSolution(int pixelX, int pixelY, int spanX, int spanY,
-            View dragView) {
-        return removeSeamFromSolution(simulateSeam(
-                () -> super.dropInPlaceSolution(pixelX, pixelY, spanX, spanY, dragView)));
-    }
-
-    void addSeam() {
-        CellLayoutLayoutParams lp = new CellLayoutLayoutParams(mCountX / 2, 0, 1, mCountY);
-        mSeamWasAdded = true;
-        lp.canReorder = false;
-        mCountX++;
-        mShortcutsAndWidgets.addViewInLayout(mSeam, lp);
-        mOccupied = createGridOccupancyWithSeam(mOccupied);
-        mTmpOccupied = new GridOccupancy(mCountX, mCountY);
-    }
-
-    void removeSeam() {
-        mCountX--;
-        mShortcutsAndWidgets.removeViewInLayout(mSeam);
-        mTmpOccupied = new GridOccupancy(mCountX, mCountY);
-        mSeamWasAdded = false;
-    }
-
-    protected <T> T simulateSeam(Supplier<T> f) {
-        if (mSeamWasAdded) {
-            return f.get();
-        }
-        GridOccupancy auxGrid = mOccupied;
-        addSeam();
-        T res = f.get();
-        removeSeam();
-        mOccupied = auxGrid;
-        return res;
-    }
-
-    private ItemConfiguration removeSeamFromSolution(ItemConfiguration solution) {
-        solution.map.forEach((view, cell) -> cell.cellX = cell.cellX > mCountX / 2
-                ? cell.cellX - 1 : cell.cellX);
-        solution.cellX = solution.cellX > mCountX / 2 ? solution.cellX - 1 : solution.cellX;
-        return solution;
-    }
-
-
-
-    GridOccupancy createGridOccupancyWithSeam(GridOccupancy gridOccupancy) {
-        GridOccupancy grid = new GridOccupancy(getCountX(), getCountY());
-        for (int x = 0; x < getCountX(); x++) {
-            for (int y = 0; y < getCountY(); y++) {
-                int offset = x >= getCountX() / 2 ? 1 : 0;
-                if (x == getCountX() / 2) {
-                    grid.cells[x][y] = true;
-                } else {
-                    grid.cells[x][y] = gridOccupancy.cells[x - offset][y];
-                }
-            }
-        }
-        return grid;
-    }
-
-    @Override
-    protected void copyCurrentStateToSolution(ItemConfiguration solution, boolean temp) {
+    public void copyCurrentStateToSolution(ItemConfiguration solution, boolean temp) {
         int childCount = mShortcutsAndWidgets.getChildCount();
         for (int i = 0; i < childCount; i++) {
             View child = mShortcutsAndWidgets.getChildAt(i);
@@ -196,4 +121,24 @@
         mLeftBackground.setBounds(rect.left, rect.top, rect.right / 2 - 20, rect.bottom);
         mRightBackground.setBounds(rect.right / 2 + 20, rect.top, rect.right, rect.bottom);
     }
+
+    public void setCountX(int countX) {
+        mCountX = countX;
+    }
+
+    public void setCountY(int countY) {
+        mCountY = countY;
+    }
+
+    public void setOccupied(GridOccupancy occupied) {
+        mOccupied = occupied;
+    }
+
+    public boolean isSeamWasAdded() {
+        return mSeamWasAdded;
+    }
+
+    public void setSeamWasAdded(boolean seamWasAdded) {
+        mSeamWasAdded = seamWasAdded;
+    }
 }