/*
Copyright 2012-2014 Samuel Gesche

This file is part of the Greek Reuse Toolkit.

The Greek Reuse Toolkit 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.

The Greek Reuse Toolkit 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 the Greek Reuse Toolkit.  If not, see <http://www.gnu.org/licenses/>.
*/

package fr.cnrs.liris.drim.grt.modele;

import java.util.Objects;
import fr.cnrs.liris.drim.grt.modele.exceptions.CoordonneeIntrouvableException;

/**
 *
 * @author sgesche
 */
public class Coordonnee {
    public final static String FIN = "fin";
    
    private String expression;
    private OrdreStrict systeme;
    
    /**
     * @deprecated utiliser getSuivante() plutôt
     */
    public Coordonnee(OrdreStrict systeme, Coordonnee precedente) throws CoordonneeIntrouvableException {
        this.systeme = systeme;
        this.expression = systeme.getSuivant(precedente).getExpression();
    }
    
    public Coordonnee(OrdreStrict systeme, String expression) throws CoordonneeIntrouvableException {
        this.systeme = systeme;
        if(systeme.contient(expression)) {
            this.expression = expression;
        } else {
            throw new CoordonneeIntrouvableException(expression + " n'est pas dans le système " + systeme.toString());
        }
    }
    
    public Coordonnee(OrdreStrict systeme, int expression) throws CoordonneeIntrouvableException {
        this(systeme, ""+expression);
    }
    
    public OrdreStrict getSysteme() {
        return systeme;
    }
    
    public Coordonnee getSuivante() throws CoordonneeIntrouvableException {
        return new Coordonnee(systeme, this);
    }
    
    public Coordonnee getPrecedente() throws CoordonneeIntrouvableException {
        return new Coordonnee(systeme, systeme.getPrecedent(this).getExpression());
    }
    
    public String getExpression() {
        return expression;
    }
    
    public boolean isFinale() {
        return expression.equals(FIN);
    }
    
    public int getDistance(Coordonnee autreCoordonnee) {
        if(autreCoordonnee.systeme.equals(systeme)) {
            return systeme.getDistance(this, autreCoordonnee);
        } else {
            return Integer.MAX_VALUE;
        }
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 43 * hash + Objects.hashCode(this.expression);
        hash = 43 * hash + Objects.hashCode(this.systeme);
        return hash;
    }
    
    @Override
    public boolean equals(Object o) {
        if(!(o instanceof Coordonnee)) {
            return false;
        }
        Coordonnee o2 = (Coordonnee)o;
        return o2.expression.equals(expression) && o2.systeme.equals(systeme);
    }
    
    @Override
    public String toString() {
        return getSysteme() + ":" + getExpression();
    }
}
