/* ====================================================================
   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.ss.formula;

import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

import org.apache.poi.ss.formula.eval.BlankEval;
import org.apache.poi.ss.formula.eval.BoolEval;
import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.eval.RefEval;
import org.apache.poi.ss.formula.eval.StringEval;
import org.apache.poi.ss.formula.eval.ValueEval;
import org.apache.poi.ss.formula.functions.AggregateFunction;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.ConditionFilterData;
import org.apache.poi.ss.usermodel.ConditionFilterType;
import org.apache.poi.ss.usermodel.ConditionType;
import org.apache.poi.ss.usermodel.ConditionalFormatting;
import org.apache.poi.ss.usermodel.ConditionalFormattingRule;
import org.apache.poi.ss.usermodel.ExcelNumberFormat;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.util.LocaleUtil;

/**
 * Abstracted and cached version of a Conditional Format rule for use with a
 * {@link ConditionalFormattingEvaluator}. This references a rule, its owning
 * {@link ConditionalFormatting}, its priority order (lower index = higher priority in Excel),
 * and the information needed to evaluate the rule for a given cell.
 * <p>
 * Having this all combined and cached avoids repeated access calls to the
 * underlying structural objects, XSSF CT* objects and HSSF raw byte structures.
 * Those objects can be referenced from here. This object will be out of sync if
 * anything modifies the referenced structures' evaluation properties.
 * <p>
 * The assumption is that consuming applications will read the display properties once and
 * create whatever style objects they need, caching those at the application level.
 * Thus this class only caches values needed for evaluation, not display.
 */
public class EvaluationConditionalFormatRule implements Comparable<EvaluationConditionalFormatRule> {

    private final WorkbookEvaluator workbookEvaluator;
    private final Sheet sheet;
    private final ConditionalFormatting formatting;
    private final ConditionalFormattingRule rule;

    /* cached values */
    private final CellRangeAddress[] regions;

    private CellRangeAddress topLeftRegion;

    /**
     * Depending on the rule type, it may want to know about certain values in the region when evaluating {@link #matches(CellReference)},
     * such as top 10, unique, duplicate, average, etc.  This collection stores those if needed so they are not repeatedly calculated
     */
    private final Map<CellRangeAddress, Set<ValueAndFormat>> meaningfulRegionValues = new HashMap<>();

    private final int priority;
    private final int formattingIndex;
    private final int ruleIndex;
    private final String formula1;
    private final String formula2;
    private final String text;
    // cached for performance, used with cell text comparisons, which are case insensitive and need to be Locale aware (contains, starts with, etc.)
    private final String lowerText;

    private final OperatorEnum operator;
    private final ConditionType type;
    // cached for performance, to avoid reading the XMLBean every time a conditionally formatted cell is rendered
    private final ExcelNumberFormat numberFormat;
    // cached for performance, used to format numeric cells for string comparisons.  See Bug #61764 for explanation
    private final DecimalFormat decimalTextFormat;

