/*
     *
     *        function phase_space_state = get_phase_space_state (Particle_System)
     *      %GET_PHASE_SPACE_STATE  Retrieve phase space state vector.
     *      %
     *      %   Example
     *      %
     *      %   SS = GET_PHASE_SPACE_STATE (PS) returns the current 1-by-6*N
     *      %   phase space state vector SS from the particle system PS.
     *      %   N is the number of particles.
     *      %
     *      %   See also set_phase_space_state.
     *      %
     *      %   Copyright 2008-2008 buchholz.hs-bremen.de
     *
     *      positions = get_particles_positions (Particle_System);
     *      velocities = get_particles_velocities (Particle_System);
     *
     *      phase_space_state = [positions, velocities];
     *
     *  end
     *
     */

    // see the pdf page 56. quuestion about ode4. claims this is called 4 times by that.

    //function state_derivative = compute_state_derivative ...
    //(time , phase_space_state , Particle_System )

    // so i supose i have to pass in tiem, parentsystem and phasestate too

    //private List<PhaseSpace> computeStateDerivate(List<PhaseSpace> phaseSpaceStates) //not sure time needed // herein lays the problem
    //{
    //    List<PhaseSpace> stateDerivate = null;

    //    //if (this.currentPhaseSpace != null)
    //    {
    //        //the matlab code sets phaseSpace here before updateing forces.

    //        /*

    //        The evaluation is initialized by transposing the state vector into a row30 vector

    //        phase_space_state = phase_space_state (:) ’;

    //        and inserting it (back) into the particle system

    //        Particle_System . set_phase_space_state ( phase_space_state );

    //        */

    //        //	this.setPhaseSpace(this.currentPhaseSpace); //added in atempt to fix the above // but sends the partilce flying into the air

    //        this.setPhaseSpace(phaseSpaceStates);

    //        updateAllForces(); // should this really update forces? i nkow the matlab does. but the pixar didn't // maybe it a problem i don't have attractions yet

    //        stateDerivate = new List<PhaseSpace>();

    //        List<Vector3> _velocities = getParticlesVelocities();
    //        List<Vector3> _accelerations = getParticlesAccelerations();

    //        if ((_velocities == null || _accelerations == null) || (_velocities.Count != this.particles.Count || _accelerations.Count != this.particles.Count))
    //        {
    //            Debug.LogWarning("ERROR: velocities, accelerations and Particles lists are not same length or null!!");
    //        }
    //        else
    //        {
    //            for (int i = 0; i < this.particles.Count; i++)
    //            {
    //                if (this.particles[i] != null)
    //                {
    //                    stateDerivate.Add(new PhaseSpace());

    //                    stateDerivate[i].x = _velocities[i].x;
    //                    stateDerivate[i].y = _velocities[i].y;
    //                    stateDerivate[i].z = _velocities[i].z;

    //                    stateDerivate[i].x_v = _accelerations[i].x;
    //                    stateDerivate[i].y_v = _accelerations[i].y;
    //                    stateDerivate[i].z_v = _accelerations[i].z; // that are thise used for anyway? can see where they are used / now they are for drag
    //                }
    //            }
    //        }
    //    }

    //    return stateDerivate;
    //}

    /*
     *   function state_derivative = compute_state_derivative ...
     *          (time, phase_space_state, Particle_System)
     *      %COMPUTE_STATE_DERIVATIVE  Compute state derivative vector.
     *      %
     *      %   Example
     *      %
     *      %   SD = COMPUTE_STATE_DERIVATIVE (T, SS, PS) returns the 6*N-by-1
     *      %   phase space state derivative vector SD of the particle system PS at time T.
     *      %   SS is the current 6*N-by-1 phase space state vector.
     *      %   N is the number of particles.
     *      %
     *      %   See also ode4, set_phase_space_state, aggregate_forces,
     *      %   get_particles_velocities, get_particles_accelerations.
     *      %
     *      %   Copyright 2008-2008 buchholz.hs-bremen.de
     *
     *      phase_space_state = phase_space_state(:)';
     *
     *      Particle_System.set_phase_space_state (phase_space_state);
     *
     *      Particle_System.aggregate_forces;
     *
     *      velocities = Particle_System.get_particles_velocities;
     *
     *      accelerations = Particle_System.get_particles_accelerations;
     *
     *      state_derivative = [velocities, accelerations]';
     *
     *  end
     *
     */

    public float rungeKutta(PhaseSpace devState, PhaseSpace currentState, float startTime, float endTime, func func)
    {
        // atm asuming its worknig only doing ode4 in x.pos

        float stepTime = endTime - startTime;

        float x0 = currentState.x;

        float t0 = startTime;

        float k1_x = stepTime * func(x0, t0);

        float k2_x = stepTime * func(x0 + (k1_x / 2), t0 + (stepTime / 2));

        float k3_x = stepTime * func(x0 + (k2_x / 2), t0 + (stepTime / 2));

        float k4_x = stepTime * func(x0 + k3_x, t0 + stepTime);

        float rk_x = x0 + (1 / 6 * k1_x) + (1 / 3 * k2_x) + (1 / 3 * k3_x) + (1 / 6 * k4_x);

        return(rk_x);

        /* runge-kutta form pdf page 7
         *
         *
         *  h =  time step
         *
         *  k1 = h * f(x0, t0)
         *
         *  k2 = h * f(x0 + k1/2 , t0 + h/2)
         *
         *  k3 = h * f(x0 + k2/2 , t0 + h/2)
         *
         *  k4 = h * f(x0 + k3 , t0 + h)
         *
         *  x0(t0+h) = x0 + (1/6 * k1) + (1/3 * k2) +(1/3 * k3) +(1/6 * k4)
         *
         * The simplest numerical method is called Euler’s method. Let our initial value for x be denoted by
         * x0 = x(t0) and our estimate of x at a later time t0 + h by x(t0 + h) where h is a stepsize parameter.
         * Euler’s method simply computes x.t0 C h/ by taking a step in the derivative direction,
         * x(t0 + h) = x0 + h x'(t0):
         *
         * x' = f(x,t)
         *
         * x'' = f/m
         *
         * v' = f/m
         *
         * x' = v
         *
         * which for me means
         *
         */
    }
    private List <PhaseSpace> computeStateDerivate2(List <PhaseSpace> spaceState)
    {
        this.setPhaseSpace(spaceState);

        this.updateAllForces(); // aggregate forces

        var velocities    = this.getParticlesVelocities();
        var accelerations = this.getParticlesAccelerations();

        var stateDerivate = new List <PhaseSpace>(this.particles.Count);

        for (int i = 0; i < this.particles.Count; i++)
        {
            var state = new PhaseSpace(velocities[i], accelerations[i]);
            stateDerivate.Add(state);
        }

        return(stateDerivate);
    }