/* FichothequeLib_Impl - Copyright (c) 2012-2022 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.fichotheque.impl;

import java.util.ArrayList;
import java.util.List;
import net.fichotheque.thesaurus.Motcle;
import net.fichotheque.utils.ThesaurusUtils;


/**
 *
 * @author Vincent Calame
 */
class Motcles {

    private final List<AbstractMotcle> list = new ArrayList<AbstractMotcle>();
    private List<Motcle> cacheList = null;

    Motcles() {
    }


    int size() {
        return list.size();
    }

    List<Motcle> getCache() {
        List<Motcle> result = cacheList;
        if (result == null) {
            result = initCache();
        }
        return result;
    }

    synchronized void remove(int index) {
        list.remove(index);
        int size = list.size();
        for (int i = index; i < size; i++) {
            AbstractMotcle motcle = list.get(i);
            motcle.decreaseIndex();
        }
        clearCache();
    }

    synchronized void add(AbstractMotcle motcle) {
        int size = list.size();
        list.add(motcle);
        motcle.setChildIndex(size);
        clearCache();
    }

    synchronized void permute(int oldIndex, int newIndex) {
        if ((newIndex < 0) || (newIndex >= list.size())) {
            throw new IndexOutOfBoundsException();
        }
        AbstractMotcle movedMotcle = list.set(newIndex, list.get(oldIndex));
        if (oldIndex > newIndex) {
            for (int i = newIndex + 1; i <= oldIndex; i++) {
                movedMotcle.setChildIndex(i);
                movedMotcle = list.set(i, movedMotcle);
            }
        } else {
            for (int i = newIndex - 1; i >= oldIndex; i--) {
                movedMotcle.setChildIndex(i);
                movedMotcle = list.set(i, movedMotcle);
            }
        }
        clearCache();
    }

    private synchronized List<Motcle> initCache() {
        if (cacheList != null) {
            return cacheList;
        }
        List<Motcle> newCacheList = ThesaurusUtils.wrap(list.toArray(new Motcle[list.size()]));
        cacheList = newCacheList;
        return newCacheList;
    }

    private void clearCache() {
        cacheList = null;
    }

}
