/* cor_link.h */

#include <coriolis/kernel.h>

#ifndef COR_LINK__H
#define COR_LINK__H

/* - this file contains prototypes of various constraints.  most are taken
   directly from Prof. Baraff's documentation.  A few of the others, axial 
   constraints and attachments should work but don't. I don't know whether 
   they're written incorrectly or whether its because of coriolis.
   - all constraints need to be initially satisfied to have any chance of 
   working */

Barrier *create_rope_constraint( RigidBody &body, ctriple bp, ctriple wp, 
				 double );
Barrier *create_rope_constraint( RigidBody &bodA, RigidBody &bodB, ctriple bpa,
				 ctriple bpb, double );

void create_angular_constraint( RigidBody2d &b1, RigidBody2d &b2, double angle,
			        BodySystem &bs );

void create_attachment( RigidBody &b1, RigidBody &b2, EConstraint *&constr1,
			EConstraint *&constr2, EConstraint *&constr3 );

/* axes must be normalized */
void create_axial_link( RigidBody &b1, ctriple s_bp, ctriple s_axis, 
			RigidBody &b2, ctriple t_bp, ctriple t_axis,
			EConstraint *&, EConstraint *& );
void create_axial_link( RigidBody &body, ctriple bp, ctriple b_axis,
			ctriple wp, ctriple w_axis,
			EConstraint *&, EConstraint *& );

EConstraint *create_dist_constraint( RigidBody &, ctriple, RigidBody &, ctriple,
				     double dist );

EConstraint *create_dist_constraint( RigidBody&, ctriple, ctriple, double dist);


/* motor definition: defining a force function based on Influence class */
struct Motor : public Influence {
private:
  RigidBody *body1, *body2;  // the two bodies linked by this infuence
public:

  triple      bp1, bp2;  // body points on bodies 1 and 2 respectively
  double      torque;    // angular force of influence 
  double      magnitude, frequency, phase; // torque parameters
 
  Motor();
  ~Motor();

  // The next line instantiates the type function of EntityHook.  It may not
  // actually be necessary. Without it, Motor would simply inherit the type
  // function of Influence, which returns the constant INFLUENCE.
  
  // The binary scope resolution operator, ::, ties the member, actually an
  // enumerated type, Entitytype, to the class name, EntityHook.  The MOTOR type
  // name has been added to userhooks.h

  //  EntityHook::EntityType type(void) {return MOTOR;}

  EntityHook::EntityType Motor::type(void) {return MOTOR;}
 
  // header for init function that is called when an instance of 
  // Motor is created.
  void init( RigidBody &bod1, RigidBody &bod2, triple bop1, triple bop2,
		    double mag = 1, double f = 1, double phase = 0 );
		    
  //required member functions 
  void ignore( Body & );    // used to remove influence       
  void update( );           // required
};


struct Booster : public Influence {
  private:
  RigidBody *body;
  triple axis; /* unit length body space direction to thrust in offset by body's
		  com */

  public:
  double thrust;
  
  Booster( void );
  //  ~Booster( void );

  EntityHook::EntityType Booster::type(void) {return BOOSTER;}
 
  void init( RigidBody &Body, double thrust, ctriple axis = triple( 1, 0, 0 ) );
  /* normalizes and set axis */
  void set_axis( ctriple axis );
		    
  // required member functions 
  void ignore( Body & );    // used to remove influence       
  void update( void );           // required
};

#endif
