package simphy.script;

/**
 * Implementation of a pivot joint.
 * <p>
 * A pivot joint allows two bodies to rotate freely about a common point, but 
 * does not allow them to translate relative to one another.  The system as a
 * whole can translate and rotate freely.
 * <p>
 * By default the lower and upper limit angles are set to the current angle 
 * between the bodies.  When the lower and upper limits are equal, the bodies 
 * rotate together and are not allowed rotate relative to one another.  By
 * default the limits are disabled.
 * <p>
 * If the lower and upper limits are set explicitly, the values must follow 
 * these restrictions:
 * <ul>
 * <li>lower limit &le; upper limit</li>
 * <li>lower limit &gt; -180</li>
 * <li>upper limit &lt; 180</li>
 * </ul> 
 * To create a joint with limits outside of this range use the 
 * {@link #setReferenceAngle(double)} method.  This method sets the baseline 
 * angle for the joint, which represents 0 radians in the context of the 
 * limits.  For example:
 * <pre>
 * // we would like the joint limits to be [30, 260]
 * // this is the same as the limits [-60, 170] if the reference angle is 90
 * joint.setLimits(Math.toRadians(-60), Math.toRadians(170));
 * joint.setReferenceAngle(Math.toRadians(90));
 * </pre>
 * This joint also supports a motor.  The motor is an angular motor about the
 * anchor point.  The motor speed can be positive or negative to indicate a
 * clockwise or counter-clockwise rotation.  The maximum motor torque must be 
 * greater than zero for the motor to apply any motion.
 */
public class RevoluteJoint extends Joint {

	/**
	 * Returns the relative speed at which the {@link Body}s
	 * are rotating in radians/second.
	 * @return double
	 */
	public double getJointSpeed() {
		return 0;
	}
	
	/**
	 * Returns the relative angle between the two {@link Body}s in radians in the range [-&pi;, &pi;].
	 * @return double
	 */
	public double getJointAngle() {
		return 0;
	}
	
	/**
	 * Returns true if this motor is enabled.
	 * @return boolean
	 */
	public boolean isMotorEnabled() {
		return false;
	}
	
	/**
	 * Sets whether the motor for this joint is enabled or not.
	 * @param flag true if the motor should be enabled
	 */
	public void setMotorEnabled(boolean flag) {
	}
	
	/**
	 * Returns the maximum torque this motor will apply in newton-meters.
	 * @return double
	 */
	public double getMaximumMotorTorque() {
		return 0;
	}
	
	/**
	 * Sets the maximum torque this motor will apply in newton-meters.
	 * @param maximumMotorTorque the maximum motor torque in newton-meters; must be greater than or equal to zero
	 * @throws IllegalArgumentException if maxMotorTorque is less than zero
	 * @see #setMotorSpeed(double)
	 */
	public void setMaximumMotorTorque(double maximumMotorTorque) {
	}
	
	/**
	 * Returns the desired motor speed in radians/second.
	 * @return double
	 */
	public double getMotorSpeed() {
		return 0;
	}
	
	/**
	 * Sets the target motor speed in radians/second.
	 * @param motorSpeed the motor speed desired in radians/second
	 * @see #setMaximumMotorTorque(double)
	 */
	public void setMotorSpeed(double motorSpeed) {
		
	}
	
	/**
	 * Returns the motor torque in newton-meters.
	 * @return double
	 */
	public double getMotorTorque() {
		return 0;
	}
	
	/**
	 * Returns true if the rotational limit is enabled.
	 * @return boolean
	 */
	public boolean isLimitEnabled() {
		return false;
	}
	
	/**
	 * Enables or disables the rotational limit.
	 * @param flag true if the limit should be enabled
	 */
	public void setLimitEnabled(boolean flag) {
	}
	
	/**
	 * Returns the upper rotational limit in radians.
	 * @return double
	 */
	public double getUpperLimit() {
		return 0;
	}
	
	/**
	 * Sets the upper rotational limit.
	 * <p>
	 * Must be greater than or equal to the lower rotational limit.
	 * <p>
	 * See the class documentation for more details on the limit ranges.
	 * @param upperLimit the upper rotational limit in radians
	 * @throws IllegalArgumentException if upperLimit is less than the current lower limit
	 */
	public void setUpperLimit(double upperLimit) {
	}
	
	/**
	 * Returns the lower rotational limit in radians.
	 * @return double
	 */
	public double getLowerLimit() {
		return 0;
	}
	
	/**
	 * Sets the lower rotational limit.
	 * <p>
	 * Must be less than or equal to the upper rotational limit.
	 * <p>
	 * See the class documentation for more details on the limit ranges.
	 * @param lowerLimit the lower rotational limit in radians
	 * @throws IllegalArgumentException if lowerLimit is greater than the current upper limit
	 */
	public void setLowerLimit(double lowerLimit) {
	}
	
	/**
	 * Sets the upper and lower rotational limits.
	 * <p>
	 * The lower limit must be less than or equal to the upper limit.
	 * <p>
	 * See the class documentation for more details on the limit ranges.
	 * @param lowerLimit the lower limit in radians
	 * @param upperLimit the upper limit in radians
	 * @throws IllegalArgumentException if the lowerLimit is greater than upperLimit
	 */
	public void setLimits(double lowerLimit, double upperLimit) {
	}
	
	/**
	 * Returns the reference angle.
	 * <p>
	 * The reference angle is the angle calculated when the joint was created from the
	 * two joined bodies.  The reference angle is the angular difference between the
	 * bodies.
	 * @return double
	 */
	public double getReferenceAngle() {
		return 0;
	}
	
	/**
	 * Sets the reference angle.
	 * <p>
	 * This method can be used to set the reference angle to override the computed
	 * reference angle from the constructor.  This is useful in recreating the joint
	 * from a current state.
	 * @param angle the reference angle in radians
	 * @see #getReferenceAngle()
	 */
	public void setReferenceAngle(double angle) {
		
	}

	/**
	 * Returns the current state of the limit.
	 * @return {@link LimitState}
	 */
	public LimitState getLimitState() {
		return null;
	}
}
