final Set coloverlaps = (Set) getColumnOverlapRefs(left, top, right, bottom, new HashSet());
final Set rowoverlaps = (Set) getRowOverlapRefs(left, top, right, bottom, new HashSet());
final Map orgoverlaps = new HashMap();
for (final Iterator it=coloverlaps.iterator(); it.hasNext();) {
final Reference ref = (Reference) it.next();
final int l = ref.getLeft();
final int t = ref.getTop();
final int r = ref.getRight();
final int b = ref.getBottom();
int dstl = (l>=left && l<=right) ?
(l + coloffset) : l;
int dstr = (r>=left && r<=right) ?
(r + coloffset) : r;
if (dstl > dstr) { //twist
final int tmp = dstl;
dstl = dstr;
dstr = tmp;
}
if (dstl >= dstleft && dstr <= dstright) { // after column move, and row in range
final int dstt = t + rowoffset;
final int dstb = b + rowoffset;
orgoverlaps.put(ref, new int[] {dstl, dstt, dstr, dstb});
}
}
for (final Iterator it=rowoverlaps.iterator(); it.hasNext();) {
final Reference ref = (Reference) it.next();
if (orgoverlaps.containsKey(ref)) { //handled already
continue;
}
final int l = ref.getLeft();
final int t = ref.getTop();
final int r = ref.getRight();
final int b = ref.getBottom();
int dstt = (t>=top && t<=bottom) ?
(t + rowoffset) : t;
int dstb = (b>=bottom && b<=bottom) ?
(b + rowoffset) : b;
if (dstt > dstb) { //twist
final int tmp = dstt;
dstt = dstb;
dstb = tmp;
}
if (dstt >= dsttop && dstb <= dstbottom) { // after row move, and column in range
final int dstl = l + coloffset;
final int dstr = r + coloffset;
orgoverlaps.put(ref, new int[] {dstl, dstt, dstr, dstb});
}
}
final Set totoverlaps = (Set) getTotalOverlapRefs(dstleft, dsttop, dstright, dstbottom, new HashSet());
for (final Iterator it = totoverlaps.iterator(); it.hasNext();) {
final Reference ref = (Reference) it.next();
if (!orgoverlaps.containsKey(ref)) {
ref.remove();
}
}
//TODO: Might need to separate matrix to matrixCell and matrixFormula to speedup formula operation.
//In the meantime, mark out the following
//for each Ref in orgoverlaps, move to new place
/* for (final Iterator it = orgoverlaps.entrySet().iterator(); it.hasNext();) {
final Entry me = (Entry) it.next();
final Ref2d ref = (Ref2d) me.getKey();
final int[] ltrb = (int[]) me.getValue();
final CellIndex lti = getCellIndex(ltrb[1], ltrb[0]);
final CellIndex rbi = getCellIndex(ltrb[3], ltrb[2]);
final Range org = new RangeSimple(_sheet, null, ref.getLeft(), ref.getTop(), ref.getRight(), ref.getBottom());
final Range mod = new RangeSimple(_sheet, null, ltrb[0], ltrb[1], ltrb[2], ltrb[3]);
changed.put(ref, new Range[] {org, mod});
ref.setLtIndex(lti);
ref.setRbIndex(rbi);
}
*/
final Set ltRefs = new HashSet();
if (rowoffset >= 0) { //move down
int x = Collections.binarySearch(_rows, new Integer(bottom));
if (x < 0) {
x = -x - 2; //-(x+1)-1
}
for(int j = x; j >= 0; --j) {
final RowIndex ri = (RowIndex) _rows.get(j);
if (ri.getRow() < top) {
break;
}
//getRowIndex might add RowIndex into _rows
//moveCellIndexTo might remove RowIndex from _rows
//however, in our case, we are doing decrease iterate,
//no matter added or removed it will not affect our operation,
//so no need to adjust sz and j
final RowIndex dstri = getRowIndex(ri.getRow()+rowoffset);
ri.moveToNewBoth(dstri, left, top, right, bottom, coloffset, rowoffset, ltRefs, changed);
}
} else { //move up
int x = Collections.binarySearch(_rows, new Integer(top));
if (x < 0) {
x = -(x+1);
}
int sz = _rows.size();
for(int j = x; j < sz; ++j) {
final RowIndex ri = (RowIndex) _rows.get(j);
if (ri.getRow() > bottom) {
break;
}
int jdiff = 0;
//getRowIndex might add RowIndex into _rows
//moveCellIndexTo might remove RowIndex from _rows
//must adjust sz and j
final RowIndex dstri = getRowIndex(ri.getRow()+rowoffset);
if (dstri.isEmpty() && rowoffset < 0) {
++jdiff;
}
if (ri.moveToNewBoth(dstri, left, top, right, bottom, coloffset, rowoffset, ltRefs, changed)) {
--jdiff;
}
j += jdiff;
sz = _rows.size();
}
}
//cannot adjust left-top simulataneously in above loop
//RowIndex can be removed or added unexpectedly, no proper way to adjust the j index above
for (final Iterator it = ltRefs.iterator(); it.hasNext(); ) {
final Ref2d ref = (Ref2d) it.next();
final CellIndex srcci = ref.getLtIndex();
final RowIndex srcri = srcci.getRowIndex();
final int col = srcci.getColumn();
final int row = srcri.getRow();
final CellIndex ci = getCellIndex(row+rowoffset, col+coloffset);
ci.addLtRef(ref);