
import { Spring } from './Spring';
import { Body } from "./Body"

export class RotationalSpring extends Spring {

    /**
     * Rest angle of the spring.
     * @property restAngle
     * @type {number}
     */
    restAngle: number;

    /**
     * A rotational spring, connecting two bodies rotation. This spring explicitly adds angularForce (torque) to the bodies.
     *
     * The spring can be combined with a {{#crossLink "RevoluteConstraint"}}{{/crossLink}} to make, for example, a mouse trap.
     *
     * @class RotationalSpring
     * @extends Spring
     * @constructor
     * @param {Body} bodyA
     * @param {Body} bodyB
     * @param {Object} [options]
     * @param {number} [options.restAngle] The relative angle of bodies at which the spring is at rest. If not given, it's set to the current relative angle between the bodies.
     * @param {number} [options.stiffness=100] Spring constant (see Hookes Law). A number >= 0.
     * @param {number} [options.damping=1] A number >= 0.
     *
     * @example
     *     var spring = new RotationalSpring(bodyA, bodyB, {
     *         stiffness: 100,
     *         damping: 1
     *     });
     *     world.addSpring(spring);
     */
    constructor(bodyA: Body, bodyB: Body, options?: any) {
        options = options || {};

        super(bodyA, bodyB, options);


        this.restAngle = options.restAngle !== undefined ? options.restAngle : bodyB.angle - bodyA.angle;
    }
    /**
     * Apply the spring force to the connected bodies.
     * @method applyForce
     */
    applyForce() {
        var k = this.stiffness,
            d = this.damping,
            l = this.restAngle,
            bodyA = this.bodyA,
            bodyB = this.bodyB,
            x = bodyB.angle - bodyA.angle,
            u = bodyB.angularVelocity - bodyA.angularVelocity;

        var torque = - k * (x - l) - d * u;

        bodyA.angularForce -= torque;
        bodyB.angularForce += torque;
    };
}
