/* FichothequeLib_Impl - Copyright (c) 2008-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 net.fichotheque.EditOrigin;
import net.fichotheque.Fichotheque;
import net.fichotheque.FichothequeEditor;
import net.fichotheque.Metadata;
import net.fichotheque.metadata.FichothequeMetadata;
import net.fichotheque.metadata.FichothequeMetadataEditor;
import net.mapeadores.util.localisation.Lang;
import net.mapeadores.util.text.Label;
import net.mapeadores.util.text.StringUtils;


/**
 *
 * @author Vincent Calame
 */
class FichothequeMetadataImpl extends AbstractMetadata implements FichothequeMetadata {

    private final FichothequeImpl fichotheque;
    private String authority = "fichotheque.net";
    private String baseName = "fichotheque";

    private FichothequeMetadataImpl(FichothequeImpl fichotheque) {
        this.fichotheque = fichotheque;
    }

    public static FichothequeMetadataImpl.InitEditor init(FichothequeImpl fichotheque, FichothequeImpl.InitEditor fichothequeInitEditor) {
        FichothequeMetadataImpl metadata = new FichothequeMetadataImpl(fichotheque);
        return new InitEditor(metadata, fichothequeInitEditor);
    }

    @Override
    public String getAuthority() {
        return authority;
    }

    @Override
    public Fichotheque getFichotheque() {
        return fichotheque;
    }

    @Override
    public String getBaseName() {
        return baseName;
    }

    @Override
    protected void fireChange(FichothequeEditor fichothequeEditor) {
        FichothequeMetadataEditorImpl metadataEditor = (FichothequeMetadataEditorImpl) fichothequeEditor.getFichothequeMetadataEditor();
        metadataEditor.setMetadataChange();
    }

    FichothequeMetadataEditorImpl getFichothequeMetadataEditor(FichothequeEditor fichothequeEditor) {
        return new FichothequeMetadataEditorImpl(fichothequeEditor);
    }

    private boolean innerSetAuthority(String s) {
        if (!StringUtils.isAuthority(s)) {
            throw new IllegalArgumentException("not an authority : " + s);
        }
        boolean done = false;
        if (!s.equals(authority)) {
            authority = s;
            done = true;
        }
        return done;
    }

    private boolean innerSetBaseName(String s) {
        if (!StringUtils.isTechnicalName(s, true)) {
            throw new IllegalArgumentException("not a technical name : " + s);
        }
        boolean done = false;
        if (!s.equals(baseName)) {
            baseName = s;
            done = true;
        }
        return done;
    }


    public static class InitEditor implements FichothequeMetadataEditor {

        private final FichothequeMetadataImpl metadata;
        private final FichothequeImpl.InitEditor fichothequeInitEditor;

        private InitEditor(FichothequeMetadataImpl metadata, FichothequeImpl.InitEditor fichothequeInitEditor) {
            this.metadata = metadata;
            this.fichothequeInitEditor = fichothequeInitEditor;
        }

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

        @Override
        public FichothequeEditor getFichothequeEditor() {
            return fichothequeInitEditor;
        }

        @Override
        public boolean setAuthority(String s) {
            return metadata.innerSetAuthority(s);
        }

        @Override
        public boolean setBaseName(String s) {
            return metadata.innerSetBaseName(s);
        }

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

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

    }


    class FichothequeMetadataEditorImpl implements FichothequeMetadataEditor {

        private final FichothequeEditor fichothequeEditor;
        private boolean metadataChanged = false;

        private FichothequeMetadataEditorImpl(FichothequeEditor fichothequeEditor) {
            this.fichothequeEditor = fichothequeEditor;
        }

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

        @Override
        public FichothequeEditor getFichothequeEditor() {
            return fichothequeEditor;
        }

        @Override
        public boolean setAuthority(String s) {
            boolean done = innerSetAuthority(s);
            if (done) {
                setMetadataChange();
            }
            return done;
        }

        @Override
        public boolean setBaseName(String s) {
            boolean done = innerSetBaseName(s);
            if (done) {
                setMetadataChange();
            }
            return done;
        }

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

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

        void setMetadataChange() {
            metadataChanged = true;
        }

        void saveChanges() {
            EditOrigin editOrigin = fichothequeEditor.getEditOrigin();
            if (metadataChanged) {
                fichotheque.getFichothequeDataSource().saveFichothequeMetadata(FichothequeMetadataImpl.this, editOrigin);
                metadataChanged = false;
            }
        }

    }

}
