/* FichothequeLib_Impl - Copyright (c) 2006-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.LinkedHashSet;
import java.util.Set;
import net.fichotheque.FichothequeEditor;
import net.fichotheque.Metadata;
import net.fichotheque.thesaurus.Thesaurus;
import net.fichotheque.thesaurus.ThesaurusEditor;
import net.fichotheque.thesaurus.metadata.ThesaurusMetadata;
import net.fichotheque.thesaurus.metadata.ThesaurusMetadataEditor;
import net.mapeadores.util.localisation.Lang;
import net.mapeadores.util.localisation.Langs;
import net.mapeadores.util.localisation.LangsUtils;
import net.mapeadores.util.text.Label;


/**
 *
 * @author Vincent Calame
 */
class ThesaurusMetadataImpl extends AbstractMetadata implements ThesaurusMetadata {

    private final static Lang DEFAULT_LANG = Lang.build("fr");
    private final ThesaurusImpl thesaurus;
    private Langs authorizedLangs;

    private ThesaurusMetadataImpl(ThesaurusImpl thesaurus) {
        this.thesaurus = thesaurus;
        if (thesaurus.getThesaurusType() != BABELIEN_TYPE) {
            authorizedLangs = LangsUtils.wrap(DEFAULT_LANG);
        }
    }

    static ThesaurusMetadataImpl.InitEditor fromInit(ThesaurusImpl.InitEditor thesaurusInitEditor) {
        ThesaurusMetadataImpl metadata = new ThesaurusMetadataImpl((ThesaurusImpl) thesaurusInitEditor.getThesaurus());
        return new InitEditor(metadata, thesaurusInitEditor);
    }

    static ThesaurusMetadataImpl fromNew(ThesaurusImpl thesaurus) {
        return new ThesaurusMetadataImpl(thesaurus);
    }

    @Override
    public Thesaurus getThesaurus() {
        return thesaurus;
    }

    @Override
    public short getThesaurusType() {
        return thesaurus.getThesaurusType();
    }

    @Override
    public Langs getAuthorizedLangs() {
        return authorizedLangs;
    }

    ThesaurusMetadataEditor getThesaurusMetadataEditor(ThesaurusImpl.ThesaurusEditorImpl thesaurusEditor) {
        return new ThesaurusMetadataEditorImpl(thesaurusEditor);
    }

    @Override
    protected void fireChange(FichothequeEditor fichothequeEditor) {
        ThesaurusImpl.ThesaurusEditorImpl thesaurusEditor = (ThesaurusImpl.ThesaurusEditorImpl) fichothequeEditor.getThesaurusEditor(thesaurus);
        thesaurusEditor.setMetadataChange();
    }

    private boolean innerSetAuthorizedLangs(Langs langs) {
        if (thesaurus.getThesaurusType() == BABELIEN_TYPE) {
            throw new UnsupportedOperationException("setAuthorizedLangIntegerList() cannot be invoked when getThesaurusType() == BABELIEN ");
        }
        if (langs == null) {
            throw new IllegalArgumentException("intList == null");
        }
        if (langs.isEmpty()) {
            throw new IllegalArgumentException("intList.size() == 0");
        }
        Set<Lang> set = new LinkedHashSet<Lang>(langs);
        Langs newLangs = LangsUtils.fromCollection(set);
        if (!LangsUtils.areEquals(newLangs, authorizedLangs)) {
            authorizedLangs = newLangs;
            return true;
        } else {
            return false;
        }
    }


    static class InitEditor implements ThesaurusMetadataEditor {

        private final ThesaurusMetadataImpl thesaurusMetadata;
        private final ThesaurusEditor thesaurusEditor;

        private InitEditor(ThesaurusMetadataImpl thesaurusMetadata, ThesaurusEditor thesaurusEditor) {
            this.thesaurusMetadata = thesaurusMetadata;
            this.thesaurusEditor = thesaurusEditor;
        }

        @Override
        public Metadata getMetadata() {
            return thesaurusMetadata;
        }

        @Override
        public ThesaurusEditor getThesaurusEditor() {
            return thesaurusEditor;
        }

        @Override
        public boolean setAuthorizedLangs(Langs langs) {
            return thesaurusMetadata.innerSetAuthorizedLangs(langs);
        }

        @Override
        public boolean putLabel(String name, Label label) {
            return thesaurusMetadata.innerPutLabel(name, label);
        }

        @Override
        public boolean removeLabel(String name, Lang lang) {
            return thesaurusMetadata.innerRemoveLabel(name, lang);
        }

    }


    private class ThesaurusMetadataEditorImpl implements ThesaurusMetadataEditor {

        private final ThesaurusImpl.ThesaurusEditorImpl thesaurusEditor;

        private ThesaurusMetadataEditorImpl(ThesaurusImpl.ThesaurusEditorImpl thesaurusEditor) {
            this.thesaurusEditor = thesaurusEditor;
        }

        @Override
        public Metadata getMetadata() {
            return ThesaurusMetadataImpl.this;
        }

        @Override
        public ThesaurusEditor getThesaurusEditor() {
            return thesaurusEditor;
        }

        @Override
        public boolean setAuthorizedLangs(Langs langs) {
            boolean done = innerSetAuthorizedLangs(langs);
            if (done) {
                fireChange();
            }
            return done;
        }

        @Override
        public boolean putLabel(String name, Label label) {
            boolean done = innerPutLabel(name, label);
            if (done) {
                fireChange();
            }
            return done;
        }

        @Override
        public boolean removeLabel(String name, Lang lang) {
            boolean done = innerRemoveLabel(name, lang);
            if (done) {
                fireChange();
            }
            return done;
        }

        private void fireChange() {
            thesaurusEditor.setMetadataChange();
        }

    }

}
