package script;


import java.awt.Color;

/**
 * Class to represent Position dependent Vector Field (Electric, magnetic or gravitational)
 * Field can be represented as a function of position x,y or polar coordinates r and th (theta)
 * @author Mahesh kurmi
 */
public abstract class Field {
	/**
	 * Creates variable Vector field which can be represented as a function of position x,y or polar coordinates r and th (theta)
	 * @param xExpr Mathematical expression for x component of field in terms of x, y, r and th
	 * @param yExpr Mathematical expression for x component of field in terms of x, y, r and th
	 * @param bounds  Region of influence of field, can be null if field exists everywhere
	 */
	public Field(String xExpr, String yExpr, Object bounds){
	}
	
	
	/**
	 * Resets expression of intensity and parser and sets intensity to constant value force
	 * @param force
	 *            the intensity to set
	 */
	public void setIntensity(Vector2 intensity) {
	}
	
	/**
	 * Sets expression for the field, the expression can be a function of position <b>x</b>, <b>y</b> or polar coordinates  <b>r</b> and  <b>th</b>(theta)
	 * @param xExpr expression for x component of field 
	 * @param yExpr expression for y component of field 
	 */
	public void setExpressions(String xExpr,String yExpr){
	}
	

	
	/**returns intensity of field at a point
	 * 
	 * @param v Position of the point in world space
	 * @return Intensity of field in SI unit at the point specified, returns null if field is not defined at the point
	 */
	public Vector2 getIntensityAtPoint(Vector2 v){
		return null;
	}
	
	/**
	 * Calculates the instantaneous force based on current variables values and return force Vector <br>
	 * returns null if field/force at this point is not defined
	 * @param body the body at which force is to be calculated
	 * @see getIntensityAtPoint
	 */
	public  Vector2 calculateForce(Body body){
		return null;
	}
	
	/**
	 * returns force on body applied by this field<br>
	 * returns null if filed is not active or body is static or body lies outside the bounds of the field
	 * @param body SandboxBody under influence of field
	 * @param timeStep deltaTime of world.step
	 * @return
	 */
	public Vector2 getForce(Body body, double timestep) {
		return null;
	}
	
	
	/**
	 * returns expression for x component of field
	 * @return
	 */
	public String getxExpr() {
		return "";
	}
	
	/**
	 * returns expression for y component of field
	 * @return
	 */
	public String getyExpr() {
		return "";
	}
	
	
	/**
	 * returns bounds of this field
	 * @return
	 */
	public Object getBounds() {
		return null;
	}
	
	/**
	 * returns name/identifier of the field
	 * @return
	 */
	public String getName(){
		return "";
	}

	/**
	 * Sets name of the field, ame is used as identifier for field in script
	 */
	public void setName(String name){
		
	}
	
	@Override
	public String toString(){
		return "";//getSymbol()+ " [ "+xExpr+Unicode.hat+"i + "+yExpr+Unicode.hat+"j ]";
	}
	
	/**
	 * Sets bound of the field
	 * @param bounds Region of influence of field, can be null if field exists everywhere
	 */
	public void setBounds(Object bounds) {
		//if(bounds==null)bounds=new NullBounds();
		//this.bounds = bounds;
	}
	

	/**
	 * Sets bounds of field as rectangular
	 * @param x top left x
	 * @param y top left y
	 * @param w width
	 * @param h height
	 */
	public void setRectangularBounds(double x,double y,double w,double h){
	}
	
	/**
	 * 
	 * @param cx x coordinate of center of circle
	 * @param cy x coordinate of center of circle 
	 * @param r  radius
	 */
	public void setCircularBounds(double cx, double cy, double r){
	}
	
	/**
	 * returns color used to render field
	 * @return
	 */
	public Color getColor() {
		return null;
	}

	/**
	 * sets color used to render field
	 */
	public void setColor(Color color) {
		
	}

	/**
	 * returns true if field is defined and active , therefore can apply force on bodies
	 * @return
	 */
	public boolean isEnabled() {
		return false;
	}

	/**
	 * if disabled neither field is rendered nor applies any force
	 * @param enabled
	 */
	public void setEnabled(boolean enabled) {
		
	}

	/**
	 * returns true if expression of field is defined
	 * @return
	 */
	public boolean isDefined() {
		return  false;
	}

	/**
	 * returnd default symbol used to prepresent field (Ex. Gravitational field is represented as G)
	 * @return
	 */
	public abstract String getSymbol();
	
	/**
	 * Returns SI unit in which Field is represented 
	 * @return
	 */
	public abstract String getUnit();
	
}
