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

import org.apache.poi.ss.formula.ThreeDEval;
import org.apache.poi.ss.formula.TwoDEval;
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.EvaluationException;
import org.apache.poi.ss.formula.eval.NumberEval;
import org.apache.poi.ss.formula.eval.NumericValueEval;
import org.apache.poi.ss.formula.eval.OperandResolver;
import org.apache.poi.ss.formula.eval.RefEval;
import org.apache.poi.ss.formula.eval.StringValueEval;
import org.apache.poi.ss.formula.eval.ValueEval;

/**
 * This is the super class for all excel function evaluator
 * classes that take variable number of operands, and
 * where the order of operands does not matter
 */
public abstract class MultiOperandNumericFunction implements Function {

	private final boolean _isReferenceBoolCounted;
	private final boolean _isBlankCounted;

    protected MultiOperandNumericFunction(boolean isReferenceBoolCounted, boolean isBlankCounted) {
        _isReferenceBoolCounted = isReferenceBoolCounted;
        _isBlankCounted = isBlankCounted;
    }

	static final double[] EMPTY_DOUBLE_ARRAY = { };

	private static class DoubleList {
		private double[] _array;
		private int _count;

		public DoubleList() {
			_array = new double[8];
			_count = 0;
		}

		public double[] toArray() {
			if(_count < 1) {
				return EMPTY_DOUBLE_ARRAY;
			}
			double[] result = new double[_count];
			System.arraycopy(_array, 0, result, 0, _count);
			return result;
		}

		private void ensureCapacity(int reqSize) {
			if(reqSize > _array.length) {
				int newSize = reqSize * 3 / 2; // grow with 50% extra
				double[] newArr = new double[newSize];
				System.arraycopy(_array, 0, newArr, 0, _count);
				_array = newArr;
			}
		}

		public void add(double value) {
			ensureCapacity(_count + 1);
			_array[_count] = value;
			_count++;
		}
	}

	private static final int DEFAULT_MAX_NUM_OPERANDS = 30;

	public final ValueEval evaluate(ValueEval[] args, int srcCellRow, int srcCellCol) {

		double d;
		try {
			double[] values = getNumberArray(args);
			d = evaluate(values);
		} catch (EvaluationException e) {
			return e.getErrorEval();
		}

		if (Double.isNaN(d) || Double.isInfinite(d))
			return ErrorEval.NUM_ERROR;

		return new NumberEval(d);
	}

	protected abstract double evaluate(double[] values) throws EvaluationException;

	/**
	 * Maximum number of operands accepted by this function.
	 * Subclasses may override to change default value.
	 */
	protected int getMaxNumOperands() {
		return DEFAULT_MAX_NUM_OPERANDS;
	}

	/**
	 * Returns a double array that contains values for the numeric cells
	 * from among the list of operands. Blanks and Blank equivalent cells
	 * are ignored. Error operands or cells containing operands of type
	 * that are considered invalid and would result in #VALUE! error in
	 * excel cause this function to return <code>null</code>.
	 *
	 * @return never <code>null</code>
	 */
	protected final double[] getNumberArray(ValueEval[] operands) throws EvaluationException {
		if (operands.length > getMaxNumOperands()) {
			throw EvaluationException.invalidValue();
		}
		DoubleList retval = new DoubleList();

		for (int i=0, iSize=operands.length; i<iSize; i++) {
			collectValues(operands[i], retval);
		}
		return retval.toArray();
	}

    /**
     *  Whether to count nested subtotals.
     */
    public boolean isSubtotalCounted(){
        return true;
    }

	/**
	 * Collects values from a single argument
	 */
	private void collectValues(ValueEval operand, DoubleList temp) throws EvaluationException {
        if (operand instanceof ThreeDEval) {
            ThreeDEval ae = (ThreeDEval) operand;
            for (int sIx=ae.getFirstSheetIndex(); sIx <= ae.getLastSheetIndex(); sIx++) {
                int width = ae.getWidth();
                int height = ae.getHeight();
                for (int rrIx=0; rrIx<height; rrIx++) {
                    for (int rcIx=0; rcIx<width; rcIx++) {
                        ValueEval ve = ae.getValue(sIx, rrIx, rcIx);
                        if(!isSubtotalCounted() && ae.isSubTotal(rrIx, rcIx)) continue;
                        collectValue(ve, true, temp);
                    }
                }
            }
            return;
        }
		if (operand instanceof TwoDEval) {
			TwoDEval ae = (TwoDEval) operand;
			int width = ae.getWidth();
			int height = ae.getHeight();
			for (int rrIx=0; rrIx<height; rrIx++) {
				for (int rcIx=0; rcIx<width; rcIx++) {
					ValueEval ve = ae.getValue(rrIx, rcIx);
                    if(!isSubtotalCounted() && ae.isSubTotal(rrIx, rcIx)) continue;
                    collectValue(ve, true, temp);
				}
			}
			return;
		}
		if (operand instanceof RefEval) {
			RefEval re = (RefEval) operand;
			for (int sIx = re.getFirstSheetIndex(); sIx <= re.getLastSheetIndex(); sIx++) {
			    collectValue(re.getInnerValueEval(sIx), true, temp);
			}
			return;
		}
		collectValue(operand, false, temp);
	}
	private void collectValue(ValueEval ve, boolean isViaReference, DoubleList temp)  throws EvaluationException {
		if (ve == null) {
			throw new IllegalArgumentException("ve must not be null");
		}
		if (ve instanceof BoolEval) {
			if (!isViaReference || _isReferenceBoolCounted) {
				BoolEval boolEval = (BoolEval) ve;
				temp.add(boolEval.getNumberValue());
			}
			return;
		}
		if (ve instanceof NumericValueEval) {
			NumericValueEval ne = (NumericValueEval) ve;
			temp.add(ne.getNumberValue());
			return;
		}
		if (ve instanceof StringValueEval) {
			if (isViaReference) {
				// ignore all ref strings
				return;
			}
			String s = ((StringValueEval) ve).getStringValue();
			Double d = OperandResolver.parseDouble(s);
			if(d == null) {
				throw new EvaluationException(ErrorEval.VALUE_INVALID);
			}
			temp.add(d.doubleValue());
			return;
		}
		if (ve instanceof ErrorEval) {
			throw new EvaluationException((ErrorEval) ve);
		}
		if (ve == BlankEval.instance) {
			if (_isBlankCounted) {
				temp.add(0.0);
			}
			return;
		}
		throw new RuntimeException("Invalid ValueEval type passed for conversion: ("
				+ ve.getClass() + ")");
	}
}
