/*
 * @author Ranides Atterwim {@literal <ranides@gmail.com>}
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.xml;

import org.w3c.dom.Document;

/**
 * XMLDocument allows you to create detached XML nodes, associated with it.
 * Detached nodes can be inserted anywhere into parse tree.
 *
 * This class does not represent root node of XML document.
 * To obtain root element, please use {@link #root} or {@link #node}
 *
 * @author Ranides Atterwim {@literal <ranides@gmail.com>}
 */
public interface XMLDocument {

    /**
     * Interoperability method: returns "org.w3c.dom.Document"
     *
     * @return this
     */
    Document node();

    /**
     * Returns root element of this document
     *
     * @return XMLElement
     */
    XMLElement root();

    /**
     * Creates new attribute element.
     *
     * Attribute nodes can be inserted into collection returned by {@link XMLElement#attrs()}.
     * You can set attribute value by calling {@link XMLElement#text(String)} on returned element.
     *
     * @param name name
     * @return XMLElement
     */
    XMLElement attr(String name);

    /**
     * Creates new CDATA element with specified content.
     *
     * CDATA nodes can be inserted to any tag node using {@link XMLElement#append}
     *
     * @param value value
     * @return XMLElement
     */
    XMLElement cdata(String value);

    /**
     * Creates new comment section with specified content.
     *
     * CDATA nodes can be inserted to any tag node using {@link XMLElement#append}
     *
     * @param value value
     * @return XMLElement
     */
    XMLElement comment(String value);

    /**
     * Creates new empty document fragment.
     *
     * Fragments can be inserted to any tag node using {@link XMLElement#append}
     * Insertion of fragment causes direct insertion of its children, not container itself.
     *
     * @return XMLElement
     */
    XMLElement fragment();

    /**
     * Creates new document fragment with children defined by "xml" markup.
     *
     * Fragments can be inserted to any tag node using {@link XMLElement#append}
     * Insertion of fragment causes direct insertion of its children, not container itself.
     *
     * @param xml xml
     * @return XMLElement
     */
    XMLElement fragment(String xml);

    /**
     * Creates new tag with specified name.
     *
     * Tag nodes can be inserted to any tag node using {@link XMLElement#append}
     *
     * @param tag tag
     * @return XMLElement
     */
    XMLElement tag(String tag);

    /**
     * Creates new reference to entity with provided name.
     *
     * @param name name
     * @return XMLElement
     */
    XMLElement entity(String name);

    /**
     * Creates new processing instruction with specified content.
     *
     * Processing instructions can be prepended before root tag
     *
     * @param target target
     * @param value value
     * @return XMLElement
     */
    XMLElement processing(String target, String value);

    /**
     * Creates new text node. Escapes all special characters, for example &amp; &lt; &gt;
     *
     * Text nodes can be inserted to any tag node using {@link XMLElement#append}
     *
     * @param value value
     * @return XMLElement
     */
    XMLElement text(String value);
    
}
