/*
* Copyright (c) 2025 Chris Giles
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies.
* Chris Giles makes no representations about the suitability
* of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/

#pragma once

#include <basilisk/physics/forces/force.h>

namespace bsk::internal {

// Standard spring force
class Spring : public Force
{
private:
    glm::vec2 rA, rB;
    float rest;

public:
    Spring(Solver* solver, Rigid* bodyA, Rigid* bodyB, glm::vec2 rA, glm::vec2 rB, float stiffness, float rest = -1);

    int rows() const override { return 1; }

    bool initialize() override { return true; }
    void computeConstraint(float alpha) override;
    void computeDerivatives(Rigid* body) override;
    
    // Getters
    glm::vec2 getRA() const { return rA; }
    glm::vec2 getRB() const { return rB; }
    float getRest() const { return rest; }
    
    // Setters
    void setRA(const glm::vec2& value) { rA = value; }
    void setRB(const glm::vec2& value) { rB = value; }
    void setRest(float value) { rest = value; }
    
    // Mutable references
    glm::vec2& getRARef() { return rA; }
    glm::vec2& getRBRef() { return rB; }
    float& getRestRef() { return rest; }
};

}

