1package com.android.launcher3.util;
2
3import android.graphics.Rect;
4
5import com.android.launcher3.ItemInfo;
6
7/**
8 * Utility object to manage the occupancy in a grid.
9 */
10public class GridOccupancy {
11
12    private final int mCountX;
13    private final int mCountY;
14
15    public final boolean[][] cells;
16
17    public GridOccupancy(int countX, int countY) {
18        mCountX = countX;
19        mCountY = countY;
20        cells = new boolean[countX][countY];
21    }
22
23    /**
24     * Find the first vacant cell, if there is one.
25     *
26     * @param vacantOut Holds the x and y coordinate of the vacant cell
27     * @param spanX Horizontal cell span.
28     * @param spanY Vertical cell span.
29     *
30     * @return true if a vacant cell was found
31     */
32    public boolean findVacantCell(int[] vacantOut, int spanX, int spanY) {
33        for (int y = 0; (y + spanY) <= mCountY; y++) {
34            for (int x = 0; (x + spanX) <= mCountX; x++) {
35                boolean available = !cells[x][y];
36                out:
37                for (int i = x; i < x + spanX; i++) {
38                    for (int j = y; j < y + spanY; j++) {
39                        available = available && !cells[i][j];
40                        if (!available) break out;
41                    }
42                }
43                if (available) {
44                    vacantOut[0] = x;
45                    vacantOut[1] = y;
46                    return true;
47                }
48            }
49        }
50        return false;
51    }
52
53    public void copyTo(GridOccupancy dest) {
54        for (int i = 0; i < mCountX; i++) {
55            for (int j = 0; j < mCountY; j++) {
56                dest.cells[i][j] = cells[i][j];
57            }
58        }
59    }
60
61    public boolean isRegionVacant(int x, int y, int spanX, int spanY) {
62        int x2 = x + spanX - 1;
63        int y2 = y + spanY - 1;
64        if (x < 0 || y < 0 || x2 >= mCountX || y2 >= mCountY) {
65            return false;
66        }
67        for (int i = x; i <= x2; i++) {
68            for (int j = y; j <= y2; j++) {
69                if (cells[i][j]) {
70                    return false;
71                }
72            }
73        }
74        return true;
75    }
76
77    public void markCells(int cellX, int cellY, int spanX, int spanY, boolean value) {
78        if (cellX < 0 || cellY < 0) return;
79        for (int x = cellX; x < cellX + spanX && x < mCountX; x++) {
80            for (int y = cellY; y < cellY + spanY && y < mCountY; y++) {
81                cells[x][y] = value;
82            }
83        }
84    }
85
86    public void markCells(Rect r, boolean value) {
87        markCells(r.left, r.top, r.width(), r.height(), value);
88    }
89
90    public void markCells(CellAndSpan cell, boolean value) {
91        markCells(cell.cellX, cell.cellY, cell.spanX, cell.spanY, value);
92    }
93
94    public void markCells(ItemInfo item, boolean value) {
95        markCells(item.cellX, item.cellY, item.spanX, item.spanY, value);
96    }
97
98    public void clear() {
99        markCells(0, 0, mCountX, mCountY, false);
100    }
101}
102