/* Copyright 2002-2013 CS Systèmes d'Information
 * Licensed to CS Systèmes d'Information (CS) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * CS 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.orekit.forces.drag;

import java.util.ArrayList;
import java.util.Collection;

import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
import org.apache.commons.math3.ode.Parameterizable;
import org.orekit.errors.OrekitException;
import org.orekit.errors.OrekitMessages;
import org.orekit.forces.ForceModel;
import org.orekit.frames.Frame;
import org.orekit.propagation.SpacecraftState;
import org.orekit.propagation.events.EventDetector;
import org.orekit.propagation.numerical.TimeDerivativesEquations;
import org.orekit.time.AbsoluteDate;


/** Atmospheric drag force model.
 *
 * The drag acceleration is computed as follows :
 *
 * &gamma; = (1/2 * Ro * V<sup>2</sup> * S / Mass) * DragCoefVector
 *
 * With DragCoefVector = {Cx, Cy, Cz} and S given by the user through the interface
 * {@link DragSensitive}
 *
 * @author &Eacute;douard Delente
 * @author Fabien Maussion
 * @author V&eacute;ronique Pommier-Maurussane
 * @author Pascal Parraud
 */

public class DragForce implements ForceModel, Parameterizable {

    /** Parameter name for drag coefficient enabling jacobian processing. */
    public static final String DRAG_COEFFICIENT = "DRAG COEFFICIENT";

    /** List of the parameters names. */
    private static final ArrayList<String> PARAMETERS_NAMES;
    static {
        PARAMETERS_NAMES = new ArrayList<String>();
        PARAMETERS_NAMES.add(DRAG_COEFFICIENT);
    }

    /** Atmospheric model. */
    private final Atmosphere atmosphere;

    /** Spacecraft. */
    private final DragSensitive spacecraft;

    /** Simple constructor.
     * @param atmosphere atmospheric model
     * @param spacecraft the object physical and geometrical information
     */
    public DragForce(final Atmosphere atmosphere, final DragSensitive spacecraft) {
        this.atmosphere = atmosphere;
        this.spacecraft = spacecraft;
    }

    /** Compute the contribution of the drag to the perturbing acceleration.
     * @param s the current state information : date, kinematics, attitude
     * @param adder object where the contribution should be added
     * @exception OrekitException if some specific error occurs
     */
    public void addContribution(final SpacecraftState s,
                                final TimeDerivativesEquations adder)
        throws OrekitException {

        final AbsoluteDate date     = s.getDate();
        final Frame        frame    = s.getFrame();
        final Vector3D     position = s.getPVCoordinates().getPosition();

        final double rho    = atmosphere.getDensity(date, position, frame);
        final Vector3D vAtm = atmosphere.getVelocity(date, position, frame);
        final Vector3D relativeVelocity = vAtm.subtract(s.getPVCoordinates().getVelocity());

        // Addition of calculated acceleration to adder
        adder.addAcceleration(spacecraft.dragAcceleration(s, rho, relativeVelocity), frame);

    }

    /** There are no discrete events for this model.
     * @return an empty array
     */
    public EventDetector[] getEventsDetectors() {
        return new EventDetector[0];
    }

    /** {@inheritDoc} */
    public Collection<String> getParametersNames() {
        return PARAMETERS_NAMES;
    }

    /** {@inheritDoc} */
    public boolean isSupported(final String name) {
        return name.equals(DRAG_COEFFICIENT);
    }

    /** {@inheritDoc} */
    public double getParameter(final String name) throws IllegalArgumentException {
        if (name.matches(DRAG_COEFFICIENT)) {
            return spacecraft.getDragCoefficient();
        } else {
            throw OrekitException.createIllegalArgumentException(OrekitMessages.UNKNOWN_PARAMETER, name);
        }
    }

    /** {@inheritDoc} */
    public void setParameter(final String name, final double value) throws IllegalArgumentException {
        if (name.matches(DRAG_COEFFICIENT)) {
            spacecraft.setDragCoefficient(value);
        } else {
            throw OrekitException.createIllegalArgumentException(OrekitMessages.UNKNOWN_PARAMETER, name);
        }
    }

}

@@ -865,66 +865,8 @@
 g;%0A%0A
-import java.util.ArrayList;%0Aimport java.util.Collection;%0A%0A
 impo
@@ -965,16 +965,24 @@
 th3.ode.
+Abstract
 Paramete
@@ -1036,49 +1036,8 @@
 on;%0A
-import org.orekit.errors.OrekitMessages;%0A
 impo
@@ -1740,16 +1740,48 @@
 agForce 
+extends AbstractParameterizable 
 implemen
@@ -1797,25 +1797,8 @@
 odel
-, Parameterizable
  %7B%0A%0A
@@ -1949,230 +1949,8 @@
 %22;%0A%0A
-    /** List of the parameters names. */%0A    private static final ArrayList%3CString%3E PARAMETERS_NAMES;%0A    static %7B%0A        PARAMETERS_NAMES = new ArrayList%3CString%3E();%0A        PARAMETERS_NAMES.add(DRAG_COEFFICIENT);%0A    %7D%0A%0A
     
@@ -2317,24 +2317,57 @@
 acecraft) %7B%0A
+        super(DRAG_COEFFICIENT);%0A
         this
@@ -3659,281 +3659,8 @@
  %7D%0A%0A
-    /** %7B@inheritDoc%7D */%0A    public Collection%3CString%3E getParametersNames() %7B%0A        return PARAMETERS_NAMES;%0A    %7D%0A%0A    /** %7B@inheritDoc%7D */%0A    public boolean isSupported(final String name) %7B%0A        return name.equals(DRAG_COEFFICIENT);%0A    %7D%0A%0A    /** %7B@inheritDoc%7D */%0A
     
@@ -3751,55 +3751,46 @@
     
-if (name.matches(DRAG_COEFFICIENT)) %7B%0A 
+complainIfNotSupported(name);%0A
         
    r
@@ -3781,27 +3781,24 @@
 e);%0A        
-   
 return space
@@ -3829,141 +3829,8 @@
 ();%0A
-        %7D else %7B%0A            throw OrekitException.createIllegalArgumentException(OrekitMessages.UNKNOWN_PARAMETER, name);%0A        %7D%0A
     
@@ -3971,50 +3971,38 @@
     
-if (name.matches(DRAG_COEFFICIENT)) %7B%0A    
+complainIfNotSupported(name);%0A
     
@@ -4047,141 +4047,8 @@
 e);%0A
-        %7D else %7B%0A            throw OrekitException.createIllegalArgumentException(OrekitMessages.UNKNOWN_PARAMETER, name);%0A        %7D%0A
     

Use AbstractParameterizable instead of implementing the interface.