package clothSimulator;


import java.util.List;

import annas.graph.ArcInterface;

/** author Ben Sprott
 * 
 * @author ben
 *
 */

/** This is the main interface for constraints.  It will define what methods a constraint class should 
 * have.  
 * 
 */

public interface Constraint extends ArcInterface<Particle>{

	/** A constraint should know where in the constraint list it sits, ie its index
	 */
	public int getCLIndex();
	/** of course, you need to set that index first */
	public void setCLIndex(int cLIndex);
		
	enum ConstraintType { STRETCH, PINNED };
	
	/**
	 * This constraintType method will return a string naming the constraint type.  I am considering
	 * three constraint types for now namely stretch, shear and bend as outlined in Stam's paper.  A
	 * fourth type of constraint might be a pinning constraint (ie constrained in all directions) and
	 * we might have a pinning constraint
	 * @return
	 */
	public ConstraintType constraintType();
	
	/** The current_g is a method that will act as a function, returning a double value equal to
	 * the value of the constraint function for the given constraint at the current time step.
	 * 
	 * @return
	 */
	public void updateCurrent_g();
	
	/** The current_G method will act as a function and return the value of the gradient
	 *  of the constraint at the current time step.
	 * 
	 * @return
	 */
	public void updateCurrent_G();
	
	/** the current_Gdot() method returns the value of the first time derivative of the gradient
	 * of the constraint function.
	 * @return
	 */
	public void updateCurrent_Gdot();
	
	/** It seems to make sense that we want to update g,G, Gdot all at once, so lets add a method to update all
	 * 
	 */
	public void updateAll();
	
	/** Constraints also need to know how to handle delgdot dot v where delgdot is the first time derivative
	 * of constraint i and v is some arbitrary input vector who's length is equal to the number of dofs of the 
	 * system.
	 */
	public double GdotiDot(double[] in);
	
	/** Constraints also need to know how to handle delg dot v where delg is the gradient of a constraint
	 * and v is a vector size eqaul to the num d.o.f.s and the product is a dot product.  This
	 * kind of multipliation is part of matrix vector multiplication 
	 */
	public double GiDot(double[] in);
	
	/** Constraints need to be able to do Gtransposei dot v which is an inner product of a row of
	 * G transpose with a vector v passed in as adouble array. v should be of size number of constraints
	 * 
	 */
	public void GtransiDot(double[] in,double[] out);
	
	/**
	 * A constraint should be able to return a list of particles
	 */
	
	public List<Particle> ParticleList();
	
	/** A constraint will have to be able to offer up its g value since we need to consgtruct the g vector 
	 * during the calculation of b in Ax=b
	 * 
	 */
	public double get_g();
	/** A constraint will have to be able to offer up its G values
	 * I have kind of forgotten what length is, but I think it is just the number of dofs in the system..  It makes sense that a constraint would not know
	 * how many dofs there are in the whole system, so you have to pass it.
	 */
	public double[] get_G(int length);
	/** A constraint will have to be able to offer up its Gdot values
	 * 
	 */
	public double[] get_GDot(int length);
	
	/** here is a rather suspect method which returns a double value equal to the constraint "set point".  Now, I jut made that word up and what I mean for it to refer to is the lenght of a stretch constraint
	 * it is zero for a pin constraint and if we had angle constraints it might refer to the angle. 
	 * 
	 */
	public double setPoint();
}