    /**
     *
     * @param workbookEvaluator
     * @param sheet
     * @param formatting
     * @param formattingIndex for priority, zero based
     * @param rule
     * @param ruleIndex for priority, zero based, if this is an HSSF rule.  Unused for XSSF rules
     * @param regions could be read from formatting, but every call creates new objects in a new array.
     *                  this allows calling it once per formatting instance, and re-using the array.
     */
    public EvaluationConditionalFormatRule(WorkbookEvaluator workbookEvaluator, Sheet sheet, ConditionalFormatting formatting, int formattingIndex, ConditionalFormattingRule rule, int ruleIndex, CellRangeAddress[] regions) {
        super();
        this.workbookEvaluator = workbookEvaluator;
        this.sheet = sheet;
        this.formatting = formatting;
        this.rule = rule;
        this.formattingIndex = formattingIndex;
        this.ruleIndex = ruleIndex;

        this.priority = rule.getPriority();

        this.regions = regions;

        for (CellRangeAddress region : regions) {
            if (topLeftRegion == null) topLeftRegion = region;
            else if (region.getFirstColumn() < topLeftRegion.getFirstColumn()
                    || region.getFirstRow() < topLeftRegion.getFirstRow()) {
                topLeftRegion = region;
            }
        }
        formula1 = rule.getFormula1();
        formula2 = rule.getFormula2();

        text = rule.getText();
        lowerText = text == null ? null : text.toLowerCase(LocaleUtil.getUserLocale());

        numberFormat = rule.getNumberFormat();

        operator = OperatorEnum.values()[rule.getComparisonOperation()];
        type = rule.getConditionType();

//         Excel uses the stored text representation from the XML apparently, in tests done so far
        decimalTextFormat = new DecimalFormat("0", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
        decimalTextFormat.setMaximumFractionDigits(340); // DecimalFormat.DOUBLE_FRACTION_DIGITS, which is default scoped
    }

    /**
     * @return sheet
     */
    public Sheet getSheet() {
        return sheet;
    }

    /**
     * @return the formatting
     */
    public ConditionalFormatting getFormatting() {
        return formatting;
    }

    /**
     * @return conditional formatting index
     */
    public int getFormattingIndex() {
        return formattingIndex;
    }

    /**
     * @return Excel number format string to apply to matching cells, or null to keep the cell default
     */
    public ExcelNumberFormat getNumberFormat() {
        return numberFormat;
    }

    /**
     * @return the rule
     */
    public ConditionalFormattingRule getRule() {
        return rule;
    }

    /**
     * @return rule index
     */
    public int getRuleIndex() {
        return ruleIndex;
    }

    /**
     * @return the regions
     */
    public CellRangeAddress[] getRegions() {
        return regions;
    }

    /**
     * @return the priority
     */
    public int getPriority() {
        return priority;
    }

    /**
     * @return the formula1
     */
    public String getFormula1() {
        return formula1;
    }

    /**
     * @return the formula2
     */
    public String getFormula2() {
        return formula2;
    }

    /**
     * @return condition text if any, or null
     */
    public String getText() {
        return text;
    }

    /**
     * @return the operator
     */
    public OperatorEnum getOperator() {
        return operator;
    }

    /**
     * @return the type
     */
    public ConditionType getType() {
        return type;
    }

    /**
     * Defined as equal sheet name and formatting and rule indexes
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (! obj.getClass().equals(this.getClass())) {
            return false;
        }
        final EvaluationConditionalFormatRule r = (EvaluationConditionalFormatRule) obj;
        return getSheet().getSheetName().equalsIgnoreCase(r.getSheet().getSheetName())
            && getFormattingIndex() == r.getFormattingIndex()
            && getRuleIndex() == r.getRuleIndex();
    }

    /**
     * Per Excel Help, XSSF rule priority is sheet-wide, not just within the owning ConditionalFormatting object.
     * This can be seen by creating 4 rules applying to two different ranges and examining the XML.
     * <p>
     * HSSF priority is based on definition/persistence order.
     *
     * @param o
     * @return comparison based on sheet name, formatting index, and rule priority
     */
    @Override
    public int compareTo(EvaluationConditionalFormatRule o) {
        int cmp = getSheet().getSheetName().compareToIgnoreCase(o.getSheet().getSheetName());
        if (cmp != 0) {
            return cmp;
        }

        final int x = getPriority();
        final int y = o.getPriority();
        // logic from Integer.compare()
        cmp = Integer.compare(x, y);
        if (cmp != 0) {
            return cmp;
        }

        cmp = Integer.compare(getFormattingIndex(), o.getFormattingIndex());
        if (cmp != 0) {
            return cmp;
        }
        return Integer.compare(getRuleIndex(), o.getRuleIndex());
    }

    @Override
    public int hashCode() {
        return Objects.hash(sheet.getSheetName(),formattingIndex,ruleIndex);
    }

    /**
     * @param ref
     * @return true if this rule evaluates to true for the given cell
     */
    /* package */ boolean matches(CellReference ref) {
        // first check that it is in one of the regions defined for this format
        CellRangeAddress region = null;
        for (CellRangeAddress r : regions) {
            if (r.isInRange(ref)) {
                region = r;
                break;
            }
        }

        if (region == null) {
            // cell not in range of this rule
            return false;
        }

        final ConditionType ruleType = getRule().getConditionType();

        // these rules apply to all cells in a region. Specific condition criteria
        // may specify no special formatting for that value partition, but that's display logic
        if (ruleType.equals(ConditionType.COLOR_SCALE)
            || ruleType.equals(ConditionType.DATA_BAR)
            || ruleType.equals(ConditionType.ICON_SET)) {
           return true;
        }

        Cell cell = null;
        final Row row = sheet.getRow(ref.getRow());
        if (row != null) {
            cell = row.getCell(ref.getCol());
        }

        if (ruleType.equals(ConditionType.CELL_VALUE_IS)) {
            // undefined cells never match a VALUE_IS condition
            if (cell == null) return false;
            return checkValue(cell, topLeftRegion);
        }
        if (ruleType.equals(ConditionType.FORMULA)) {
            return checkFormula(ref, topLeftRegion);
        }
        if (ruleType.equals(ConditionType.FILTER)) {
            return checkFilter(cell, ref, topLeftRegion);
        }

        // TODO: anything else, we don't handle yet, such as top 10
        return false;
    }

    /**
     * @param cell the cell to check for
     * @param region for adjusting relative formulas
     * @return if the value of the cell is valid or not for the formatting rule
     */
    private boolean checkValue(Cell cell, CellRangeAddress region) {
        if (cell == null || DataValidationEvaluator.isType(cell, CellType.BLANK)
           || DataValidationEvaluator.isType(cell,CellType.ERROR)
           || (DataValidationEvaluator.isType(cell,CellType.STRING)
                   && (cell.getStringCellValue() == null || cell.getStringCellValue().isEmpty())
               )
           ) {
            return false;
        }

        ValueEval eval = unwrapEval(workbookEvaluator.evaluate(rule.getFormula1(), ConditionalFormattingEvaluator.getRef(cell), region));

        String f2 = rule.getFormula2();
        ValueEval eval2 = BlankEval.instance;
        if (f2 != null && f2.length() > 0) {
            eval2 = unwrapEval(workbookEvaluator.evaluate(f2, ConditionalFormattingEvaluator.getRef(cell), region));
        }

        // we assume the cell has been evaluated, and the current formula value stored
        if (DataValidationEvaluator.isType(cell, CellType.BOOLEAN)
                && (eval == BlankEval.instance || eval instanceof BoolEval)
                && (eval2 == BlankEval.instance || eval2 instanceof BoolEval)
           ) {
            return operator.isValid(cell.getBooleanCellValue(), eval == BlankEval.instance ? null : ((BoolEval) eval).getBooleanValue(), eval2 == BlankEval.instance ? null : ((BoolEval) eval2).getBooleanValue());
        }
        if (DataValidationEvaluator.isType(cell, CellType.NUMERIC)
                && (eval == BlankEval.instance || eval instanceof NumberEval )
                && (eval2 == BlankEval.instance || eval2 instanceof NumberEval)
           ) {
            return operator.isValid(cell.getNumericCellValue(), eval == BlankEval.instance ? null : ((NumberEval) eval).getNumberValue(), eval2 == BlankEval.instance ? null : ((NumberEval) eval2).getNumberValue());
        }
        if (DataValidationEvaluator.isType(cell, CellType.STRING)
                && (eval == BlankEval.instance || eval instanceof StringEval )
                && (eval2 == BlankEval.instance || eval2 instanceof StringEval)
           ) {
                return operator.isValid(cell.getStringCellValue(), eval == BlankEval.instance ? null : ((StringEval) eval).getStringValue(), eval2 == BlankEval.instance ? null : ((StringEval) eval2).getStringValue());
        }

        return operator.isValidForIncompatibleTypes();
    }

    private ValueEval unwrapEval(ValueEval eval) {
        ValueEval comp = eval;

        while (comp instanceof RefEval) {
            RefEval ref = (RefEval) comp;
            comp = ref.getInnerValueEval(ref.getFirstSheetIndex());
        }
        return comp;
    }
    /**
     * @param ref needed for offsets from region anchor - may be null!
     * @param region for adjusting relative formulas
     * @return true/false using the same rules as Data Validation evaluations
     */
    private boolean checkFormula(CellReference ref, CellRangeAddress region) {
        ValueEval comp = unwrapEval(workbookEvaluator.evaluate(rule.getFormula1(), ref, region));

        // Copied for now from DataValidationEvaluator.ValidationEnum.FORMULA#isValidValue()
        if (comp instanceof BlankEval) {
            return true;
        }
        if (comp instanceof ErrorEval) {
            return false;
        }
        if (comp instanceof BoolEval) {
            return ((BoolEval) comp).getBooleanValue();
        }
        // empirically tested in Excel - 0=false, any other number = true/valid
        // see test file DataValidationEvaluations.xlsx
        if (comp instanceof NumberEval) {
            return ((NumberEval) comp).getNumberValue() != 0;
        }
        return false; // anything else is false, such as text
    }

    private boolean checkFilter(Cell cell, CellReference ref, CellRangeAddress region) {
        final ConditionFilterType filterType = rule.getConditionFilterType();
        if (filterType == null) {
            return false;
        }

        final ValueAndFormat cv = getCellValue(cell);

        // TODO: this could/should be delegated to the Enum type, but that's in the usermodel package,
        // we may not want evaluation code there.  Of course, maybe the enum should go here in formula,
        // and not be returned by the SS model, but then we need the XSSF rule to expose the raw OOXML
        // type value, which isn't ideal either.
        switch (filterType) {
        case FILTER:
            return false; // we don't evaluate HSSF filters yet
        case TOP_10:
            // from testing, Excel only operates on numbers and dates (which are stored as numbers) in the range.
            // numbers stored as text are ignored, but numbers formatted as text are treated as numbers.

            if (! cv.isNumber()) {
                return false;
            }

            return getMeaningfulValues(region, false, new ValueFunction() {
                @Override
                public Set<ValueAndFormat> evaluate(List<ValueAndFormat> allValues) {
                    final ConditionFilterData conf = rule.getFilterConfiguration();

                    if (! conf.getBottom()) {
                        allValues.sort(Collections.reverseOrder());
                    } else {
                        Collections.sort(allValues);
                    }

                    int limit = Math.toIntExact(conf.getRank());
                    if (conf.getPercent()) {
                        limit = allValues.size() * limit / 100;
                    }
                    if (allValues.size() <= limit) {
                        return new HashSet<>(allValues);
                    }

                    return new HashSet<>(allValues.subList(0, limit));
                }
            }).contains(cv);
        case UNIQUE_VALUES:
            // Per Excel help, "duplicate" means matching value AND format
            // https://support.office.com/en-us/article/Filter-for-unique-values-or-remove-duplicate-values-ccf664b0-81d6-449b-bbe1-8daaec1e83c2
            return getMeaningfulValues(region, true, new ValueFunction() {
                @Override
                public Set<ValueAndFormat> evaluate(List<ValueAndFormat> allValues) {
                    Collections.sort(allValues);

                    final Set<ValueAndFormat> unique = new HashSet<>();

                    for (int i = 0; i < allValues.size(); i++) {
                        final ValueAndFormat v = allValues.get(i);
                        // skip this if the current value matches the next one, or is the last one and matches the previous one
                        if ( (i < allValues.size()-1 && v.equals(allValues.get(i+1)) ) || ( i > 0 && i == allValues.size()-1 && v.equals(allValues.get(i-1)) ) ) {
                            // current value matches next value, skip both
                            i++;
                            continue;
                        }
                        unique.add(v);
                    }

                    return unique;
                }
            }).contains(cv);
        case DUPLICATE_VALUES:
            // Per Excel help, "duplicate" means matching value AND format
            // https://support.office.com/en-us/article/Filter-for-unique-values-or-remove-duplicate-values-ccf664b0-81d6-449b-bbe1-8daaec1e83c2
            return getMeaningfulValues(region, true, new ValueFunction() {
                @Override
                public Set<ValueAndFormat> evaluate(List<ValueAndFormat> allValues) {
                    Collections.sort(allValues);

                    final Set<ValueAndFormat> dup = new HashSet<>();

                    for (int i = 0; i < allValues.size(); i++) {
                        final ValueAndFormat v = allValues.get(i);
                        // skip this if the current value matches the next one, or is the last one and matches the previous one
                        if ( (i < allValues.size()-1 && v.equals(allValues.get(i+1)) ) || ( i > 0 && i == allValues.size()-1 && v.equals(allValues.get(i-1)) ) ) {
                            // current value matches next value, add one
                            dup.add(v);
                            i++;
                        }
                    }
                    return dup;
                }
            }).contains(cv);
        case ABOVE_AVERAGE:
            // from testing, Excel only operates on numbers and dates (which are stored as numbers) in the range.
            // numbers stored as text are ignored, but numbers formatted as text are treated as numbers.

            final ConditionFilterData conf = rule.getFilterConfiguration();

            // actually ordered, so iteration order is predictable
            List<ValueAndFormat> values = new ArrayList<>(getMeaningfulValues(region, false, new ValueFunction() {
                @Override
                public Set<ValueAndFormat> evaluate(List<ValueAndFormat> allValues) {
                    double total = 0;
                    ValueEval[] pop = new ValueEval[allValues.size()];
                    for (int i = 0; i < allValues.size(); i++) {
                        ValueAndFormat v = allValues.get(i);
                        total += v.value.doubleValue();
                        pop[i] = new NumberEval(v.value.doubleValue());
                    }

                    final Set<ValueAndFormat> avgSet = new LinkedHashSet<>(1);
                    avgSet.add(new ValueAndFormat(Double.valueOf(allValues.size() == 0 ? 0 : total / allValues.size()), null, decimalTextFormat));

                    final double stdDev = allValues.size() <= 1 ? 0 : ((NumberEval) AggregateFunction.STDEV.evaluate(pop, 0, 0)).getNumberValue();
                    avgSet.add(new ValueAndFormat(Double.valueOf(stdDev), null, decimalTextFormat));
                    return avgSet;
                }
            }));

            Double val = cv.isNumber() ? cv.getValue() : null;
            if (val == null) {
                return false;
            }

            double avg = values.get(0).value.doubleValue();
            double stdDev = values.get(1).value.doubleValue();

            /*
             * use StdDev, aboveAverage, equalAverage to find:
             * comparison value
             * operator type
             */

            Double comp = Double.valueOf(conf.getStdDev() > 0 ? (avg + (conf.getAboveAverage() ? 1 : -1) * stdDev * conf.getStdDev()) : avg) ;

            final OperatorEnum op;
            if (conf.getAboveAverage()) {
                if (conf.getEqualAverage()) {
                    op = OperatorEnum.GREATER_OR_EQUAL;
                } else {
                    op = OperatorEnum.GREATER_THAN;
                }
            } else {
                if (conf.getEqualAverage()) {
                    op = OperatorEnum.LESS_OR_EQUAL;
                } else {
                    op = OperatorEnum.LESS_THAN;
                }
            }
            return op.isValid(val, comp, null);
        case CONTAINS_TEXT:
            // implemented both by a cfRule "text" attribute and a formula.  Use the text.
            return text == null ? false : cv.toString().toLowerCase(LocaleUtil.getUserLocale()).contains(lowerText);
        case NOT_CONTAINS_TEXT:
            // implemented both by a cfRule "text" attribute and a formula.  Use the text.
            return text == null ? true : ! cv.toString().toLowerCase(LocaleUtil.getUserLocale()).contains(lowerText);
        case BEGINS_WITH:
            // implemented both by a cfRule "text" attribute and a formula.  Use the text.
            return cv.toString().toLowerCase(LocaleUtil.getUserLocale()).startsWith(lowerText);
        case ENDS_WITH:
            // implemented both by a cfRule "text" attribute and a formula.  Use the text.
            return cv.toString().toLowerCase(LocaleUtil.getUserLocale()).endsWith(lowerText);
        case CONTAINS_BLANKS:
            try {
                String v = cv.getString();
                // see TextFunction.TRIM for implementation
                return v == null || v.trim().length() == 0;
            } catch (Exception e) {
                // not a valid string value, and not a blank cell (that's checked earlier)
                return false;
            }
        case NOT_CONTAINS_BLANKS:
            try {
                String v = cv.getString();
                // see TextFunction.TRIM for implementation
                return v != null && v.trim().length() > 0;
            } catch (Exception e) {
                // not a valid string value, but not blank
                return true;
            }
        case CONTAINS_ERRORS:
            return cell != null && DataValidationEvaluator.isType(cell, CellType.ERROR);
        case NOT_CONTAINS_ERRORS:
            return cell == null || ! DataValidationEvaluator.isType(cell, CellType.ERROR);
        case TIME_PERIOD:
            // implemented both by a cfRule "text" attribute and a formula.  Use the formula.
            return checkFormula(ref, region);
        default:
            return false;
        }
    }

    /**
     * from testing, Excel only operates on numbers and dates (which are stored as numbers) in the range.
     * numbers stored as text are ignored, but numbers formatted as text are treated as numbers.
     *
     * @param region
     * @return the meaningful values in the range of cells specified
     */
    private Set<ValueAndFormat> getMeaningfulValues(CellRangeAddress region, boolean withText, ValueFunction func) {
        Set<ValueAndFormat> values = meaningfulRegionValues.get(region);
        if (values != null) {
            return values;
        }

        List<ValueAndFormat> allValues = new ArrayList<>((region.getLastColumn() - region.getFirstColumn() + 1) * (region.getLastRow() - region.getFirstRow() + 1));

        for (int r=region.getFirstRow(); r <= region.getLastRow(); r++) {
            final Row row = sheet.getRow(r);
            if (row == null) {
                continue;
            }
            for (int c = region.getFirstColumn(); c <= region.getLastColumn(); c++) {
                Cell cell = row.getCell(c);
                final ValueAndFormat cv = getCellValue(cell);
                if (withText || cv.isNumber()) {
                    allValues.add(cv);
                }
            }
        }

        values = func.evaluate(allValues);
        meaningfulRegionValues.put(region, values);

        return values;
    }

    private ValueAndFormat getCellValue(Cell cell) {
        if (cell != null) {
            final String format = cell.getCellStyle().getDataFormatString();
            CellType type = cell.getCellType();
            if (type == CellType.FORMULA) {
                type = cell.getCachedFormulaResultType();
            }
            switch (type) {
                case NUMERIC:
                    return new ValueAndFormat(Double.valueOf(cell.getNumericCellValue()), format, decimalTextFormat);
                case STRING:
                case BOOLEAN:
                    return new ValueAndFormat(cell.getStringCellValue(), format);
                default:
                    break;
            }
        }
        return new ValueAndFormat("", "");
    }
    /**
     * instances evaluate the values for a region and return the positive matches for the function type.
     * TODO: when we get to use Java 8, this is obviously a Lambda Function.
     */
    protected interface ValueFunction {

        /**
         *
         * @param values
         * @return the desired values for the rules implemented by the current instance
         */
        Set<ValueAndFormat> evaluate(List<ValueAndFormat> values);
    }

    /**
     * Not calling it OperatorType to avoid confusion for now with other classes.
     * Definition order matches OOXML type ID indexes.
     * Note that this has NO_COMPARISON as the first item, unlike the similar
     * DataValidation operator enum. Thanks, Microsoft.
     */
    public static enum OperatorEnum {
        NO_COMPARISON {
            /** always false/invalid */
            @Override
            public <C extends Comparable<C>> boolean isValid(C cellValue, C v1, C v2) {
                return false;
            }
        },
        BETWEEN {
            @Override
            public <C extends Comparable<C>> boolean isValid(C cellValue, C v1, C v2) {
                if (v1 == null) {
                    if (cellValue instanceof Number) {
                        // use zero for null
                        double n1 = 0;
                        double n2 = v2 == null ? 0 : ((Number) v2).doubleValue();
                        return Double.compare( ((Number) cellValue).doubleValue(), n1) >= 0 && Double.compare(((Number) cellValue).doubleValue(), n2) <= 0;
                    } else if (cellValue instanceof String) {
                        String n1 = "";
                        String n2 = v2 == null ? "" : (String) v2;
                        return ((String) cellValue).compareToIgnoreCase(n1) >= 0 && ((String) cellValue).compareToIgnoreCase(n2) <= 0;
                    } else if (cellValue instanceof Boolean) return false;
                    return false; // just in case - not a typical possibility
                }
                return cellValue.compareTo(v1) >= 0 && cellValue.compareTo(v2) <= 0;
            }
        },
        NOT_BETWEEN {
            @Override
            public <C extends Comparable<C>> boolean isValid(C cellValue, C v1, C v2) {
                if (v1 == null) {
                    if (cellValue instanceof Number) {
                        // use zero for null
                        double n1 = 0;
                        double n2 = v2 == null ? 0 : ((Number) v2).doubleValue();
                        return Double.compare( ((Number) cellValue).doubleValue(), n1) < 0 || Double.compare(((Number) cellValue).doubleValue(), n2) > 0;
                    } else if (cellValue instanceof String) {
                        String n1 = "";
                        String n2 = v2 == null ? "" : (String) v2;
                        return ((String) cellValue).compareToIgnoreCase(n1) < 0 || ((String) cellValue).compareToIgnoreCase(n2) > 0;
                    } else if (cellValue instanceof Boolean) return true;
                    return false; // just in case - not a typical possibility
                }
                return cellValue.compareTo(v1) < 0 || cellValue.compareTo(v2) > 0;
            }

            public boolean isValidForIncompatibleTypes() {
                return true;
            }
        },
        EQUAL {
            @Override
            public <C extends Comparable<C>> boolean isValid(C cellValue, C v1, C v2) {
                if (v1 == null) {
                    if (cellValue instanceof Number) {
                        // use zero for null
                        return Double.compare( ((Number) cellValue).doubleValue(), 0) == 0;
                    } else if (cellValue instanceof String) {
                        return false; // even an empty string is not equal the empty cell, only another empty cell is, handled higher up
                    } else if (cellValue instanceof Boolean) return false;
                    return false; // just in case - not a typical possibility
                }
                // need to avoid instanceof, to work around a 1.6 compiler bug
                if (cellValue.getClass() == String.class) {
                    return cellValue.toString().compareToIgnoreCase(v1.toString()) == 0;
                }
                return cellValue.compareTo(v1) == 0;
            }
        },
        NOT_EQUAL {
            @Override
            public <C extends Comparable<C>> boolean isValid(C cellValue, C v1, C v2) {
                if (v1 == null) {
                    return true; // non-null not equal null, returns true
                }
                // need to avoid instanceof, to work around a 1.6 compiler bug
                if (cellValue.getClass() == String.class) {
                    return cellValue.toString().compareToIgnoreCase(v1.toString()) == 0;
                }
                return cellValue.compareTo(v1) != 0;
            }

            public boolean isValidForIncompatibleTypes() {
                return true;
            }
        },
        GREATER_THAN {
            @Override
            public <C extends Comparable<C>> boolean isValid(C cellValue, C v1, C v2) {
                if (v1 == null) {
                    if (cellValue instanceof Number) {
                        // use zero for null
                        return Double.compare( ((Number) cellValue).doubleValue(), 0) > 0;
                    } else if (cellValue instanceof String) {
                        return true; // non-null string greater than empty cell
                    } else if (cellValue instanceof Boolean) return true;
                    return false; // just in case - not a typical possibility
                }
                return cellValue.compareTo(v1) > 0;
            }
        },
        LESS_THAN {
            @Override
            public <C extends Comparable<C>> boolean isValid(C cellValue, C v1, C v2) {
                if (v1 == null) {
                    if (cellValue instanceof Number) {
                        // use zero for null
                        return Double.compare( ((Number) cellValue).doubleValue(), 0) < 0;
                    } else if (cellValue instanceof String) {
                        return false; // non-null string greater than empty cell
                    } else if (cellValue instanceof Boolean) return false;
                    return false; // just in case - not a typical possibility
                }
                return cellValue.compareTo(v1) < 0;
            }
        },
        GREATER_OR_EQUAL {
            @Override
            public <C extends Comparable<C>> boolean isValid(C cellValue, C v1, C v2) {
                if (v1 == null) {
                    if (cellValue instanceof Number) {
                        // use zero for null
                        return Double.compare( ((Number) cellValue).doubleValue(), 0) >= 0;
                    } else if (cellValue instanceof String) {
                        return true; // non-null string greater than empty cell
                    } else if (cellValue instanceof Boolean) return true;
                    return false; // just in case - not a typical possibility
                }
                return cellValue.compareTo(v1) >= 0;
            }
        },
        LESS_OR_EQUAL {
            @Override
            public <C extends Comparable<C>> boolean isValid(C cellValue, C v1, C v2) {
                if (v1 == null) {
                    if (cellValue instanceof Number) {
                        // use zero for null
                        return Double.compare( ((Number) cellValue).doubleValue(), 0) <= 0;
                    } else if (cellValue instanceof String) {
                        return false; // non-null string not less than empty cell
                    } else if (cellValue instanceof Boolean) return false; // for completeness
                    return false; // just in case - not a typical possibility
                }
                return cellValue.compareTo(v1) <= 0;
            }
        },
        ;

        /**
         * Evaluates comparison using operator instance rules
         * @param cellValue won't be null, assumption is previous checks handled that
         * @param v1 if null, per Excel behavior various results depending on the type of cellValue and the specific enum instance
         * @param v2 null if not needed.  If null when needed, various results, per Excel behavior
         * @return true if the comparison is valid
         */
        public abstract <C extends Comparable<C>> boolean isValid(C cellValue, C v1, C v2);

        /**
         * Called when the cell and comparison values are of different data types
         * Needed for negation operators, which should return true.
         * @return true if this comparison is true when the types to compare are different
         */
        public boolean isValidForIncompatibleTypes() {
            return false;
        }
    }

    /**
     * Note: this class has a natural ordering that is inconsistent with equals.
     */
    protected static class ValueAndFormat implements Comparable<ValueAndFormat> {

        private final Double value;
        private final String string;
        private final String format;
        private final DecimalFormat decimalTextFormat;

        public ValueAndFormat(Double value, String format, DecimalFormat df) {
            this.value = value;
            this.format = format;
            string = null;
            decimalTextFormat = df;
        }

        public ValueAndFormat(String value, String format) {
            this.value = null;
            this.format = format;
            string = value;
            decimalTextFormat = null;
        }

        public boolean isNumber() {
            return value != null;
        }

        public Double getValue() {
            return value;
        }

        public String getString() {
            return string;
        }

        public String toString() {
            if(isNumber()) {
                return decimalTextFormat.format(getValue().doubleValue());
            } else {
                return getString();
            }
        }

        @Override
        public boolean equals(Object obj) {
            if (!(obj instanceof ValueAndFormat)) {
                return false;
            }
            ValueAndFormat o = (ValueAndFormat) obj;
            return (Objects.equals(value, o.value)
                    && Objects.equals(format, o.format)
                    && Objects.equals(string, o.string));
        }

        /**
         * Note: this class has a natural ordering that is inconsistent with equals.
         * @param o
         * @return value comparison
         */
        @Override
        public int compareTo(ValueAndFormat o) {
            if (value == null && o.value != null) {
                return 1;
            }
            if (o.value == null && value != null) {
                return -1;
            }
            int cmp = value == null ? 0 : value.compareTo(o.value);
            if (cmp != 0) {
                return cmp;
            }

            if (string == null && o.string != null) {
                return 1;
            }
            if (o.string == null && string != null) {
                return -1;
            }

            return string == null ? 0 : string.compareTo(o.string);
        }

        @Override
        public int hashCode() {
            return Objects.hash(string,value,format);
        }
    }
}
