/**
 * 
 * @constructor
 * @param {type} options
 */
XmlWriter = function (options) {
    this.xml = "";
    this.indentLength = -999999;
    if (options) {
        if (options.indentLength) {
            this.indentLength = options.indentLength;
        } else if (options.prettyXml) {
            this.indentLength = 0;
        } 
    }
};

XmlWriter.prototype.appendXMLDeclaration = function () {
    this.write('<?xml version="1.0" encoding="UTF-8"?>');
    if (this.indentLength < 0) {
        this.write('\n');
    }
    return this;
};

XmlWriter.prototype.startOpenTag = function (tagName, indentBefore) {
    if (indentBefore === undefined) {
        indentBefore = true;
    }
    if (indentBefore) {
        this.appendIndent();
    }
    this.write('<');
    this.write(tagName);
    return this;
};

XmlWriter.prototype.endOpenTag = function () {
    this.write('>');
    this.increaseIndentValue();
    return this;
};

XmlWriter.prototype.closeEmptyTag = function () {
    this.write('/');
    this.write('>');
    return this;
};

XmlWriter.prototype.openTag = function (tagName, indentBefore) {
    if (indentBefore === undefined) {
        indentBefore = true;
    }
    if (indentBefore) {
        this.appendIndent();
    }
    this.write('<');
    this.write(tagName);
    this.write('>');
    this.increaseIndentValue();
    return this;
};

XmlWriter.prototype.closeTag = function (tagName, indentBefore) {
    if (indentBefore === undefined) {
        indentBefore = true;
    }
    this.decreaseIndentValue();
    if (indentBefore) {
        this.appendIndent();
    }
    this.write('<');
    this.write('/');
    this.write(tagName);
    this.write('>');
    return this;
};

XmlWriter.prototype.addText = function (text) {
    if (text) {
        this.escape(text);
    }
    return this;
};

XmlWriter.prototype.addCData = function (text) {
    this.write("<![CDATA[");
    var length = text.length;
    var carac;
    for (let i = 0; i < length; i++) {
        carac = text.charAt(i);
        if (carac === ']') {
            if ((i < (length - 1)) && (text.charAt(i + 1) === ']')) {
                this.write("]]>");
                this.write("]]");
                this.write("<![CDATA[");
                i = i + 1;
            } else {
                this.write(']');
            }
        } else {
            this.write(carac);
        }
    }
    this.write("]]>");
    return this;
};

XmlWriter.prototype.addAttribute = function (attributeName, value) {
    if ((value === 0) || (value)) {
        this.write(' ');
        this.write(attributeName);
        this.write('=');
        this.write('\"');
        this.escape(value.toString());
        this.write('\"');
    }
    return this;
};

XmlWriter.prototype.addSimpleElement = function (tagName, value) {
    if (value) {
        this.startOpenTag(tagName);
        this.endOpenTag();
        this.addText(value);
        this.closeTag(tagName, false);
    }
    return this;
};

XmlWriter.prototype.addEmptyElement = function (tagName) {
    this.startOpenTag(tagName);
    this.closeEmptyTag();
    return this;
};

XmlWriter.prototype.write = function (text) {
    this.xml += text;
    return this;
};

XmlWriter.prototype.escape = function (text) {
    var carac;
    for(let i = 0, len = text.length; i < len; i++) {
        carac = text.charAt(i);
        switch (carac) {
            case '&':
                this.write("&amp;");
                break;
            case '"':
                this.write("&quot;");
                break;
            case '<':
                this.write("&lt;");
                break;
            case '>':
                this.write("&gt;");
                break;
            case '\'':
                this.write("&apos;");
                break;
            case '\u00A0':
                this.write("&#x00A0;");
                break;
            default:
                this.write(carac);
        }
    }
    return this;
};

XmlWriter.prototype.appendIndent = function () {
    if (this.indentLength > -1) {
        this.write('\n');
        for(let i = 0, len = this.indentLength; i < len; i++) {
            this.write('\t');
        }
    }
    return this;
};
               
XmlWriter.prototype.increaseIndentValue = function () {
    this.indentLength = this.indentLength + 1;
    return this;
};

XmlWriter.prototype.decreaseIndentValue = function () {
    this.indentLength = this.indentLength - 1;
    return this;
};

