/* ====================================================================
   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.CFHeader12Record;
import org.apache.poi.hssf.record.CFHeaderBase;
import org.apache.poi.hssf.record.CFHeaderRecord;
import org.apache.poi.hssf.record.CFRule12Record;
import org.apache.poi.hssf.record.CFRuleBase;
import org.apache.poi.hssf.record.CFRuleRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.ss.formula.FormulaShifter;
import org.apache.poi.ss.formula.ptg.AreaErrPtg;
import org.apache.poi.ss.formula.ptg.AreaPtg;
import org.apache.poi.ss.formula.ptg.Ptg;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.RecordFormatException;

/**
 * <p>CFRecordsAggregate - aggregates Conditional Formatting records CFHeaderRecord 
 * and number of up CFRuleRecord records together to simplify access to them.</p>
 * <p>Note that Excel versions before 2007 can only cope with a maximum of 3
 *  Conditional Formatting rules per sheet. Excel 2007 or newer can cope with
 *  unlimited numbers, as can Apache OpenOffice. This is an Excel limitation,
 *  not a file format one.</p>
 */
public final class CFRecordsAggregate extends RecordAggregate {
    /** Excel 97-2003 allows up to 3 conditional formating rules */
    private static final int MAX_97_2003_CONDTIONAL_FORMAT_RULES = 3;
    private static final POILogger logger = POILogFactory.getLogger(CFRecordsAggregate.class);

    private final CFHeaderBase header;

    /** List of CFRuleRecord objects */
    private final List<CFRuleBase> rules;

    private CFRecordsAggregate(CFHeaderBase pHeader, CFRuleBase[] pRules) {
        if(pHeader == null) {
            throw new IllegalArgumentException("header must not be null");
        }
        if(pRules == null) {
            throw new IllegalArgumentException("rules must not be null");
        }
        if(pRules.length > MAX_97_2003_CONDTIONAL_FORMAT_RULES) {
            logger.log(POILogger.WARN, "Excel versions before 2007 require that "
                    + "No more than " + MAX_97_2003_CONDTIONAL_FORMAT_RULES 
                    + " rules may be specified, " + pRules.length + " were found,"
                    + " this file will cause problems with old Excel versions");
        }
        if (pRules.length != pHeader.getNumberOfConditionalFormats()) {
            throw new RecordFormatException("Mismatch number of rules");
        }
        header = pHeader;
        rules = new ArrayList<CFRuleBase>(pRules.length);
        for (CFRuleBase pRule : pRules) {
            checkRuleType(pRule);
            rules.add(pRule);
        }
    }

    public CFRecordsAggregate(CellRangeAddress[] regions, CFRuleBase[] rules) {
        this(createHeader(regions, rules), rules);
    }
    private static CFHeaderBase createHeader(CellRangeAddress[] regions, CFRuleBase[] rules) {
        final CFHeaderBase header;
        if (rules.length == 0 || rules[0] instanceof CFRuleRecord) {
            header = new CFHeaderRecord(regions, rules.length);
        } else {
            header = new CFHeader12Record(regions, rules.length);
        }

        // set the "needs recalculate" by default to avoid Excel handling conditional formatting incorrectly
        // see bug 52122 for details
        header.setNeedRecalculation(true);

        return header;
    }

    /**
     * Create CFRecordsAggregate from a list of CF Records
     * @param rs - the stream to read from
     * @return CFRecordsAggregate object
     */
    public static CFRecordsAggregate createCFAggregate(RecordStream rs) {
        Record rec = rs.getNext();
        if (rec.getSid() != CFHeaderRecord.sid &&
            rec.getSid() != CFHeader12Record.sid) {
            throw new IllegalStateException("next record sid was " + rec.getSid() 
                    + " instead of " + CFHeaderRecord.sid + " or " +
                    CFHeader12Record.sid + " as expected");
        }

        CFHeaderBase header = (CFHeaderBase)rec;
        int nRules = header.getNumberOfConditionalFormats();

        CFRuleBase[] rules = new CFRuleBase[nRules];
        for (int i = 0; i < rules.length; i++) {
            rules[i] = (CFRuleBase) rs.getNext();
        }

        return new CFRecordsAggregate(header, rules);
    }

    /**
     * Create a deep clone of the record
     */
    public CFRecordsAggregate cloneCFAggregate() {
        CFRuleBase[] newRecs = new CFRuleBase[rules.size()];
        for (int i = 0; i < newRecs.length; i++) {
            newRecs[i] = getRule(i).clone();
        }
        return new CFRecordsAggregate(header.clone(), newRecs);
    }

    /**
     * @return the header. Never <code>null</code>.
     */
    public CFHeaderBase getHeader() {
        return header;
    }

