/**************************************************************************
 OmegaT - Computer Assisted Translation (CAT) tool 
          with fuzzy matching, translation memory, keyword search, 
          glossaries, and translation leveraging into updated projects.

 Copyright (C) 2020 Thomas Cordonnier
               Home page: http://www.omegat.org/
               Support center: http://groups.yahoo.com/group/OmegaT/

 This file is part of OmegaT.

 OmegaT 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.

 OmegaT 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 **************************************************************************/

package org.omegat.core.statistics;

import java.util.List;

import org.omegat.core.data.EntryKey;
import org.omegat.core.data.IProject;
import org.omegat.core.events.IStopped;
import org.omegat.core.matching.external.IExternalMemory;
import org.omegat.core.matching.FindMatches;
import org.omegat.core.matching.NearString;
import org.omegat.tokenizer.ITokenizer;
import org.omegat.util.TMXProp;

/**
 * Matcher which keeps only the score, not even the matches
 *
 * @author Thomas Cordonnier
 */
public class FindMatchesStatistics extends FindMatches {    
    private int resultScore = -1;

    public FindMatchesStatistics(ITokenizer sourceTokenizer, final IExternalMemory[] externalMemories, String memoryPath, boolean allowSeparateSegmentMatch, boolean searchExactlyTheSame) {
        super(sourceTokenizer, externalMemories, memoryPath, allowSeparateSegmentMatch, searchExactlyTheSame); 
        this.FUZZY_MATCH_THRESHOLD = 0;
    }
    
    /**
     * @param searchExactlyTheSame
     *            allows to search similarities with the same text as source segment. This mode used only for
     *            separate sentence match in paragraph project, i.e. where source is just part of current
     *            source.
     */
    public FindMatchesStatistics(ITokenizer sourceTokenizer, final IExternalMemory[] externalMemories, boolean allowSeparateSegmentMatch, boolean searchExactlyTheSame) {
        super(sourceTokenizer, externalMemories, allowSeparateSegmentMatch, searchExactlyTheSame);
        this.FUZZY_MATCH_THRESHOLD = 0;
    }
    
    public final int maxCount() { return 1; }    

    public int search(final IProject project, final String searchText,
            final boolean requiresTranslation, final IStopped stop)
            throws StoppedException {
        resultScore = -1;
        try { doSearch(project, searchText, requiresTranslation, false, stop); }
        catch (StoppedException st) {
            if (resultScore >= 95) return resultScore; else throw st;
        }
        
        return resultScore;
    }
        
    /**
     * Compare one entry with original entry.
     * 
     * @param candEntry
     *            entry to compare
     */
    protected void evalEntry(final EntryKey key, final String source, final String translation,
            String realSource, int totalPenalty, boolean fuzzy,
            NearString.MATCH_SOURCE comesFrom, final String tmxName,
            final String creator, final long creationDate, final String changer, final long changedDate,
            final String revisor, final String note, final List<TMXProp> props) {
        switch (this.sortKey) {
            case SCORE_STEM:
                resultScore = Math.max(resultScore, calcSimilarityStem(realSource) - totalPenalty);
                break;
            case SCORE_NO_STEM:
                resultScore = Math.max(resultScore, calcSimilarityNoStem(realSource) - totalPenalty);
                break;
            case ADJUSTED_SCORE:
                resultScore = Math.max(resultScore, calcSimilarityAdjusted(realSource) - totalPenalty);
                break;
            case IMPROVED_SCORE:
                resultScore = Math.max(resultScore, calcSimilarityImproved(realSource) - totalPenalty);
                break;
        }
        if (resultScore >= 95) // enough to say that we are in row 2
            throw new StoppedException();
    }
}
