/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You 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 org.apache.poi.hssf.record.aggregates;

import java.util.ArrayList;
import java.util.List;

import org.apache.poi.hssf.model.RecordStream;
import org.apache.poi.hssf.record.MergeCellsRecord;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellRangeAddressList;

public final class MergedCellsTable extends RecordAggregate {
	// enforced by the 8224 byte limit
	private static final int MAX_MERGED_REGIONS = 1027;

	private final List<CellRangeAddress> _mergedRegions;

	/**
	 * Creates an empty aggregate
	 */
	public MergedCellsTable() {
		_mergedRegions = new ArrayList<>();
	}

	/**
	 * reads zero or more consecutive {@link MergeCellsRecord}s
	 * @param rs
	 */
	public void read(RecordStream rs) {
        while (rs.peekNextClass() == MergeCellsRecord.class) {
			MergeCellsRecord mcr = (MergeCellsRecord) rs.getNext();
			int nRegions = mcr.getNumAreas();
			for (int i = 0; i < nRegions; i++) {
				CellRangeAddress cra = mcr.getAreaAt(i);
				_mergedRegions.add(cra);
			}
		}
	}

	@Override
	public int getRecordSize() {
		// a bit cheaper than the default impl
		int nRegions = _mergedRegions.size();
		if (nRegions < 1) {
			// no need to write a single empty MergeCellsRecord
			return 0;
		}
		int nMergedCellsRecords = nRegions / MAX_MERGED_REGIONS;
		int nLeftoverMergedRegions = nRegions % MAX_MERGED_REGIONS;

        return nMergedCellsRecords
                * (4 + CellRangeAddressList.getEncodedSize(MAX_MERGED_REGIONS)) + 4
                + CellRangeAddressList.getEncodedSize(nLeftoverMergedRegions);
	}

	@Override
    public void visitContainedRecords(RecordVisitor rv) {
		int nRegions = _mergedRegions.size();
		if (nRegions < 1) {
			// no need to write a single empty MergeCellsRecord
			return;
		}

		int nFullMergedCellsRecords = nRegions / MAX_MERGED_REGIONS;
		int nLeftoverMergedRegions = nRegions % MAX_MERGED_REGIONS;
		CellRangeAddress[] cras = new CellRangeAddress[nRegions];
		_mergedRegions.toArray(cras);

		for (int i = 0; i < nFullMergedCellsRecords; i++) {
			int startIx = i * MAX_MERGED_REGIONS;
			rv.visitRecord(new MergeCellsRecord(cras, startIx, MAX_MERGED_REGIONS));
		}
		if (nLeftoverMergedRegions > 0) {
			int startIx = nFullMergedCellsRecords * MAX_MERGED_REGIONS;
			rv.visitRecord(new MergeCellsRecord(cras, startIx, nLeftoverMergedRegions));
		}
	}
	public void addRecords(MergeCellsRecord[] mcrs) {
		for (int i = 0; i < mcrs.length; i++) {
			addMergeCellsRecord(mcrs[i]);
		}
	}

	private void addMergeCellsRecord(MergeCellsRecord mcr) {
		int nRegions = mcr.getNumAreas();
		for (int i = 0; i < nRegions; i++) {
			CellRangeAddress cra = mcr.getAreaAt(i);
			_mergedRegions.add(cra);
		}
	}

	public CellRangeAddress get(int index) {
		checkIndex(index);
		return _mergedRegions.get(index);
	}

	public void remove(int index) {
		checkIndex(index);
		_mergedRegions.remove(index);
	}

	private void checkIndex(int index) {
		if (index < 0 || index >= _mergedRegions.size()) {
			throw new IllegalArgumentException("Specified CF index " + index
					+ " is outside the allowable range (0.." + (_mergedRegions.size() - 1) + ")");
		}
	}

	public void addArea(int rowFrom, int colFrom, int rowTo, int colTo) {
		_mergedRegions.add(new CellRangeAddress(rowFrom, rowTo, colFrom, colTo));
	}

	public int getNumberOfMergedRegions() {
		return _mergedRegions.size();
	}
}