    private void checkRuleIndex(int idx) {
        if(idx < 0 || idx >= rules.size()) {
            throw new IllegalArgumentException("Bad rule record index (" + idx 
                    + ") nRules=" + rules.size());
        }
    }
    private void checkRuleType(CFRuleBase r) {
        if (header instanceof CFHeaderRecord &&
                 r instanceof CFRuleRecord) {
            return;
        }
        if (header instanceof CFHeader12Record &&
                 r instanceof CFRule12Record) {
           return;
        }
        throw new IllegalArgumentException("Header and Rule must both be CF or both be CF12, can't mix");
    }

    public CFRuleBase getRule(int idx) {
        checkRuleIndex(idx);
        return rules.get(idx);
    }
    public void setRule(int idx, CFRuleBase r) {
        if (r == null) {
            throw new IllegalArgumentException("r must not be null");
        }
        checkRuleIndex(idx);
        checkRuleType(r);
        rules.set(idx, r);
    }
    public void addRule(CFRuleBase r) {
        if (r == null) {
            throw new IllegalArgumentException("r must not be null");
        }
        if(rules.size() >= MAX_97_2003_CONDTIONAL_FORMAT_RULES) {
            logger.log(POILogger.WARN, "Excel versions before 2007 cannot cope with" 
                    + " any more than " + MAX_97_2003_CONDTIONAL_FORMAT_RULES 
                    + " - this file will cause problems with old Excel versions");
        }
        checkRuleType(r);
        rules.add(r);
        header.setNumberOfConditionalFormats(rules.size());
    }
    public int getNumberOfRules() {
        return rules.size();
    }

    /**
     * String representation of CFRecordsAggregate
     */
    public String toString() {
        StringBuilder buffer = new StringBuilder();
        String type = "CF";
        if (header instanceof CFHeader12Record) {
            type = "CF12";
        }

        buffer.append("[").append(type).append("]\n");
        if( header != null ) {
            buffer.append(header.toString());
        }
        for (CFRuleBase cfRule : rules) {
            buffer.append(cfRule.toString());
        }
        buffer.append("[/").append(type).append("]\n");
        return buffer.toString();
    }

    public void visitContainedRecords(RecordVisitor rv) {
        rv.visitRecord(header);
        for (CFRuleBase rule : rules) {
            rv.visitRecord(rule);
        }
    }

    /**
     * @return <code>false</code> if this whole {@link CFHeaderRecord} / {@link CFRuleRecord}s should be deleted
     */
    public boolean updateFormulasAfterCellShift(FormulaShifter shifter, int currentExternSheetIx) {
        CellRangeAddress[] cellRanges = header.getCellRanges();
        boolean changed = false;
        List<CellRangeAddress> temp = new ArrayList<CellRangeAddress>();
        for (CellRangeAddress craOld : cellRanges) {
            CellRangeAddress craNew = shiftRange(shifter, craOld, currentExternSheetIx);
            if (craNew == null) {
                changed = true;
                continue;
            }
            temp.add(craNew);
            if (craNew != craOld) {
                changed = true;
            }
        }

        if (changed) {
            int nRanges = temp.size();
            if (nRanges == 0) {
                return false;
            }
            CellRangeAddress[] newRanges = new CellRangeAddress[nRanges];
            temp.toArray(newRanges);
            header.setCellRanges(newRanges);
        }

        for (CFRuleBase rule : rules) {
            Ptg[] ptgs;
            ptgs = rule.getParsedExpression1();
            if (ptgs != null && shifter.adjustFormula(ptgs, currentExternSheetIx)) {
                rule.setParsedExpression1(ptgs);
            }
            ptgs = rule.getParsedExpression2();
            if (ptgs != null && shifter.adjustFormula(ptgs, currentExternSheetIx)) {
                rule.setParsedExpression2(ptgs);
            }
            if (rule instanceof CFRule12Record) {
                CFRule12Record rule12 = (CFRule12Record)rule;
                ptgs = rule12.getParsedExpressionScale();
                if (ptgs != null && shifter.adjustFormula(ptgs, currentExternSheetIx)) {
                    rule12.setParsedExpressionScale(ptgs);
                }
            }
        }
        return true;
    }

    private static CellRangeAddress shiftRange(FormulaShifter shifter, CellRangeAddress cra, int currentExternSheetIx) {
        // FormulaShifter works well in terms of Ptgs - so convert CellRangeAddress to AreaPtg (and back) here
        AreaPtg aptg = new AreaPtg(cra.getFirstRow(), cra.getLastRow(), cra.getFirstColumn(), cra.getLastColumn(), false, false, false, false);
        Ptg[] ptgs = { aptg, };

        if (!shifter.adjustFormula(ptgs, currentExternSheetIx)) {
            return cra;
        }
        Ptg ptg0 = ptgs[0];
        if (ptg0 instanceof AreaPtg) {
            AreaPtg bptg = (AreaPtg) ptg0;
            return new CellRangeAddress(bptg.getFirstRow(), bptg.getLastRow(), bptg.getFirstColumn(), bptg.getLastColumn());
        }
        if (ptg0 instanceof AreaErrPtg) {
            return null;
        }
        throw new IllegalStateException("Unexpected shifted ptg class (" + ptg0.getClass().getName() + ")");
    }
}
