/* BdfServer - Copyright (c) 2023 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 fr.exemole.bdfserver.xml.dyn;

import fr.exemole.bdfserver.api.BdfServer;
import net.fichotheque.namespaces.IconSpace;
import fr.exemole.bdfserver.tools.storage.StorageUtils;
import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import net.mapeadores.util.attr.Attribute;
import net.mapeadores.util.base64.Base64;
import net.mapeadores.util.io.DocStream;
import net.mapeadores.util.io.IOUtils;
import net.mapeadores.util.text.RelativePath;
import net.mapeadores.util.xml.ns.NameSpace;
import net.mapeadores.util.xml.svg.SvgWriter;


/**
 *
 * @author Vincent Calame
 */
public class Icon32SvgWriter extends SvgWriter {

    private final static String TEXT_ONLY_PATH = "M 0 10 h 32 V 32 H 0 Z";
    private final static String CARTOUCHE_ONLY_PATH = "M 0 0 h 32 v 10 A 21,21 0 0,0 10,32 H 0 Z";
    private final static String TEXT_AND_CARTOUCHE_PATH = "M 0 10 h 32 A 21,21 0 0,0 10,32 H 0 Z";
    private final BdfServer bdfServer;
    private final RelativePath cartouchePath;
    private final Attribute textIconAttribute;
    private final String iconClipPath;

    public Icon32SvgWriter(BdfServer bdfServer) {
        super(true);
        this.bdfServer = bdfServer;
        this.cartouchePath = getCartouchePath(bdfServer);
        this.textIconAttribute = getTextIconAttribute(bdfServer);
        this.iconClipPath = getClipPath(cartouchePath, textIconAttribute);
    }

    public void open() throws IOException {
        addNameSpace(NameSpace.XLINK_NAMESPACE);
        openSvg(32, 32);
        appendDefs();
    }

    public void appendBitmapIcon() throws IOException {
        DocStream bitmapIcon = bdfServer.getResourceDocStream(StorageUtils.ICON32);
        String base64;
        try (InputStream is = bitmapIcon.getInputStream()) {
            byte[] byteArray = IOUtils.toByteArray(is);
            base64 = Base64.encodeBase64String(byteArray);
        }
        startImageOpenTag("data:image/png;base64," + base64, 0, 0, 32, 32);
        if (iconClipPath != null) {
            addAttribute("style", "clip-path: url(#iconClip);");
        }
        closeEmptyTag();
    }

    public void appendBitmapCartouche() throws IOException {
        if (cartouchePath == null) {
            return;
        }
        DocStream cartoucheIcon = bdfServer.getResourceDocStream(cartouchePath);
        if (cartoucheIcon == null) {
            return;
        }
        String base64;
        try (InputStream is = cartoucheIcon.getInputStream()) {
            byte[] byteArray = IOUtils.toByteArray(is);
            base64 = Base64.encodeBase64String(byteArray);
        }
        startImageOpenTag("data:image/png;base64," + base64, 16, 16, 16, 16);
        closeEmptyTag();
    }

    public void appendIconText() throws IOException {
        if (textIconAttribute == null) {
            return;
        }
        String text = textIconAttribute.getFirstValue().replace('_', '\u00A0');
        String style = "font-weight:bold;font-size:10px;font-family:monospace;fill:#000000;";
        int size = textIconAttribute.size();
        if (size > 1) {
            StringBuilder buf = new StringBuilder(style);
            for (int i = 1; i < size; i++) {
                buf.append(textIconAttribute.get(i));
                buf.append(';');
            }
            style = buf.toString();
        }
        startTextOpenTag(1, 9);
        addStyleAttribute(style);
        endOpenTag();
        addText(text);
        closeText();
    }

    public void close() throws IOException {
        closeSvg();
    }

    private void appendDefs() throws IOException {
        if (iconClipPath != null) {
            openTag("defs");
            startOpenTag("clipPath");
            addAttribute("id", "iconClip");
            endOpenTag();
            startOpenTag("path");
            addAttribute("d", iconClipPath);
            closeEmptyTag();
            closeTag("clipPath");
            closeTag("defs");
        }
    }

    private void write() throws IOException {
        open();
        appendBitmapIcon();
        appendBitmapCartouche();
        appendIconText();
        close();
    }

    private static RelativePath getCartouchePath(BdfServer bdfServer) {
        Attribute cartoucheAttribute = bdfServer.getFichotheque().getFichothequeMetadata().getAttributes().getAttribute(IconSpace.CARTOUCHE_KEY);
        if (cartoucheAttribute != null) {
            try {
                return RelativePath.parse(cartoucheAttribute.getFirstValue());
            } catch (ParseException pe) {

            }
        }
        return null;
    }

    private static Attribute getTextIconAttribute(BdfServer bdfServer) {
        return bdfServer.getFichotheque().getFichothequeMetadata().getAttributes().getAttribute(IconSpace.TEXT_KEY);
    }

    private static String getClipPath(RelativePath cartouchePath, Attribute textAttribute) {
        if (cartouchePath == null) {
            if (textAttribute == null) {
                return null;
            } else {
                return TEXT_ONLY_PATH;
            }
        } else if (textAttribute == null) {
            return CARTOUCHE_ONLY_PATH;
        } else {
            return TEXT_AND_CARTOUCHE_PATH;
        }
    }

    public static String getSvgString(BdfServer bdfServer) {
        Icon32SvgWriter svgWriter = new Icon32SvgWriter(bdfServer);
        StringBuilder buf = new StringBuilder(1024);
        svgWriter.setAppendable(buf);
        svgWriter.setIndentLength(0);
        try {
            svgWriter.appendXMLDeclaration();
            svgWriter.write();
        } catch (IOException ioe) {
        }
        return buf.toString();
    }

}
