/* Copyright (c) 2005 Stanford University and Christopher Bruns
 * 
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including 
 * without limitation the rights to use, copy, modify, merge, publish, 
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject
 * to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included 
 * in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

/*
 * Created on Jan 18, 2006
 * Original author: Christopher Bruns
 */
package org.simtk.isimsu;

public class IonSpecies 
implements ConstIonType, Comparable<IonSpecies>
{
    static class IonSurfaceModel {
        private IonSurfaceModel() {}
    }
    static IonSurfaceModel HARD_SPHERE_MODEL = new IonSurfaceModel();
    static IonSurfaceModel LENNARD_JONES_MODEL = new IonSurfaceModel();
    
    private String id;
    private float radius;
    private float charge;
    private float surfaceWellDepth;

    public int compareTo(IonSpecies otherIon) {
        final int BEFORE = -1;
        final int EQUAL = 0;
        final int AFTER = 1;

        if (this == otherIon) return EQUAL;

        // Alphabetical increasing order by name
        int comparison = this.getIonId().compareTo(otherIon.getIonId());
        if ( comparison != EQUAL ) return comparison;    
        
        // Secondary decreasing order by charge
        if (this.getCharge() > otherIon.getCharge()) return BEFORE;
        if (this.getCharge() < otherIon.getCharge()) return AFTER;
        
        // Tertiary increasing order by radius
        if (this.getRadius() < otherIon.getRadius()) return BEFORE;
        if (this.getRadius() > otherIon.getRadius()) return AFTER;
        
        assert this.equals(otherIon) : "compareTo inconsistent with equals.";

        return EQUAL;
    }
    
    /**
     * @return Returns the charge.
     */
    public float getCharge() {
        return charge;
    }
    /**
     * @param charge The charge to set.
     */
    public void setCharge(float charge) {
        this.charge = charge;
    }
    /**
     * @return Returns the id.
     */
    public String getIonId() {
        return id;
    }
    /**
     * @param id The id to set.
     */
    public void setIonId(String id) {
        this.id = id;
    }
    /**
     * @return Returns the radius.
     */
    public float getRadius() {
        return radius;
    }
    /**
     * @param radius The radius to set.
     */
    public void setRadius(float radius) {
        this.radius = radius;
    }
    /**
     * @return Returns the surfaceWellDepth.
     */
    public float getSurfaceWellDepth() {
        return surfaceWellDepth;
    }
    /**
     * @param surfaceWellDepth The surfaceWellDepth to set.
     */
    public void setSurfaceWellDepth(float surfaceWellDepth) {
        this.surfaceWellDepth = surfaceWellDepth;
    }
    
    // Let the ion be hashed based on id, charge, and radius
    public boolean equals(Object o) {
        boolean isEqual = true;

        if (o instanceof IonSpecies) {
            IonSpecies other = (IonSpecies) o;
            if (! (getIonId().equals(other.getIonId())) ) isEqual = false;
            if (! (getRadius() == (other.getRadius())) ) isEqual = false;
            if (! (getCharge() == (other.getCharge())) ) isEqual = false;
        }
        else isEqual = false;

        return isEqual;
    }
    
    public int hashCode() {
        int hashCode = 0;

        hashCode += getIonId().hashCode();
        hashCode += 2 * new Double(getRadius()).hashCode();
        hashCode += 3 * new Double(getCharge()).hashCode();
        
        return hashCode;
    }
    
}
