/* UtilLib - 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.mapeadores.util.xml.svg;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import net.mapeadores.util.xml.DefaultXMLWriter;
import net.mapeadores.util.xml.XMLUtils;
import net.mapeadores.util.xml.ns.NameSpace;


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

    private static final NameSpace DEFAULT_NAMESPACE = new NameSpace("", "http://www.w3.org/2000/svg");
    private final List<NameSpace> nameSpaceList = new ArrayList<NameSpace>();

    {
        nameSpaceList.add(NameSpace.SVG_NAMESPACE);
    }

    private final String prefix;

    public SvgWriter(boolean isDefaultNamespace) {
        if (isDefaultNamespace) {
            prefix = "";
            nameSpaceList.add(DEFAULT_NAMESPACE);
        } else {
            prefix = "svg:";
            nameSpaceList.add(NameSpace.SVG_NAMESPACE);
        }
    }

    public void addNameSpace(NameSpace nameSpace) {
        nameSpaceList.add(nameSpace);
    }

    public void openSvg(int width, int height) throws IOException {
        startOpenTag(prefix + "svg");
        for (NameSpace nameSpace : nameSpaceList) {
            XMLUtils.appendNameSpaceAttribute(this, nameSpace);
        }
        addWidthAttribute(width);
        addHeightAttribute(height);
        endOpenTag();
    }

    public void closeSvg() throws IOException {
        closeTag(prefix + "svg");
    }

    public void openGroup() throws IOException {
        openTag(prefix + "g");
    }

    public void closeGroup() throws IOException {
        closeTag(prefix + "g");
    }

    public void closeA() throws IOException {
        closeTag(prefix + "a");
    }

    public void closeText() throws IOException {
        closeTag(prefix + "text", false);
    }

    public void addXAttribute(int x) throws IOException {
        addAttribute("x", String.valueOf(x));
    }

    public void addYAttribute(int y) throws IOException {
        addAttribute("y", String.valueOf(y));
    }

    public void addWidthAttribute(int width) throws IOException {
        if (width >= 0) {
            addAttribute("width", String.valueOf(width));
        }
    }

    public void addHeightAttribute(int height) throws IOException {
        if (height >= 0) {
            addAttribute("height", String.valueOf(height));
        }
    }

    public void addStyleAttribute(String style) throws IOException {
        addAttribute("style", style);
    }

    public void addClassAttribute(String className) throws IOException {
        addAttribute("class", className);
    }

    public void addIdAttribute(String id) throws IOException {
        addAttribute("id", id);
    }

    public void addTransformAttribute(String transform) throws IOException {
        addAttribute("transform", transform);
    }

    public void startGroupOpenTag() throws IOException {
        startOpenTag(prefix + "g");
    }

    public void startAOpenTag(String href) throws IOException {
        startOpenTag(prefix + "a");
        addAttribute("xlink:href", href);
    }

    public void startLineOpenTag(int x1, int y1, int x2, int y2) throws IOException {
        startOpenTag(prefix + "line");
        addAttribute("x1", String.valueOf(x1));
        addAttribute("y1", String.valueOf(y1));
        addAttribute("x2", String.valueOf(x2));
        addAttribute("y2", String.valueOf(y2));
    }

    public void startArcPathOpenTag(int x1, int y1, int rx, int ry, int xrotate, boolean largeArcFlag, boolean sweepFlag, int x2, int y2) throws IOException {
        StringBuilder bufD = new StringBuilder();
        bufD.append("M ");
        bufD.append(x1);
        bufD.append(",");
        bufD.append(y1);
        bufD.append(" A ");
        bufD.append(rx);
        bufD.append(",");
        bufD.append(ry);
        bufD.append(" ");
        bufD.append(xrotate);
        bufD.append(" ");
        bufD.append((largeArcFlag) ? 1 : 0);
        bufD.append(",");
        bufD.append((sweepFlag) ? 1 : 0);
        bufD.append(" ");
        bufD.append(x2);
        bufD.append(",");
        bufD.append(y2);
        startOpenTag(prefix + "path");
        addAttribute("d", bufD.toString());
    }

    public void startRectOpenTag(int x, int y, int width, int height) throws IOException {
        startOpenTag(prefix + "rect");
        addXAttribute(x);
        addYAttribute(y);
        addWidthAttribute(width);
        addHeightAttribute(height);
    }

    public void startTextOpenTag(int x, int y) throws IOException {
        startOpenTag(prefix + "text");
        addXAttribute(x);
        addYAttribute(y);
    }

    public void startEllipseOpentag(int cx, int cy, int rx, int ry) throws IOException {
        startOpenTag(prefix + "ellipse");
        addAttribute("cx", String.valueOf(cx));
        addAttribute("cy", String.valueOf(cy));
        addAttribute("rx", String.valueOf(rx));
        addAttribute("ry", String.valueOf(ry));
    }

    public void startImageOpenTag(String href, int x, int y, int width, int height) throws IOException {
        startOpenTag(prefix + "image");
        addAttribute("xlink:href", href);
        addXAttribute(x);
        addYAttribute(y);
        addWidthAttribute(width);
        addHeightAttribute(height);
    }

    public String getRotate(int angle, int x, int y) {
        StringBuilder buf = new StringBuilder();
        buf.append("rotate(");
        buf.append(angle);
        buf.append(",");
        buf.append(x);
        buf.append(",");
        buf.append(y);
        buf.append(")");
        return buf.toString();
    }

    public String getTranslate(int x, int y) {
        StringBuilder buf = new StringBuilder();
        buf.append("translate(");
        buf.append(x);
        buf.append(",");
        buf.append(y);
        buf.append(")");
        return buf.toString();
    }

}
