/**
 * 
 * Written by Márton Münz and Philip C Biggin
 * Copyright (c) University of Oxford, United Kingdom
 * Visit http://sbcb.bioch.ox.ac.uk/jgromacs/
 * 
 * This source code file is part of JGromacs v1.0.
 * 
 * JGromacs v1.0 is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * JGromacs v1.0. is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with JGromacs v1.0. If not, see <http://www.gnu.org/licenses/>.
 * 
 */

package jgromacs.data;

/**
 * Objects of this class represent an angle
 *
 */
public class Angle implements Cloneable{

	private double valueInDegrees;
	
	// Constructors
	
	/**
	 * Constructs a new Angle object
	 *
	 * 
	 */
	public Angle(){
		
	}
	
	/**
	 * Constructs a new Angle object of given value in degrees
	 * @param valueInDegrees value in degrees
	 * 
	 */
	public Angle(double valueInDegrees){
		this.valueInDegrees = valueInDegrees;
	}
	
	// Getters and setters
	
	/**
	 * Returns the value of angle in degrees
	 * @return value in degrees
	 * 
	 */
	public double getInDegrees(){
		return valueInDegrees;
	}
	
	/**
	 * Returns the value of angle in radians
	 * @return value in radians
	 * 
	 */
	public double getInRadians(){
		return valueInDegrees*Math.PI/180;
	}
	
	/**
	 * Sets the value of angle in degrees
	 * @param valueInDegrees value in degrees
	 * 
	 */
	public void setInDegrees(double valueInDegrees){
		this.valueInDegrees = valueInDegrees;
	}
	
	/**
	 * Sets the value of angle in radians
	 * @param valueInRadians value in radians
	 * 
	 */
	public void setInRadians(double valueInRadians){
		valueInDegrees = valueInRadians*180/Math.PI;
	}
	
	// equals, clone and toString
	
	/**
	 * Returns true if the two angles are identical
	 * @param other the other angle
	 * 
	 */
	public boolean equals(Object other){
		if (other == null) return false;
		if (other == this) return true;
		if (this.getClass() != other.getClass()) return false;
		Angle angle = (Angle)other;
		return (Math.abs(angle.valueInDegrees-valueInDegrees)<0.0000001);
	}
	
	/**
	 * Returns hash code
	 * 
	 */
	public int hashCode() {
		return (int)valueInDegrees;
	}
	
	
	/**
	 * Returns an identical Angle object 
	 *
	 * @return clone of the angle
	 */
	public Object clone(){
		try {
			Angle ret = (Angle)super.clone();
			ret.valueInDegrees = valueInDegrees;
			return ret;
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
			return null;
		}
		
	}
	
	/**
	 * Returns the String representation of angle
	 *
	 * @return String representation
	 */
	public String toString(){
		return String.valueOf(roundIt(getInDegrees(),2))+" degrees";
	}
	
	private double roundIt(double d, int digit){
		double N = Math.pow(10, digit);
		long L = (int)Math.round(d * N); 
		double ret = L / N;
		return  ret;
	}
}
