#ifndef HINGE_JOINT_HPP
#define HINGE_JOINT_HPP

#include "joint.hpp"
#include "types.hpp"
#include "constraint_body_body_point.hpp"
#include "constraint_body_body_max_distance.hpp"
#include <vector>

class Rigid_body;
class Physics;

/// implements a simple hinge between two rigid bodies. The bodies should be in 
/// a suitable configuration when this joint is created.
class Hinge_joint : public Joint
{
public:
  // default constructor so you can initialise this joint later.
  Hinge_joint();
  
  /// TODO at the moment the bodies should be unrotated when this is called...
  /// No angle limit if fwd > MAX_HINGE_ANGLE_LIMIT
  /// after calling initialise the joint will be functional
  /// sideways slack indicates how much the hinge should allow bending in the
  /// other directions (suggest a value of 0-1)
  enum {MAX_HINGE_ANGLE_LIMIT = 150};
  void initialise(Physics * physics,
                  Rigid_body * body0, Rigid_body * body1, 
                  const Vector3 & hinge_axis, 
                  const Vector3 & hinge_pos_abs,
                  const Matrix3 & invMtx0,
                  const Matrix3 & invMtx1,
                  Scalar hinge_half_width,
                  Scalar sideways_slack,
                  Scalar hinge_fwd_angle,
                  Scalar hinge_bck_angle,
                  Scalar damping);
  void deinit(Physics * physics);

  void update(Scalar dt);
  Rigid_body * m_body0;
  Rigid_body * m_body1;
private:
  Vector3 m_hinge_axis;
//  Vector3 m_hinge_pos_rel0;
  Scalar m_damping;

  Constraint_body_body_point m_point_constraint;
  Constraint_body_body_max_distance m_side_point_constraints[2];
  Constraint_body_body_max_distance m_max_distance_constraint;
  bool m_using_limit;
  Scalar m_hinge_fwd_angle;
};

#endif
