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

/**
 * This class is used to simplify error handling logic <i>within</i> operator and function
 * implementations.   Note - <tt>OperationEval.evaluate()</tt> and <tt>Function.evaluate()</tt>
 * method signatures do not throw this exception so it cannot propagate outside.<p>
 *
 * Here is an example coded without <tt>EvaluationException</tt>, to show how it can help:
 * <pre>{@code
 * public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
 *	// ...
 *	Eval arg0 = args[0];
 *	if(arg0 instanceof ErrorEval) {
 *		return arg0;
 *	}
 *	if(!(arg0 instanceof AreaEval)) {
 *		return ErrorEval.VALUE_INVALID;
 *	}
 *	double temp = 0;
 *	AreaEval area = (AreaEval)arg0;
 *	ValueEval[] values = area.getValues();
 *	for (int i = 0; i < values.length; i++) {
 *		ValueEval ve = values[i];
 *		if(ve instanceof ErrorEval) {
 *			return ve;
 *		}
 *		if(!(ve instanceof NumericValueEval)) {
 *			return ErrorEval.VALUE_INVALID;
 *		}
 *		temp += ((NumericValueEval)ve).getNumberValue();
 *	}
 *	// ...
 * }
 * }</pre>
 * In this example, if any error is encountered while processing the arguments, an error is
 * returned immediately. This code is difficult to refactor due to all the points where errors
 * are returned.<br>
 * Using <tt>EvaluationException</tt> allows the error returning code to be consolidated to one
 * place.<p>
 * <pre>{@code
 * public Eval evaluate(Eval[] args, int srcRow, short srcCol) {
 *	try {
 *		// ...
 *		AreaEval area = getAreaArg(args[0]);
 *		double temp = sumValues(area.getValues());
 *		// ...
 *	} catch (EvaluationException e) {
 *		return e.getErrorEval();
 *	}
 *}
 *
 *private static AreaEval getAreaArg(Eval arg0) throws EvaluationException {
 *	if (arg0 instanceof ErrorEval) {
 *		throw new EvaluationException((ErrorEval) arg0);
 *	}
 *	if (arg0 instanceof AreaEval) {
 *		return (AreaEval) arg0;
 *	}
 *	throw EvaluationException.invalidValue();
 *}
 *
 *private double sumValues(ValueEval[] values) throws EvaluationException {
 *	double temp = 0;
 *	for (int i = 0; i < values.length; i++) {
 *		ValueEval ve = values[i];
 *		if (ve instanceof ErrorEval) {
 *			throw new EvaluationException((ErrorEval) ve);
 *		}
 *		if (!(ve instanceof NumericValueEval)) {
 *			throw EvaluationException.invalidValue();
 *		}
 *		temp += ((NumericValueEval) ve).getNumberValue();
 *	}
 *	return temp;
 *}
 * }</pre>
 * It is not mandatory to use EvaluationException, doing so might give the following advantages:<br>
 *  - Methods can more easily be extracted, allowing for re-use.<br>
 *  - Type management (typecasting etc) is simpler because error conditions have been separated from
 * intermediate calculation values.<br>
 *  - Fewer local variables are required. Local variables can have stronger types.<br>
 *  - It is easier to mimic common Excel error handling behaviour (exit upon encountering first
 *  error), because exceptions conveniently propagate up the call stack regardless of execution
 *  points or the number of levels of nested calls.<p>
 *
 * <b>Note</b> - Only standard evaluation errors are represented by <tt>EvaluationException</tt> (
 * i.e. conditions expected to be encountered when evaluating arbitrary Excel formulas). Conditions
 * that could never occur in an Excel spreadsheet should result in runtime exceptions. Care should
 * be taken to not translate any POI internal error into an Excel evaluation error code.
 *
 * @author Josh Micich
 */
public final class EvaluationException extends Exception {
	private final ErrorEval _errorEval;

	public EvaluationException(ErrorEval errorEval) {
		_errorEval = errorEval;
	}
	// some convenience factory methods

    /** <b>#VALUE!</b> - Wrong type of operand */
	public static EvaluationException invalidValue() {
		return new EvaluationException(ErrorEval.VALUE_INVALID);
	}
    /** <b>#REF!</b> - Illegal or deleted cell reference */
	public static EvaluationException invalidRef() {
		return new EvaluationException(ErrorEval.REF_INVALID);
	}
    /** <b>#NUM!</b> - Value range overflow */
	public static EvaluationException numberError() {
		return new EvaluationException(ErrorEval.NUM_ERROR);
	}

	public ErrorEval getErrorEval() {
		return _errorEval;
	}
}
