/*
 * 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.commons.math4.legacy.ode;

import org.apache.commons.math4.legacy.core.RealFieldElement;
import org.apache.commons.math4.legacy.exception.MaxCountExceededException;
import org.apache.commons.math4.legacy.ode.sampling.FieldStepHandler;
import org.apache.commons.math4.legacy.ode.sampling.FieldStepInterpolator;

/**
 * This class is used to handle steps for the test problems
 * integrated during the junit tests for the ODE integrators.
 * @param <T> the type of the field elements
 */
public class TestFieldProblemHandler<T extends RealFieldElement<T>>
    implements FieldStepHandler<T> {

    /** Associated problem. */
    private TestFieldProblemAbstract<T> problem;

    /** Maximal errors encountered during the integration. */
    private T maxValueError;
    private T maxTimeError;

    /** Error at the end of the integration. */
    private T lastError;

    /** Time at the end of integration. */
    private T lastTime;

    /** ODE solver used. */
    private FirstOrderFieldIntegrator<T> integrator;

    /** Expected start for step. */
    private T expectedStepStart;

    /**
     * Simple constructor.
     * @param problem problem for which steps should be handled
     * @param integrator ODE solver used
     */
    public TestFieldProblemHandler(TestFieldProblemAbstract<T> problem, FirstOrderFieldIntegrator<T> integrator) {
        this.problem      = problem;
        this.integrator   = integrator;
        maxValueError     = problem.getField().getZero();
        maxTimeError      = problem.getField().getZero();
        lastError         = problem.getField().getZero();
        expectedStepStart = null;
    }

    @Override
    public void init(FieldODEStateAndDerivative<T> state0, T t) {
        maxValueError     = problem.getField().getZero();
        maxTimeError      = problem.getField().getZero();
        lastError         = problem.getField().getZero();
        expectedStepStart = null;
    }

    @Override
    public void handleStep(FieldStepInterpolator<T> interpolator, boolean isLast) throws MaxCountExceededException {

        T start = integrator.getCurrentStepStart().getTime();
        if (start.subtract(problem.getInitialState().getTime()).divide(integrator.getCurrentSignedStepsize()).abs().getReal() > 0.001) {
            // multistep integrators do not handle the first steps themselves
            // so we have to make sure the integrator we look at has really started its work
            if (expectedStepStart != null) {
                // the step should either start at the end of the integrator step
                // or at an event if the step is split into several substeps
                T stepError = RealFieldElement.max(maxTimeError, start.subtract(expectedStepStart).abs());
                for (T eventTime : problem.getTheoreticalEventsTimes()) {
                    stepError = RealFieldElement.min(stepError, start.subtract(eventTime).abs());
                }
                maxTimeError = RealFieldElement.max(maxTimeError, stepError);
            }
            expectedStepStart = start.add(integrator.getCurrentSignedStepsize());
        }

        T pT = interpolator.getPreviousState().getTime();
        T cT = interpolator.getCurrentState().getTime();
        T[] errorScale = problem.getErrorScale();

        // store the error at the last step
        if (isLast) {
            T[] interpolatedY = interpolator.getInterpolatedState(cT).getState();
            T[] theoreticalY  = problem.computeTheoreticalState(cT);
            for (int i = 0; i < interpolatedY.length; ++i) {
                T error = interpolatedY[i].subtract(theoreticalY[i]).abs();
                lastError = RealFieldElement.max(error, lastError);
            }
            lastTime = cT;
        }

        // walk through the step
        for (int k = 0; k <= 20; ++k) {

            T time = pT.add(cT.subtract(pT).multiply(k).divide(20));
            T[] interpolatedY = interpolator.getInterpolatedState(time).getState();
            T[] theoreticalY  = problem.computeTheoreticalState(time);

            // update the errors
            for (int i = 0; i < interpolatedY.length; ++i) {
                T error = errorScale[i].multiply(interpolatedY[i].subtract(theoreticalY[i]).abs());
                maxValueError = RealFieldElement.max(error, maxValueError);
            }
        }
    }

    /**
     * Get the maximal value error encountered during integration.
     * @return maximal value error
     */
    public T getMaximalValueError() {
        return maxValueError;
    }

    /**
     * Get the maximal time error encountered during integration.
     * @return maximal time error
     */
    public T getMaximalTimeError() {
        return maxTimeError;
    }

    /**
     * Get the error at the end of the integration.
     * @return error at the end of the integration
     */
    public T getLastError() {
        return lastError;
    }

    /**
     * Get the time at the end of the integration.
     * @return time at the end of the integration.
     */
    public T getLastTime() {
        return lastTime;
    }

}
