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

import java.io.File;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.net.URI;
import java.util.function.Predicate;
import javax.xml.transform.Result;
import javax.xml.transform.Transformer;
import net.ranides.assira.collection.query.CQueryBuilder;
import net.ranides.assira.generic.Wrapper;
import net.ranides.assira.xml.impl.CElements;
import net.ranides.assira.xml.impl.W3CQuery;
import net.ranides.assira.xml.impl.W3Element;
import org.w3c.dom.Node;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
@SuppressWarnings({
    "PMD.TooManyDifferentMethods",
    "PMD.TooManyPublicMethods",
    "PMD.MethodNameRules"
})
public interface XMLElement extends Wrapper<String> {
    
    XMLElements $true = $($("<true/>"));
    
    XMLElements $false = new CElements(CQueryBuilder.empty());

    static XMLElement $(Node doc) {
        return W3Element.wrap(doc);
    }
    
    static XMLElement $(String doc) {
        return W3CQuery.$(new StringReader(doc));
    }
    
    static XMLElement $(File doc) {
        return W3CQuery.$(doc);
    }
    
    static XMLElement $(URI doc) {
        return W3CQuery.$(doc);
    }
    
    static XMLElement $(Reader doc) {
        return W3CQuery.$(doc);
    }
    
    static XMLElement $(InputStream doc) {
        return W3CQuery.$(doc);
    }
    
    static XMLElements $(XMLElements... elements) {
        return W3CQuery.$(elements);
    }
    
    static XMLElements $(XMLElement... elements) {
        return W3CQuery.$(elements);
    }

    XMLDocument document();
    
    XMLElement root();
    
    XMLType nodetype();
    
    Node node();
    
    String name();
    
    String xpath();
    
    String content();
    
    String text();
    
    XMLElements attrs();
    
    XMLElement attr(String name);
    
    
    
    XMLElements find(String selector);
    
    XMLElements find(XMLSelector selector);
    
    XMLElements children();
    
    XMLElements children(String selector);
    
    XMLElements children(Predicate<XMLContext> selector);
    
    boolean has();
    
    boolean has(String selector);
    
    boolean has(Predicate<XMLContext> selector);
    
    XMLElement next();
    
    XMLElements next(String selector);
    
    XMLElements next(Predicate<XMLContext> selector);
    
    XMLElement prev();
    
    XMLElements prev(String selector);
    
    XMLElements prev(Predicate<XMLContext> selector);
    
    XMLElement parent();
    
    XMLElements parents();
    
    XMLElements parents(String selector);
    
    XMLElements parents(Predicate<XMLContext> selector);
    
    XMLElements siblings();
    
    XMLElements siblings(String selector);
    
    XMLElements siblings(Predicate<XMLContext> selector);
    
    

    XMLElement normalize();
    
    XMLElement clear();
    
    XMLElement before(XMLElement element);
    
    XMLElement after(XMLElement element);
    
    XMLElement prepend(XMLElement element);
    
    XMLElement append(XMLElement element);
    
    XMLElement replace(XMLElement element);
    
    XMLElement rename(String tagname);
    
    XMLElement remove();
    
    XMLElement wrap(String tagname);
    
    XMLElement unwrap();
    
    XMLElement content(XMLElement value);
    
    XMLElement content(String value);
    
    XMLElement text(String value);
    
    XMLElement apply(Transformer transformer) throws XMLException;
    
    XMLElement apply(XMLElement transformer) throws XMLException;
    
    <R extends Result> R apply(Transformer transformer, R output) throws XMLException;
    
    <R extends Result> R apply(XMLElement transformer, R output) throws XMLException;
    
    XMLWriter writer();

}
