/* UtilLib - Copyright (c) 2023 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;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


/**
 *
 * @author Vincent Calame
 */
public class NearStringSplitter implements StringSplitter {

    private final static String SEPARATOR = ". ";
    private final int near;
    private final int threshold;
    private final int backwardlimit;

    public NearStringSplitter(int near, int threshold) {
        this.near = near;
        if (threshold < near) {
            this.threshold = near;
        } else {
            this.threshold = threshold;
        }
        this.backwardlimit = Math.max((this.near * 2) - this.threshold, 50);
    }

    @Override
    public List<String> split(String text) {
        if (text.length() < threshold) {
            return Collections.singletonList(text);
        }
        List<String> result = new ArrayList<String>();
        split(text, result);
        return result;
    }

    private void split(String part, List<String> result) {
        int separatorIdx = part.indexOf(SEPARATOR, near);
        if (separatorIdx == -1) {
            int backwardIdx = part.lastIndexOf(SEPARATOR, near);
            if (backwardIdx > backwardlimit) {
                result.add(part.substring(0, backwardIdx + SEPARATOR.length()));
                result.add(part.substring(backwardIdx + SEPARATOR.length()));
            } else {
                result.add(part);
            }
            return;
        }
        String newPart = null;
        if (separatorIdx > threshold) {
            int backwardIdx = part.lastIndexOf(SEPARATOR, near);
            if (backwardIdx > backwardlimit) {
                newPart = getNewPart(part, backwardIdx, result);
            }
        }
        if (newPart == null) {
            newPart = getNewPart(part, separatorIdx, result);
        }
        if (newPart.length() < threshold) {
            result.add(newPart);
        } else {
            split(newPart, result);
        }
    }

    private String getNewPart(String part, int separatorIndex, List<String> result) {
        result.add(part.substring(0, separatorIndex + SEPARATOR.length()));
        return part.substring(separatorIndex + SEPARATOR.length());
    }

}
