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

import java.io.IOException;
import java.text.DecimalFormatSymbols;
import net.mapeadores.util.xml.ns.NameSpace;


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

    public XsltWriter() {
        super();
        setAposEscaped(false);
    }

    public void startXslStyleSheetOpenTag() throws IOException {
        startOpenTag("xsl:stylesheet");
        XMLUtils.appendNameSpaceAttribute(this, NameSpace.XSL_NAMESPACE);
        addAttribute("version", "1.0");
    }

    public void openXslStyleSheet() throws IOException {
        startXslStyleSheetOpenTag();
        endOpenTag();
    }

    public void closeXslStyleSheet() throws IOException {
        closeTag("xsl:stylesheet");
    }

    public void addDecimalFormat(DecimalFormatSymbols symbols, String name) throws IOException {
        startOpenTag("xsl:decimal-format");
        addAttribute("decimal-separator", symbols.getDecimalSeparator());
        char carac = symbols.getGroupingSeparator();
        if (carac == ' ') {
            carac = '\u00A0';
        }
        addAttribute("grouping-separator", carac);
        addAttribute("pattern-separator", symbols.getPatternSeparator());
        addNameAttribute(name);
        closeEmptyTag();
    }

    public void addLiteralVariable(String name, String value) throws IOException {
        startOpenTag("xsl:variable");
        addNameAttribute(name);
        if (value != null) {
            addSelectAttribute("'" + value + "'");
        }
        closeEmptyTag();
    }

    public void addXslVariable(String name, String select, boolean isString) throws IOException {
        startOpenTag("xsl:variable");
        addNameAttribute(name);
        if (isString) {
            if (select != null) {
                addSelectAttribute("'" + select + "'");
            }
        } else {
            addSelectAttribute(select);
        }
        closeEmptyTag();
    }

    public void addXslParam(String name) throws IOException {
        startOpenTag("xsl:param");
        addNameAttribute(name);
        closeEmptyTag();
    }

    public void addXslParam(String name, String select, boolean isString) throws IOException {
        startOpenTag("xsl:param");
        addNameAttribute(name);
        if (isString) {
            if (select != null) {
                addSelectAttribute("'" + select + "'");
            }
        } else {
            addSelectAttribute(select);
        }
        closeEmptyTag();
    }

    public void addXslImport(String href) throws IOException {
        startOpenTag("xsl:import");
        addAttribute("href", href);
        closeEmptyTag();
    }

    public void addXslInclude(String href) throws IOException {
        startOpenTag("xsl:include");
        addAttribute("href", href);
        closeEmptyTag();
    }

    public void addHtmlStrictXslOutput() throws IOException {
        startOpenTag("xsl:output");
        addAttribute("method", "html");
        addAttribute("encoding", "UTF-8");
        addAttribute("doctype-public", "-//W3C//DTD HTML 4.01//EN");
        addAttribute("doctype-system", "http://www.w3.org/TR/html4/strict.dtd");
        closeEmptyTag();
    }

    public void openMatchXslTemplate(String match, String mode) throws IOException {
        addSeparator();
        startOpenTag("xsl:template");
        addMatchAttribute(match);
        addModeAttribute(mode);
        endOpenTag();

    }

    public void openMatchXslTemplate(String match, String mode, String priority) throws IOException {
        addSeparator();
        startOpenTag("xsl:template");
        addMatchAttribute(match);
        addModeAttribute(mode);
        addPriorityAttribute(priority);
        endOpenTag();

    }

    public void openNameXslTemplate(String name) throws IOException {
        addSeparator();
        startOpenTag("xsl:template");
        addNameAttribute(name);
        endOpenTag();

    }

    public void openNameXslTemplate(String name, String mode) throws IOException {
        addSeparator();
        startOpenTag("xsl:template");
        addNameAttribute(name);
        addModeAttribute(mode);
        endOpenTag();
    }

    public void openNameXslTemplate(String name, String mode, String priority) throws IOException {
        addSeparator();
        startOpenTag("xsl:template");
        addNameAttribute(name);
        addModeAttribute(mode);
        addPriorityAttribute(priority);
        endOpenTag();

    }

    public void openXslForEach(String select) throws IOException {
        startOpenTag("xsl:for-each");
        addAttribute("select", select);
        endOpenTag();
    }

    public void openXslIf(String test) throws IOException {
        startOpenTag("xsl:if", false);
        addAttribute("test", test);
        endOpenTag();
    }

    public void openXslIf(String test, boolean withIndent) throws IOException {
        startOpenTag("xsl:if", withIndent);
        addAttribute("test", test);
        endOpenTag();
    }

    public void openXslWhen(String test) throws IOException {
        startOpenTag("xsl:when");
        addAttribute("test", test);
        endOpenTag();
    }

    public void openXslChoose() throws IOException {
        openTag("xsl:choose", false);
    }

    public void openXslOtherwise() throws IOException {
        startOpenTag("xsl:otherwise");
        endOpenTag();
    }

    public void closeXslTemplate() throws IOException {
        closeTag("xsl:template");
    }

    public void closeXslForEach() throws IOException {
        closeTag("xsl:for-each");
    }

    public void closeXslIf() throws IOException {
        closeTag("xsl:if", false);
    }

    public void closeXslIf(boolean withIndent) throws IOException {
        closeTag("xsl:if", withIndent);
    }

    public void closeXslOtherwise() throws IOException {
        closeTag("xsl:otherwise", false);
    }

    public void closeXslChoose() throws IOException {
        closeTag("xsl:choose");
    }

    public void closeXslWhen() throws IOException {
        closeTag("xsl:when", false);
    }

    public void openXslApplyTemplates(String select, String mode, boolean indent) throws IOException {
        startOpenTag("xsl:apply-templates", indent);
        addSelectAttribute(select);
        addModeAttribute(mode);
        endOpenTag();
    }

    public void closeXslApplyTemplates(boolean indent) throws IOException {
        closeTag("xsl:apply-templates", indent);
    }

    public void addXslApplyTemplates(String select) throws IOException {
        addXslApplyTemplates(select, null);
    }

    public void addXslApplyTemplates(String select, String mode) throws IOException {
        startOpenTag("xsl:apply-templates", false);
        addSelectAttribute(select);
        addModeAttribute(mode);
        closeEmptyTag();
    }

    public void addXslApplyTemplates(String select, String mode, boolean indentBefore) throws IOException {
        startOpenTag("xsl:apply-templates", indentBefore);
        addSelectAttribute(select);
        addModeAttribute(mode);
        closeEmptyTag();
    }

    public void addXslCallTemplate(String name, String mode) throws IOException {
        startOpenTag("xsl:call-template", false);
        addNameAttribute(name);
        addModeAttribute(mode);
        closeEmptyTag();
    }

    public void openXslCallTemplate(String name, boolean indent) throws IOException {
        startOpenTag("xsl:call-template", indent);
        addNameAttribute(name);
        endOpenTag();
    }

    public void closeXslCallTemplate(boolean indent) throws IOException {
        closeTag("xsl:call-template", indent);
    }

    public void addXslWithParam(String name, String select, boolean isString) throws IOException {
        startOpenTag("xsl:with-param");
        addNameAttribute(name);
        if (isString) {
            if (select != null) {
                addSelectAttribute("'" + select + "'");
            }
        } else {
            addSelectAttribute(select);
        }
        closeEmptyTag();
    }

    public void addXslValueOf(String select) throws IOException {
        startOpenTag("xsl:value-of", false);
        addSelectAttribute(select);
        closeEmptyTag();
    }

    public void addXslValueOf(String select, boolean disableOutputEscaping) throws IOException {
        startOpenTag("xsl:value-of", false);
        addSelectAttribute(select);
        addAttribute("disable-output-escaping", (disableOutputEscaping) ? "yes" : "no");
        closeEmptyTag();
    }

    public void addXslValueOf(String select, boolean disableOutputEscaping, boolean indentBefore) throws IOException {
        startOpenTag("xsl:value-of", indentBefore);
        addSelectAttribute(select);
        addAttribute("disable-output-escaping", (disableOutputEscaping) ? "yes" : "no");
        closeEmptyTag();
    }

    public void addXslText(String text) throws IOException {
        openTag("xsl:text", false);
        addText(text);
        closeTag("xsl:text", false);
    }

    public void addXslText(String text, boolean disableOutputEscaping) throws IOException {
        startOpenTag("xsl:text", false);
        addAttribute("disable-output-escaping", (disableOutputEscaping) ? "yes" : "no");
        endOpenTag();
        addText(text);
        closeTag("xsl:text", false);
    }

    public void addSpaceXslText() throws IOException {
        addNoEscapeXslText(" ");
    }

    public void addTabXslText() throws IOException {
        addNoEscapeXslText("&#x9;");
    }

    public void addNewlineXslText() throws IOException {
        addNoEscapeXslText("&#xA;");
    }

    private void addNoEscapeXslText(String text) throws IOException {
        openTag("xsl:text", false);
        append(text);
        closeTag("xsl:text", false);
    }

    public void addSeparator() throws IOException {
        append("\n");
    }

    public void addSelectAttribute(String select) throws IOException {
        addAttribute("select", select);
    }

    public void addNameAttribute(String name) throws IOException {
        addAttribute("name", name);
    }

    public void addModeAttribute(String mode) throws IOException {
        addAttribute("mode", mode);
    }

    public void addMatchAttribute(String match) throws IOException {
        addAttribute("match", match);
    }

    public void addPriorityAttribute(String priority) throws IOException {
        addAttribute("priority", priority);
    }

    private void addAttribute(String attributeName, char c) throws IOException {
        char[] array = new char[1];
        array[0] = c;
        addAttribute(attributeName, new String(array));
    }

}
