/* UtilLib - Copyright (c) 2005-2019 Vincent Calame - Exemole
 * Logiciel libre donné sous triple licence :
 * 1) selon les termes de la CeCILL V2
 * 2) selon les termes de l’EUPL V.1.1
 * 3) selon les termes de la GNU GPLv3
 * Voir le fichier licences.txt
 */


package net.mapeadores.util.text.collation;

import net.mapeadores.util.text.SubstringPosition;


/**
 * Classe qui stocke la position d'un mot (Word) dans un texte. Le texte en
 * question peut être le titre d'une fiche, le libellé d'un mot-clé.
 *
 *
 * @author Vincent Calame
 */
public class CollationUnitPosition {

    private final SubstringPosition substringPosition;
    private final int[] correspondances;

    /**
     * Construit une nouvelle instance de CollationUnitPosition avec
     * unitSourceStartIndex comme point de départ du mot dans le texte,
     * wholeSourceLength la longueur totale du texte, collatedString la forme «
     * collationnée » du mot.
     */
    public CollationUnitPosition(CollationUnit collationUnit, int unitSourceStartIndex) {
        int unitSourceLength = collationUnit.getSourceString().length();
        substringPosition = new SubstringPosition(unitSourceStartIndex, unitSourceLength);
        int collatedLength = collationUnit.length();
        correspondances = new int[collatedLength];
        for (int i = 0; i < collatedLength; i++) {
            correspondances[i] = collationUnit.sourceIndexOf(i);
        }
    }

    public CollationUnitPosition(SubstringPosition substringPosition, int[] correspondances) {
        this.substringPosition = substringPosition;
        this.correspondances = correspondances;
    }

    /**
     * Retourne une instance de SubstringPosition indiquant la position du mot
     * dans le texte d'origine.
     */
    public SubstringPosition getPositionInWholeSource() {
        return substringPosition;
    }

    public int[] getCorrespondances() {
        return correspondances;
    }

    /**
     * Convertit la position du mot ou d'une partie du mot sous forme « collatée
     * » en position dans le texte d'origine.
     * <p>
     * La raison d'être de cette méthode tient au fait que des mots de longueur
     * différentes peuvent aboutir à la même forme « collatée ». Par exemple,
     * manœuvre et manoeuvre donnent la même forme alors que le premier mot a 8
     * caractères et le second 9. Si le moteur fait une recherche sur *oeuv*,
     * les deux mots répondent à ce critère l'un par ce qu'il contient œuv
     * l'autre parce qu'il contient oeuv. Pour pouvoir surligner l'emplacement
     * de la recherche (exemple man[œuv]re, man[oeuv]re), on doit avoir la
     * position exacte du début et de la fin de la chaîne de recherche.
     * <p>
     * C'est cette méthode qui permet d'obtenir les valeurs exactes des
     * positions à partir de la position de la forme collatée de oeuv dans le
     * texte collaté.
     *
     */
    public SubstringPosition convertToPositionInWholeSource(SubstringPosition partOfCollatedString) {
        int beginIndex = substringPosition.getBeginIndex() + correspondances[partOfCollatedString.getBeginIndex()];
        int length = correspondances[partOfCollatedString.getEndIndex()] - correspondances[partOfCollatedString.getBeginIndex()] + 1;
        return new SubstringPosition(beginIndex, length);
    }

    /**
     * Compare deux instances de CollationUnitPosition. Le résultat est égal à
     * getPositionInWholeSource().compareTo(collationUnitPosition.getPositionInWholeSource())
     */
    public int compareTo(CollationUnitPosition collationUnitPosition) {
        return this.substringPosition.compareTo(collationUnitPosition.substringPosition);
    }

}
