/**
* Copyright (C) 2012 alanhay <alanhay99@hotmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package uk.co.certait.htmlexporter.ss;
import java.util.ArrayList;
import java.util.List;
/**
* A CellRange represents a range of cells. The range may or may not be
* contiguous. A CellRange is considered contiguous when traversing the range
* form the top left to bottom right there are no gaps found.
*
* @author alanhay
*
*/
public class CellRange {
private List<CellRangeRow> rows;
private List<CellRangeObserver> listeners;
public CellRange() {
rows = new ArrayList<CellRangeRow>();
listeners = new ArrayList<CellRangeObserver>();
}
/**
*
* @param cell
*/
public void addCell(TableCellReference cell) {
if (rows.size() == 0) {
rows.add(new CellRangeRow(cell.getRowIndex()));
} else if (isCellInNewRow(cell)) {
int lastRowIndex = rows.get(rows.size() - 1).getIndex();
for (int i = lastRowIndex; i < cell.getRowIndex(); ++i) {
rows.add(new CellRangeRow(i + 1));
}
}
rows.get(rows.size() - 1).addCell(cell);
notifyObservers();
}
/**
*
* @param listener
*/
public void addCellRangeObserver(CellRangeObserver listener) {
listeners.add(listener);
}
/**
* Notify any registered observers that a cell has been added.
*/
private void notifyObservers() {
for (CellRangeObserver listener : listeners) {
listener.cellRangeUpdated(this);
}
}
/**
*
* @param cell
* The cell to be added.
*
* @return True if this cell references a previously unreferenced row,
* otherwise false.
*/
protected boolean isCellInNewRow(TableCellReference cell) {
boolean isNewRow = true;
for (CellRangeRow row : rows) {
if (cell.getRowIndex() == row.getIndex()) {
isNewRow = false;
}
}
return isNewRow;
}
/**
* A CellRange is considered to be contiguous if all rows within it are
* contiguous and the first and last populated columns for all rows have the
* same indices.
*
* @return True if this CellRange is contiguous, otherwise false.
*/
public boolean isContiguous() {
boolean isContiguous = true;
int firstColumn = -99;
int lastColumn = -99;
boolean firstLoop = true;
for (CellRangeRow row : rows) {
if (!row.isContiguous()) {
isContiguous = false;
break;
} else {
if (!firstLoop) {
if (row.getFirstPopulatedColumn() != firstColumn || row.getLastPopulatedColumn() != lastColumn) {
isContiguous = false;
break;
}
} else {
firstColumn = row.getFirstPopulatedColumn();
lastColumn = row.getLastPopulatedColumn();
firstLoop = false;
}
}
}
return isContiguous;
}
/**
*
* @return
*/
public int getHeight() {
return rows.size();
}
/**
*
* @return
*/
public boolean isEmpty() {
boolean isEmpty = true;
for (CellRangeRow row : rows) {
if (!row.isEmpty()) {
isEmpty = false;
break;
}
}
return isEmpty;
}
/**
*
* @return The first cell in this range, that is the cell at the top left of
* the range.
*/
public TableCellReference getFirstCell() {
return rows.get(0).getFirstCell();
}
/**
*
* @return The last cell in this range, that is the cell at the bottom right
* of the range.
*/
public TableCellReference getLastCell() {
return rows.get(rows.size() - 1).getLastCell();
}
/**
*
* @return The rows which this range references.
*/
public List<CellRangeRow> getRows() {
return rows;
}
/**
*
*/
public String toString() {
StringBuilder builder = new StringBuilder();
for (CellRangeRow row : rows) {
builder.append("\nIndex").append(row.getIndex()).append(": ");
builder.append(row.toString()).append("\n");
}
return builder.toString();
}
}