/* ====================================================================
   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 java.util.Arrays;

import org.apache.poi.ss.formula.eval.ErrorEval;
import org.apache.poi.ss.formula.eval.EvaluationException;

/**
 * Calculates Modified internal rate of return. Syntax is MIRR(cash_flow_values, finance_rate, reinvest_rate)
 *
 * <p>Returns the modified internal rate of return for a series of periodic cash flows. MIRR considers both the cost
 * of the investment and the interest received on reinvestment of cash.</p>
 *
 * Values is an array or a reference to cells that contain numbers. These numbers represent a series of payments (negative values) and income (positive values) occurring at regular periods.
 * <ul>
 *     <li>Values must contain at least one positive value and one negative value to calculate the modified internal rate of return. Otherwise, MIRR returns the #DIV/0! error value.</li>
 *     <li>If an array or reference argument contains text, logical values, or empty cells, those values are ignored; however, cells with the value zero are included.</li>
 * </ul>
 *
 * Finance_rate     is the interest rate you pay on the money used in the cash flows.
 * Reinvest_rate     is the interest rate you receive on the cash flows as you reinvest them.
 *
 * @see <a href="http://en.wikipedia.org/wiki/MIRR">Wikipedia on MIRR</a>
 * @see <a href="http://office.microsoft.com/en-001/excel-help/mirr-HP005209180.aspx">Excel MIRR</a>
 * @see Irr
 */
public class Mirr extends MultiOperandNumericFunction {

    public Mirr() {
        super(false, false);
    }

    @Override
    protected int getMaxNumOperands() {
        return 3;
    }

    @Override
    protected double evaluate(double[] values) throws EvaluationException {

        double financeRate = values[values.length-1];
        double reinvestRate = values[values.length-2];

        double[] mirrValues = Arrays.copyOf(values, values.length - 2);

        boolean mirrValuesAreAllNegatives = true;
        for (double mirrValue : mirrValues) {
            mirrValuesAreAllNegatives &= mirrValue < 0;
        }
         if (mirrValuesAreAllNegatives) {
             return -1.0d;
         }

        boolean mirrValuesAreAllPositives = true;
        for (double mirrValue : mirrValues) {
            mirrValuesAreAllPositives &= mirrValue > 0;
        }
        if (mirrValuesAreAllPositives) {
            throw new EvaluationException(ErrorEval.DIV_ZERO);
        }

        return mirr(mirrValues, financeRate, reinvestRate);
    }

    private static double mirr(double[] in, double financeRate, double reinvestRate) {
        double value = 0;
        double numOfYears = in.length - 1.;
        double pv = 0;
        double fv = 0;

        int indexN = 0;
        for (double anIn : in) {
            if (anIn < 0) {
                pv += anIn / Math.pow(1 + financeRate + reinvestRate, indexN++);
            }
        }

        for (double anIn : in) {
            if (anIn > 0) {
                fv += anIn * Math.pow(1 + financeRate, numOfYears - indexN++);
            }
        }

        if (fv != 0 && pv != 0) {
            value = Math.pow(-fv / pv, 1d / numOfYears) - 1;
        }
        return value;
    }
}
