/*************************************************************************
 *
 * Copyright 2009 by bBreak Systems.
 *
 * ExCella Reports - Excelファイルを利用した帳票ツール
 *
 * $Id: RemoveControlRowAdapter.java 5 2009-06-22 07:55:44Z tomo-shibata $
 * $Revision: 5 $
 *
 * This file is part of ExCella Reports.
 *
 * ExCella Reports is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * ExCella Reports is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the COPYING.LESSER file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with ExCella Reports .  If not, see
 * <http://www.gnu.org/licenses/lgpl-3.0-standalone.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
package org.bbreak.excella.reports.listener;

import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.bbreak.excella.core.SheetData;
import org.bbreak.excella.core.SheetParser;
import org.bbreak.excella.core.exception.ParseException;
import org.bbreak.excella.core.tag.TagParser;
import org.bbreak.excella.reports.tag.ReportsTagParser;

/**
 * シート解析後に制御行を削除するアダプタ
 * 
 * @since 1.0
 */
public class RemoveControlRowAdapter extends ReportProcessAdaptor {

    /*
     * (non-Javadoc)
     * 
     * @see org.bbreak.excella.reports.listener.ReportProcessAdaptor#postParse(org.apache.poi.ss.usermodel.Sheet, org.bbreak.excella.core.SheetParser, org.bbreak.excella.core.SheetData)
     */
    @Override
    public void postParse( Sheet sheet, SheetParser sheetParser, SheetData sheetData) throws ParseException {

        Set<Integer> removeRows = new TreeSet<Integer>( Collections.reverseOrder());

        Iterator<Row> rowIterator = sheet.iterator();
        while ( rowIterator.hasNext()) {
            Row row = rowIterator.next();
            if ( row != null) {
                if ( isControlRow( sheet, sheetParser, row)) {
                    removeRows.add( row.getRowNum());
                }
            }
        }

        for ( Integer rowIndex : removeRows) {
            // 最終行だったら、削除
            if ( rowIndex == sheet.getLastRowNum()) {
                sheet.removeRow( sheet.getRow( rowIndex));
            } else {
                sheet.removeRow( sheet.getRow( rowIndex));
                sheet.shiftRows( rowIndex + 1, sheet.getLastRowNum(), -1);
            }
        }
    }

    /**
     * 制御行の有無を返す。
     * 
     * @param sheet
     * @param sheetParser
     * @param row
     * @return
     */
    private boolean isControlRow( Sheet sheet, SheetParser sheetParser, Row row) {

        List<TagParser<?>> parsers = sheetParser.getTagParsers();

        Iterator<Cell> cellIterator = row.cellIterator();

        while ( cellIterator.hasNext()) {
            Cell cell = cellIterator.next();

            for ( TagParser<?> parser : parsers) {
                try {
                    if ( parser.isParse( sheet, cell)) {
                        if ( parser instanceof ReportsTagParser) {
                            ReportsTagParser<?> reportsTagParser = ( ReportsTagParser<?>) parser;
                            if ( reportsTagParser.useControlRow()) {
                                return true;
                            }
                        }
                    }
                } catch ( ParseException e) {
                    // 解析できないものは扱わない
                    continue;
                }
            }
        }
        return false;
    }

}
