/* FichothequeLib_Tools - Copyright (c) 2013-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.tools.dom;

import java.text.ParseException;
import java.util.function.Consumer;
import net.fichotheque.ExistingNameException;
import net.fichotheque.album.AlbumConstants;
import net.fichotheque.album.metadata.AlbumDim;
import net.fichotheque.album.metadata.AlbumMetadataEditor;
import net.mapeadores.util.attr.AttributesBuilder;
import net.mapeadores.util.logging.MessageHandler;
import net.mapeadores.util.xml.DOMUtils;
import net.mapeadores.util.xml.DomMessages;
import org.w3c.dom.Element;


/**
 *
 * @author Vincent Calame
 */
public class AlbumMetadataDOMReader extends AbstractMetadataDOMReader {

    private final AlbumMetadataEditor albumMetadataEditor;

    public AlbumMetadataDOMReader(AlbumMetadataEditor albumMetadataEditor, MessageHandler messageHandler) {
        super(albumMetadataEditor, messageHandler, "album");
        this.albumMetadataEditor = albumMetadataEditor;
    }

    public void fillMetadata(Element element) {
        AttributesBuilder attributesBuilder = new AttributesBuilder();
        DOMUtils.readChildren(element, new RootConsumer(attributesBuilder, "/" + element.getTagName()));
        flush(attributesBuilder);
    }


    private class RootConsumer implements Consumer<Element> {

        private AttributesBuilder attributesBuilder;
        private final String parentXpath;

        private RootConsumer(AttributesBuilder attributesBuilder, String parentXpath) {
            this.attributesBuilder = attributesBuilder;
            this.parentXpath = parentXpath;
        }

        @Override
        public void accept(Element element) {
            if (readCommonElement(element, attributesBuilder, parentXpath)) {
                return;
            }
            String tagname = element.getTagName();
            String xpath = parentXpath + "/" + tagname;
            if (tagname.equals("album-dim")) {
                addAlbumDim(element, xpath);
            } else if (tagname.equals("dim-usage")) {
            } else {
                DomMessages.unknownTagWarning(messageHandler, xpath);
            }

        }

        private void addAlbumDim(Element element, String xpath) {
            String name = element.getAttribute("name");
            if (name.length() == 0) {
                DomMessages.emptyAttribute(messageHandler, xpath, "name");
                return;
            }
            xpath = xpath + " name=\"" + name + "\"";
            String type = element.getAttribute("type");
            if (type.isEmpty()) {
                DomMessages.emptyAttribute(messageHandler, xpath, "type");
                return;
            }
            try {
                type = AlbumConstants.checkDimType(type);
            } catch (IllegalArgumentException iae) {
                DomMessages.wrongAttributeValue(messageHandler, xpath, "type", type);
                return;
            }
            int width = 0;
            int height = 0;
            if (AlbumConstants.needWidth(type)) {
                width = getInt(element, xpath, "width");
                if (width == -1) {
                    return;
                }
            }
            if (AlbumConstants.needHeight(type)) {
                height = getInt(element, xpath, "height");
                if (height == -1) {
                    return;
                }
            }
            AlbumDim albumDim;
            try {
                albumDim = albumMetadataEditor.createAlbumDim(name, type);
            } catch (ExistingNameException | ParseException e) {
                return;
            }
            albumMetadataEditor.setDim(albumDim, width, height);

        }

        private int getInt(Element element, String xpath, String attributeName) {
            String intString = element.getAttribute(attributeName);
            int result;
            if (intString.length() == 0) {
                DomMessages.emptyAttribute(messageHandler, xpath, attributeName);
                return -1;
            }
            try {
                result = Integer.parseInt(intString);
            } catch (NumberFormatException nfe) {
                DomMessages.wrongIntegerAttributeValue(messageHandler, xpath, attributeName, intString);
                return -1;
            }
            if (result < 1) {
                DomMessages.wrongIntegerAttributeValue(messageHandler, xpath, attributeName, intString);
                return -1;
            }
            return result;
        }

    }

}
