import codedraw.CodeDraw;

/**
 * A body with a name and an associated force. The leaf node of
 * a hierarchical cosmic system. This class implements 'CosmicSystem'.
 */
public class NamedBodyForcePair implements CosmicSystem {

    private final NamedBody body;
    private final Vector3 force = new Vector3();

    /**
     * Initializes this with name, mass, current position and movement. The associated force
     * is initialized with a zero vector.
     */
    public NamedBodyForcePair(String name, double mass, Vector3 massCenter, Vector3 currentMovement) {
        this(new NamedBody(name, mass, massCenter, currentMovement));
    }

    public NamedBodyForcePair(String name, Body body) {
        this(new NamedBody(name, body));
    }

    public NamedBodyForcePair(NamedBody body) {
        this.body = body;
    }

    public NamedBodyForcePair(NamedBodyForcePair other) {
        this(new NamedBody(other.body));
    }

    public Body getBody() {
        return body;
    }

    /**
     * Returns the name of the body.
     */
    public String getName() {
        return body.getName();
    }

    @Override
    public String toString() {
        return this.getName();
    }

    @Override
    public Vector3 getMassCenter() {
        return body.massCenter();
    }

    @Override
    public double getMass() {
        return body.mass();
    }

    @Override
    public int numberOfBodies() {
        return 1;
    }

    @Override
    public double distanceTo(CosmicSystem cs) {
        return getMassCenter().distanceTo(cs.getMassCenter());
    }

    @Override
    public void addForceFrom(Body b) {
        force.add(body.gravitationalForce(b));
    }

    @Override
    public void addForceTo(CosmicSystem cs) {
        cs.addForceFrom(body);
    }

    @Override
    public BodyLinkedList getBodies() {
        BodyLinkedList list = new BodyLinkedList();
        list.addFirst(body);
        return list;
    }

    @Override
    public void update() {
        body.move(force);
        force.set(0);
    }

    @Override
    public void draw(CodeDraw cd) {
        body.draw(cd);
    }
}
