/**
 * 
 * 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.db;

/**
 * Objects of this class represent a residue type
 *
 */
public class ResidueType implements Cloneable {

	private int which = 0;
	
	// Constants: amino acids
	
	final static int Alanine = 1;
	final static int Arginine = 2;
	final static int Asparagine = 3;
	final static int AsparticAcid = 4;
	final static int Cysteine = 5;
	final static int GlutamicAcid = 6;
	final static int Glutamine = 7;
	final static int Glycine = 8;
	final static int Histidine = 9;
	final static int Isoleucine = 10;
	final static int Leucine = 11;
	final static int Lysine = 12;
	final static int Methionine = 13;
	final static int Phenylalanine = 14;
	final static int Proline = 15;
	final static int Serine = 16;
	final static int Threonine = 17;
	final static int Tryptophan = 18;
	final static int Tyrosine = 19;
	final static int Valine = 20;
	final static int Water = 21;
	final static int Other = 22;
	final static int Unknown = 23;
	
	// Constructors
	
	/**
	 * Constructs a new ResidueType object
	 *
	 * 
	 */
	public ResidueType() {
		// TODO Auto-generated constructor stub
	}
	
	/**
	 * Constructs a new ResidueType object of a given type
	 * @param type residue type
	 * 
	 */
	public ResidueType(int type){
		which = type;
	}
	
	/**
	 * Constructs a new ResidueType object of given code
	 * @param code residue code
	 * 
	 */
	public ResidueType(String code){
		code = code.toUpperCase();
		which = 22;
		if (code.equals("A")||code.startsWith("ALA")) which = 1;
		if (code.equals("R")||code.startsWith("ARG")) which = 2;
		if (code.equals("N")||code.startsWith("ASN")) which = 3;
		if (code.equals("D")||code.startsWith("ASP")) which = 4;
		if (code.equals("C")||code.startsWith("CYS")) which = 5;
		if (code.equals("E")||code.startsWith("GLU")) which = 6;
		if (code.equals("Q")||code.startsWith("GLN")) which = 7;
		if (code.equals("G")||code.startsWith("GLY")) which = 8;
		if (code.equals("H")||code.startsWith("HIS")) which = 9;
		if (code.equals("I")||code.startsWith("ILE")) which = 10;
		if (code.equals("L")||code.startsWith("LEU")) which = 11;
		if (code.equals("K")||code.startsWith("LYS")) which = 12;
		if (code.equals("M")||code.startsWith("MET")) which = 13;
		if (code.equals("F")||code.startsWith("PHE")) which = 14;
		if (code.equals("P")||code.startsWith("PRO")) which = 15;
		if (code.equals("S")||code.startsWith("SER")) which = 16;
		if (code.equals("T")||code.startsWith("THR")) which = 17;
		if (code.equals("W")||code.startsWith("TRP")) which = 18;
		if (code.equals("Y")||code.startsWith("TYR")) which = 19;
		if (code.equals("V")||code.startsWith("VAL")) which = 20;
		if (code.equals("Sol")||code.startsWith("SOL")||code.startsWith("HOH")) which = 21;
		if (code.equals("X")||code.startsWith("XXX")) which = 23;
	}
	
	// Getters

	/**
	 * Returns 1 letter code of residue type
	 * @return residue code
	 * 
	 */
	public String get1LetterCode(){
		if (which==1) return "A";
		if (which==2) return "R";
		if (which==3) return "N";
		if (which==4) return "D";
		if (which==5) return "C";
		if (which==6) return "E";
		if (which==7) return "Q";
		if (which==8) return "G";
		if (which==9) return "H";
		if (which==10) return "I";
		if (which==11) return "L";
		if (which==12) return "K";
		if (which==13) return "M";
		if (which==14) return "F";
		if (which==15) return "P";
		if (which==16) return "S";
		if (which==17) return "T";
		if (which==18) return "W";
		if (which==19) return "Y";
		if (which==20) return "V";
		if (which==21) return "~";
		if (which==22) return "?";
		if (which==23) return "X";
		return "";
	}
	
	/**
	 * Returns 3 letter code of residue type
	 * @return residue code
	 * 
	 */
	public String get3LetterCode(){
		if (which==1) return "Ala";
		if (which==2) return "Arg";
		if (which==3) return "Asn";
		if (which==4) return "Asp";
		if (which==5) return "Cys";
		if (which==6) return "Glu";
		if (which==7) return "Gln";
		if (which==8) return "Gly";
		if (which==9) return "His";
		if (which==10) return "Ile";
		if (which==11) return "Leu";
		if (which==12) return "Lys";
		if (which==13) return "Met";
		if (which==14) return "Phe";
		if (which==15) return "Pro";
		if (which==16) return "Ser";
		if (which==17) return "Thr";
		if (which==18) return "Trp";
		if (which==19) return "Tyr";
		if (which==20) return "Val";
		if (which==21) return "Sol";
		if (which==22) return "Oth";
		if (which==23) return "Xxx";
		return "";
	}
	
	/**
	 * Returns full name of residue type
	 * @return residue name
	 * 
	 */
	public String getFullName(){
		if (which==1) return "Alanine";
		if (which==2) return "Arginine";
		if (which==3) return "Asparagine";
		if (which==4) return "AsparticAcid";
		if (which==5) return "Cysteine";
		if (which==6) return "GlutamicAcid";
		if (which==7) return "Glutamine";
		if (which==8) return "Glycine";
		if (which==9) return "Histidine";
		if (which==10) return "Isoleucine";
		if (which==11) return "Leucine";
		if (which==12) return "Lysine";
		if (which==13) return "Methionine";
		if (which==14) return "Phenylalanine";
		if (which==15) return "Proline";
		if (which==16) return "Serine";
		if (which==17) return "Threonine";
		if (which==18) return "Tryptophan";
		if (which==19) return "Tyrosine";
		if (which==20) return "Valine";
		if (which==21) return "Water";
		if (which==22) return "Other";
		if (which==23) return "Unknown";
		return "";
	}
	
	// is?
	
	/**
	 * Returns true if it is an amino acid (not water or else)
	 * 
	 * 
	 */
	public boolean isAminoAcid(){
		if (which == 0) return false;
		if (which<21) return true;
		else return false;
	}
	
	/**
	 * Returns true if it is water (not amino acid or else)
	 * 
	 * 
	 */
	public boolean isWater(){
		if (which == 21) return true;
		else return false;
	}
	
	/**
	 * Returns true if it is not an amino acid nor water
	 * 
	 * 
	 */
	public boolean isOther(){
		if (which == 22) return true;
		else return false;
	}
	
	// toString, clone, equals
	
	/**
	 * Returns the String representation of residue type
	 *
	 * @return String representation
	 */
	public String toString(){
		return get3LetterCode();
	}
	
	/**
	 * Returns an identical ResidueType object 
	 *
	 * @return clone of the residue type
	 */
	public Object clone(){
		try {
			ResidueType ret = (ResidueType)super.clone();
			ret.which = which;
			return ret;
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * Returns true if the two residue types are identical
	 * @param other the other residue type
	 * 
	 */
	public boolean equals(Object other){
		if (other == null) return false;
		if (other == this) return true;
		if (this.getClass() != other.getClass()) return false;
		ResidueType type = (ResidueType)other;
		if (type.which==which) return true;
		else return false;
	}
	
	/**
	 * Returns hash code
	 * 
	 */
	public int hashCode() {
		return which;
	}

	
}
