/* FichothequeLib_API - Copyright (c) 2006-2025 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;

import net.fichotheque.addenda.Addenda;
import net.fichotheque.addenda.AddendaEditor;
import net.fichotheque.album.Album;
import net.fichotheque.album.AlbumEditor;
import net.fichotheque.corpus.Corpus;
import net.fichotheque.corpus.CorpusEditor;
import net.fichotheque.junction.JunctionEditor;
import net.fichotheque.metadata.FichothequeMetadataEditor;
import net.fichotheque.sphere.Sphere;
import net.fichotheque.sphere.SphereEditor;
import net.fichotheque.thesaurus.Thesaurus;
import net.fichotheque.thesaurus.ThesaurusEditor;
import net.mapeadores.util.attr.Attribute;
import net.mapeadores.util.attr.AttributeBuilder;
import net.mapeadores.util.attr.AttributeChange;
import net.mapeadores.util.attr.AttributeKey;
import net.mapeadores.util.attr.Attributes;


/**
 *
 * @author Vincent Calame
 */
public interface FichothequeEditor {

    public Fichotheque getFichotheque();

    public EditOrigin getEditOrigin();

    public FichothequeMetadataEditor getFichothequeMetadataEditor();

    public AddendaEditor getAddendaEditor(SubsetKey addendaKey);

    public AlbumEditor getAlbumEditor(SubsetKey albumKey);

    public CorpusEditor getCorpusEditor(SubsetKey corpusKey);

    public SphereEditor getSphereEditor(SubsetKey sphereKey);

    public ThesaurusEditor getThesaurusEditor(SubsetKey thesaurusKey);

    public JunctionEditor getJunctionEditor();

    /**
     *
     * @throws IllegalArgumentException si corpusKey est nul ou d'un type
     * incorrect
     */
    public CorpusEditor createCorpus(SubsetKey corpusKey, Subset masterSubset) throws ExistingSubsetException;

    /**
     *
     * @throws IllegalArgumentException si sphereKey est nul ou d'un type
     * incorrect
     */
    public SphereEditor createSphere(SubsetKey sphereKey) throws ExistingSubsetException;

    /**
     * Crèe un nouveau thésaurus de type indiqué. Le type ne peut pas être
     * modifié après création du thésaurus.
     *
     * @throws IllegalArgumentException si thesaurusKey est nul ou d'un type
     * incorrect
     * @throws IllegalArgumentException si thesaurusType est incorrect
     */
    public ThesaurusEditor createThesaurus(SubsetKey thesaurusKey, String thesaurusType) throws ExistingSubsetException;

    /**
     *
     * @throws IllegalArgumentException si albumKey est nul ou d'un type
     * incorrect
     */
    public AlbumEditor createAlbum(SubsetKey albumKey) throws ExistingSubsetException;

    /**
     *
     * @throws IllegalArgumentException si addendaKey est nul ou d'un type
     * incorrect
     */
    public AddendaEditor createAddenda(SubsetKey addendaKey) throws ExistingSubsetException;

    /**
     * Supprime la sphère. Une sphère ne peut être supprimée que si elle ne
     * contient aucun rédacteur.
     *
     * @throws IllegalArgumentException si sphere n'appartient pas à la base de
     * fiches
     */
    public void removeSphere(Sphere sphere) throws NoRemoveableSubsetException;

    /**
     * Supprime le thésaurus. Un thésaurus ne peut être supprimé que s'il ne
     * contient aucun mot-clé.
     *
     * @throws IllegalArgumentException si le thésaurus n'appartient pas à la
     * base de fiches
     */
    public void removeThesaurus(Thesaurus thesaurus) throws NoRemoveableSubsetException;

    /**
     * Supprime le corpus. Un corpus ne peut être supprimé que s'il ne contient
     * aucune fiche.
     *
     * @throws IllegalArgumentException si le corpus n'appartient pas à la base
     * de fiches
     */
    public void removeCorpus(Corpus corpus) throws NoRemoveableSubsetException;

    /**
     * Supprime l'album. Un album ne peut être supprimé que s'il ne contient
     * aucune fiche.
     *
     * @throws IllegalArgumentException si l'album n'appartient pas à la base *
     * de fiches
     */
    public void removeAlbum(Album album) throws NoRemoveableSubsetException;

    /**
     * Supprime l'addenda. Un addenda ne peut être supprimé que s'il ne contient
     * aucune fiche.
     *
     * @throws IllegalArgumentException si l'addenda n'appartient pas à la base
     * de fiches
     */
    public void removeAddenda(Addenda addenda) throws NoRemoveableSubsetException;

    public boolean putAttribute(Object attributeHolder, Attribute attribute);

    public boolean removeAttribute(Object attributeHolder, AttributeKey attributeKey);

    public void saveChanges();

    public default boolean putAttribute(Object attributeHolder, AttributeKey attributeKey, String... values) {
        if ((values == null) || (values.length == 0)) {
            return removeAttribute(attributeHolder, attributeKey);
        }
        AttributeBuilder attributeBuilder = new AttributeBuilder(attributeKey);
        for (String value : values) {
            attributeBuilder.addValue(value);
        }
        Attribute attribute = attributeBuilder.toAttribute();
        if (attribute == null) {
            return removeAttribute(attributeHolder, attributeKey);
        } else {
            return putAttribute(attributeHolder, attribute);
        }
    }

    public default boolean putAttributes(Object attributeHolder, Attributes attributes) {
        boolean done = false;
        for (Attribute attribute : attributes) {
            boolean stepDone = putAttribute(attributeHolder, attribute);
            if (stepDone) {
                done = true;
            }
        }
        return done;
    }

    public default boolean changeAttributes(Object attributeHolder, AttributeChange attributeChange) {
        boolean done = false;
        for (Attribute attribute : attributeChange.getChangedAttributes()) {
            boolean stepdone = putAttribute(attributeHolder, attribute);
            if (stepdone) {
                done = true;
            }
        }
        for (AttributeKey removedAttributeKey : attributeChange.getRemovedAttributeKeyList()) {
            boolean stepdone = removeAttribute(attributeHolder, removedAttributeKey);
            if (stepdone) {
                done = true;
            }
        }
        return done;
    }

    public default AddendaEditor getAddendaEditor(Addenda addenda) {
        return getAddendaEditor(addenda.getSubsetKey());
    }

    public default AlbumEditor getAlbumEditor(Album album) {
        return getAlbumEditor(album.getSubsetKey());
    }

    public default CorpusEditor getCorpusEditor(Corpus corpus) {
        return getCorpusEditor(corpus.getSubsetKey());
    }

    public default SphereEditor getSphereEditor(Sphere sphere) {
        return getSphereEditor(sphere.getSubsetKey());
    }

    public default ThesaurusEditor getThesaurusEditor(Thesaurus thesaurus) {
        return getThesaurusEditor(thesaurus.getSubsetKey());
    }

}
