/*
 * 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.math3.ode;

import java.lang.reflect.Array;

import org.apache.commons.math3.Field;
import org.apache.commons.math3.RealFieldElement;
import org.apache.commons.math3.ode.events.FieldEventHandler;
import org.apache.commons.math3.util.MathArrays;

/**
 * This class is used as the base class of the problems that are
 * integrated during the junit tests for the ODE integrators.
 * @param <T> the type of the field elements
 */
public abstract class TestFieldProblemAbstract<T extends RealFieldElement<T>>
    implements FirstOrderFieldDifferentialEquations<T> {

    /** Field to which elements belong. */
    private Field<T> field;

    /** Dimension of the problem. */
    private int n;

    /** Number of functions calls. */
    private int calls;

    /** Initial time */
    private T t0;

    /** Initial state */
    private T[] y0;

    /** Final time */
    private T t1;

    /** Error scale */
    private T[] errorScale;

    /**
     * Simple constructor.
     * @param field field to which elements belong
     */
    protected TestFieldProblemAbstract(Field<T> field) {
        this.field = field;
        n          = 0;
        calls      = 0;
        t0         = field.getZero();
        y0         = null;
        t1         = field.getZero();
        errorScale = null;
    }

    /**
     * Set the initial conditions
     * @param t0 initial time
     * @param y0 initial state vector
     */
    protected void setInitialConditions(T t0, T[] y0) {
        calls     = 0;
        n         = y0.length;
        this.t0   = t0;
        this.y0   = y0.clone();
    }

    /**
     * Set the final conditions.
     * @param t1 final time
     */
    protected void setFinalConditions(T t1) {
        this.t1 = t1;
    }

    /**
     * Set the error scale
     * @param errorScale error scale
     */
    protected void setErrorScale(T[] errorScale) {
        this.errorScale = errorScale.clone();
    }

    /** get the filed to which elements belong.
     * @return field to which elements belong
     */
    public Field<T> getField() {
        return field;
    }

    /** Get the problem dimension.
     * @return problem dimension
     */
    public int getDimension() {
        return n;
    }

   /**
     * Get the initial state.
     * @return initial state
     */
    public FieldODEState<T> getInitialState() {
        return new FieldODEState<T>(t0, y0);
    }

    /**
     * Get the final time.
     * @return final time
     */
    public T getFinalTime() {
        return t1;
    }

    /**
     * Get the error scale.
     * @return error scale
     */
    public T[] getErrorScale() {
        return errorScale;
    }

    /**
     * Get the events handlers.
     * @return events handlers   */
    public FieldEventHandler<T>[] getEventsHandlers() {
        @SuppressWarnings("unchecked")
        final FieldEventHandler<T>[] empty =
                        (FieldEventHandler<T>[]) Array.newInstance(FieldEventHandler.class, 0);
        return empty;
    }

    /**
     * Get the theoretical events times.
     * @return theoretical events times
     */
    public T[] getTheoreticalEventsTimes() {
        return MathArrays.buildArray(field, 0);
    }

    /**
     * Get the number of calls.
     * @return nuber of calls
     */
    public int getCalls() {
        return calls;
    }

    /** {@inheritDoc} */
    public void init(T t0, T[] y0, T t) {
    }

    /** {@inheritDoc} */
    public T[] computeDerivatives(T t, T[] y) {
        ++calls;
        return doComputeDerivatives(t, y);
    }

    abstract public T[] doComputeDerivatives(T t, T[] y);

    /**
     * Compute the theoretical state at the specified time.
     * @param t time at which the state is required
     * @return state vector at time t
     */
    abstract public T[] computeTheoreticalState(T t);

    /** Convert a double.
     * @param d double to convert
     * @return converted double
     */
    protected T convert(double d) {
        return field.getZero().add(d);
    }

    /** Convert a one dimension array.
     * @param elements array elements
     * @return converted array
     */
    protected T[] convert(double ... elements) {
        T[] array = MathArrays.buildArray(field, elements.length);
        for (int i = 0; i < elements.length; ++i) {
            array[i] = convert(elements[i]);
        }
        return array;
    }

}
