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

import java.util.function.IntFunction;
import java.util.function.Predicate;

import net.ranides.assira.generic.EnumUtils;
import org.w3c.dom.Node;

/**
 *
 * @author ranides
 */
public enum XMLType implements Predicate<XMLContext> {
    
    /** The node is an {@code Element}. */
    ELEMENT(1),
    
    /** The node is an {@code Attr}. */
    ATTRIBUTE(2),
    
    /** The node is a {@code Text} node. */
    TEXT(3),
    
    /** The node is a {@code CDATASection}. */
    CDATA(4),
    
    /** The node is an {@code EntityReference}. */
    REFERENCE(5),
    
    /** The node is an {@code Entity}. */
    ENTITY(6),
    
    /** The node is a {@code ProcessingInstruction}.*/
    PROCESSING(7),
    
    /** The node is a {@code Comment}.*/
    COMMENT(8),
    
    /** The node is a {@code Document}.*/
    DOCUMENT(9),
    
    /** The node is a {@code DocumentType}.*/
    DOCTYPE(10),
    
    /** The node is a {@code DocumentFragment}.*/
    FRAGMENT(11),
    
    /** The node is a {@code Notation}.*/
    NOTATION(12),
    
    ;
    
    private static final IntFunction<XMLType> MAP = EnumUtils.lookupInt(XMLType.class, n -> n.value);
    
    private final int value;

    XMLType(int value) {
        this.value = value;
    }

    /**
     * Interoperability method: returns XMLType for provided "org.w3c.dom.Node"
     *
     * @param node node
     * @return XMLType
     */
    public static XMLType valueOf(Node node) {
        return valueOf(node.getNodeType());
    }

    /**
     * Interoperability method: returns XMLType for provided NodeType (defined in "org.w3c.dom.Node")
     *
     * Returns null for invalid values.
     *
     * @param value value
     * @return XMLType?
     */
    public static XMLType valueOf(int value) {
        return MAP.apply(value);
    }

    @Override
    public boolean test(XMLContext c) {
        return this.equals(c.node().nodetype());
    }
    
}
