/*
 * Copyright 2004,2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.axiom.om.impl.dom;

import org.apache.axiom.om.OMContainer;
import org.apache.axiom.om.OMException;
import org.apache.axiom.om.OMFactory;
import org.apache.axiom.om.OMNode;
import org.apache.axiom.om.OMOutputFormat;
import org.apache.axiom.om.OMXMLParserWrapper;
import org.apache.axiom.om.util.StAXUtils;
import org.apache.axiom.om.impl.OMNodeEx;
import org.apache.axiom.om.impl.MTOMXMLStreamWriter;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.UserDataHandler;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.io.OutputStream;
import java.io.Writer;
import java.util.Hashtable;
import java.util.Map;

public abstract class NodeImpl implements Node, NodeList, OMNodeEx, Cloneable {

    /**
     * Holds the user data objects
     */
    private Map userData = new Hashtable();

    /**
     * Field builder
     */
    protected OMXMLParserWrapper builder;

    /**
     * Field done
     */
    protected boolean done = false;

    /**
     * Field nodeType
     */
    protected int nodeType;

    protected DocumentImpl ownerNode;
    
    /**
     * Factory that created this node
     */
    protected OMFactory factory;

    // data

    protected short flags;

    protected final static short OWNED = 0x1 << 1;

    protected final static short FIRSTCHILD = 0x1 << 2;

    protected final static short READONLY = 0x1 << 3;

    protected final static short SPECIFIED = 0x1 << 4;

    protected final static short NORMALIZED = 0x1 << 5;

    //
    // Constructors
    //

    protected NodeImpl(DocumentImpl ownerDocument, OMFactory factory) {
        this(factory);
        this.ownerNode = ownerDocument;
        // this.isOwned(true);

    }

    protected NodeImpl(OMFactory factory) {
        this.factory = factory;
    }

    public void normalize() {
        //Parent node should override this 
    }

    public boolean hasAttributes() {
        return false; // overridden in ElementImpl
    }

    public boolean hasChildNodes() {
        return false; // Override in ParentNode
    }

    public String getLocalName() {
        return null; // Override in AttrImpl and ElementImpl
    }

    public String getNamespaceURI() {
        return null; // Override in AttrImpl and ElementImpl
    }

    public String getNodeValue() throws DOMException {
        return null;
    }

    /*
     * Overidden in ElementImpl and AttrImpl.
     */
    public String getPrefix() {
        return null;
    }

    public void setNodeValue(String arg0) throws DOMException {
        // Don't do anything, to be overridden in SOME Child classes
    }

    public void setPrefix(String prefix) throws DOMException {
        throw new DOMException(DOMException.NAMESPACE_ERR, DOMMessageFormatter
                .formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NAMESPACE_ERR",
                               null));
    }

    /**
     * Finds the document that this Node belongs to (the document in whose
     * context the Node was created). The Node may or may not
     */
    public Document getOwnerDocument() {
        return (Document) this.ownerNode;
    }

    /**
     * Returns the collection of attributes associated with this node, or null
     * if none. At this writing, Element is the only type of node which will
     * ever have attributes.
     * 
     * @see ElementImpl
     */
    public NamedNodeMap getAttributes() {
        return null; // overridden in ElementImpl
    }

    /**
     * Gets the first child of this Node, or null if none.
     * <P>
     * By default we do not have any children, ParentNode overrides this.
     * 
     * @see ParentNode
     */
    public Node getFirstChild() {
        return null;
    }

    /**
     * Gets the last child of this Node, or null if none.
     * <P>
     * By default we do not have any children, ParentNode overrides this.
     * 
     * @see ParentNode
     */
    public Node getLastChild() {
        return null;
    }

    /** Returns the next child of this node's parent, or null if none. */
    public Node getNextSibling() {
        return null; // default behavior, overriden in ChildNode
    }

    public Node getParentNode() {
        return null; // overriden by ChildNode
        // Document, DocumentFragment, and Attribute will never have parents.
    }

    /*
     * Same as getParentNode but returns internal type NodeImpl.
     */
    NodeImpl parentNode() {
        return null;
    }

    /** Returns the previous child of this node's parent, or null if none. */
    public Node getPreviousSibling() {
        return null; // default behavior, overriden in ChildNode
    }

    // public Node cloneNode(boolean deep) {
    // if(this instanceof OMElement) {
    // return (Node)((OMElement)this).cloneOMElement();
    // } else if(this instanceof OMText ){
    // return ((TextImpl)this).cloneText();
    // } else {
    // throw new UnsupportedOperationException("Only elements can be cloned
    // right now");
    // }
    // }
    //    
    public Node cloneNode(boolean deep) {
        NodeImpl newnode;
        try {
            newnode = (NodeImpl) clone();
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException("**Internal Error**" + e);
        }
        newnode.ownerNode = this.ownerNode;
        newnode.isOwned(false);

        newnode.isReadonly(false);

        return newnode;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.w3c.dom.Node#getChildNodes()
     */
    public NodeList getChildNodes() {
        return this;
    }

    public boolean isSupported(String feature, String version) {
        throw new UnsupportedOperationException();
        // TODO
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.w3c.dom.Node#appendChild(org.w3c.dom.Node)
     */
    public Node appendChild(Node newChild) throws DOMException {
        return insertBefore(newChild, null);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.w3c.dom.Node#removeChild(org.w3c.dom.Node)
     */
    public Node removeChild(Node oldChild) throws DOMException {
        throw new DOMException(DOMException.NOT_FOUND_ERR, DOMMessageFormatter
                .formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_FOUND_ERR",
                               null));
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.w3c.dom.Node#insertBefore(org.w3c.dom.Node, org.w3c.dom.Node)
     */
    public Node insertBefore(Node newChild, Node refChild) throws DOMException {
        // Overridden in ParentNode
        throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
                               DOMMessageFormatter.formatMessage(
                                       DOMMessageFormatter.DOM_DOMAIN,
                                       "HIERARCHY_REQUEST_ERR", null));

    }

    /*
     * (non-Javadoc)
     * 
     * @see org.w3c.dom.Node#replaceChild(org.w3c.dom.Node, org.w3c.dom.Node)
     */
    public Node replaceChild(Node newChild, Node oldChild) throws DOMException {
        throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
                               DOMMessageFormatter.formatMessage(
                                       DOMMessageFormatter.DOM_DOMAIN,
                                       "HIERARCHY_REQUEST_ERR", null));
    }

    //
    // NodeList methods
    //

    /**
     * NodeList method: Returns the number of immediate children of this node.
     * <P>
     * By default we do not have any children, ParentNode overrides this.
     * 
     * @see ParentNode
     * 
     * @return Returns int.
     */
    public int getLength() {
        return 0;
    }

    /**
     * NodeList method: Returns the Nth immediate child of this node, or null if
     * the index is out of bounds.
     * <P>
     * By default we do not have any children, ParentNode overrides this.
     * 
     * @see ParentNode
     * 
     * @return Returns org.w3c.dom.Node
     * @param index
     */
    public Node item(int index) {
        return null;
    }

    /*
     * Flags setters and getters
     */

    final boolean isOwned() {
        return (flags & OWNED) != 0;
    }

    final void isOwned(boolean value) {
        flags = (short) (value ? flags | OWNED : flags & ~OWNED);
    }

    final boolean isFirstChild() {
        return (flags & FIRSTCHILD) != 0;
    }

    final void isFirstChild(boolean value) {
        flags = (short) (value ? flags | FIRSTCHILD : flags & ~FIRSTCHILD);
    }

    final boolean isReadonly() {
        return (flags & READONLY) != 0;
    }

    final void isReadonly(boolean value) {
        flags = (short) (value ? flags | READONLY : flags & ~READONLY);
    }

    final boolean isSpecified() {
        return (flags & SPECIFIED) != 0;
    }

    final void isSpecified(boolean value) {
        flags = (short) (value ? flags | SPECIFIED : flags & ~SPECIFIED);
    }

    final boolean isNormalized() {
        return (flags & NORMALIZED) != 0;
    }

    final void isNormalized(boolean value) {
        // See if flag should propagate to parent.
        if (!value && isNormalized() && ownerNode != null) {
            ownerNode.isNormalized(false);
        }
        flags = (short) (value ? flags | NORMALIZED : flags & ~NORMALIZED);
    }

    // /
    // /OM Methods
    // /

    /*
     * (non-Javadoc)
     * 
     * @see org.apache.axis2.om.OMNode#getParent()
     */
    public OMContainer getParent() throws OMException {
        return null; // overriden by ChildNode
        // Document, DocumentFragment, and Attribute will never have parents.
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.apache.axis2.om.OMNode#isComplete()
     */
    public boolean isComplete() {
        return this.done;
    }

    public void setComplete(boolean state) {
        this.done = state;

    }

    /**
     * There no concept of caching in this OM-DOM implementation.
     */
    public void internalSerializeWithCache(XMLStreamWriter writer)
            throws XMLStreamException {
        this.internalSerialize(writer);
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.apache.axis2.om.OMNode#insertSiblingAfter
     * (org.apache.axis2.om.OMNode)
     */
    public void insertSiblingAfter(OMNode sibling) throws OMException {
        // Overridden in ChildNode
        throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
                               DOMMessageFormatter.formatMessage(
                                       DOMMessageFormatter.DOM_DOMAIN,
                                       "HIERARCHY_REQUEST_ERR", null));

    }

    /*
     * (non-Javadoc)
     * 
     * @see org.apache.axis2.om.OMNode#insertSiblingBefore
     * (org.apache.axis2.om.OMNode)
     */
    public void insertSiblingBefore(OMNode sibling) throws OMException {
        // Overridden in ChildNode
        throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
                               DOMMessageFormatter.formatMessage(
                                       DOMMessageFormatter.DOM_DOMAIN,
                                       "HIERARCHY_REQUEST_ERR", null));

    }

    /**
     * Default behavior returns null, overriden in ChildNode.
     */
    public OMNode getPreviousOMSibling() {
        return null;
    }

    /**
     * Default behavior returns null, overriden in ChildNode.
     */
    public OMNode getNextOMSibling() {
        return null;
    }

    public void setPreviousOMSibling(OMNode previousSibling) {
        throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
                               DOMMessageFormatter.formatMessage(
                                       DOMMessageFormatter.DOM_DOMAIN,
                                       "HIERARCHY_REQUEST_ERR", null));
    }

    public void setNextOMSibling(OMNode previousSibling) {
        throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR,
                               DOMMessageFormatter.formatMessage(
                                       DOMMessageFormatter.DOM_DOMAIN,
                                       "HIERARCHY_REQUEST_ERR", null));
    }

    /**
     * Builds next element.
     */
    public void build() {
        while (!done)
            this.builder.next();
    }

    /**
     * Sets the owner document.
     * 
     * @param document
     */
    protected void setOwnerDocument(DocumentImpl document) {
        this.ownerNode = document;
        this.isOwned(true);
    }

    public void serialize(XMLStreamWriter xmlWriter) throws XMLStreamException {
        MTOMXMLStreamWriter writer = new MTOMXMLStreamWriter(xmlWriter);
        internalSerialize(writer);
        writer.flush();
    }

    public void serializeAndConsume(XMLStreamWriter xmlWriter)
            throws XMLStreamException {
        MTOMXMLStreamWriter writer = new MTOMXMLStreamWriter(xmlWriter);
        internalSerializeAndConsume(writer);
        writer.flush();
    }

    public OMNode detach() {
        throw new OMException(
                "Elements that doesn't have a parent can not be detached");
    }

    /*
     * DOM-Level 3 methods
     */

    public String getBaseURI() {
        // TODO TODO
        throw new UnsupportedOperationException("TODO");
    }

    public short compareDocumentPosition(Node arg0) throws DOMException {
        // TODO TODO
        throw new UnsupportedOperationException("TODO");
    }

    public String getTextContent() throws DOMException {
        // TODO TODO
        throw new UnsupportedOperationException("TODO");
    }

    public void setTextContent(String arg0) throws DOMException {
        // TODO TODO
        throw new UnsupportedOperationException("TODO");
    }

    public boolean isSameNode(Node arg0) {
        // TODO TODO
        throw new UnsupportedOperationException("TODO");
    }

    public String lookupPrefix(String arg0) {
        // TODO TODO
        throw new UnsupportedOperationException("TODO");
    }

    public boolean isDefaultNamespace(String arg0) {
        // TODO TODO
        throw new UnsupportedOperationException("TODO");
    }

    public String lookupNamespaceURI(String arg0) {
        // TODO TODO
        throw new UnsupportedOperationException("TODO");
    }

    public boolean isEqualNode(Node arg0) {
        // TODO TODO
        throw new UnsupportedOperationException("TODO");
    }

    public Object getFeature(String arg0, String arg1) {
        // TODO TODO
        throw new UnsupportedOperationException("TODO");
    }

    public Object setUserData(String key, Object value, UserDataHandler userDataHandler) {
       return userData.put(key, value);
    }

    public Object getUserData(String key) {
        return userData.get(key);
    }

    public void serialize(OutputStream output) throws XMLStreamException {
        serialize(StAXUtils.createXMLStreamWriter(output));
    }

    public void serialize(Writer writer) throws XMLStreamException {
        serialize(StAXUtils.createXMLStreamWriter(writer));
    }

    public void serializeAndConsume(OutputStream output)
            throws XMLStreamException {
        serializeAndConsume(StAXUtils
                .createXMLStreamWriter(output));
    }

    public void serializeAndConsume(Writer writer) throws XMLStreamException {
        serializeAndConsume(StAXUtils
                .createXMLStreamWriter(writer));
    }

    public void serialize(OutputStream output, OMOutputFormat format)
            throws XMLStreamException {
        MTOMXMLStreamWriter writer = new MTOMXMLStreamWriter(output, format);
        internalSerialize(writer);
        writer.flush();
    }

    public void serialize(Writer writer2, OMOutputFormat format)
            throws XMLStreamException {
        MTOMXMLStreamWriter writer = new MTOMXMLStreamWriter(StAXUtils
                .createXMLStreamWriter(writer2));
        writer.setOutputFormat(format);
        internalSerialize(writer);
        writer.flush();
    }

    public void serializeAndConsume(OutputStream output, OMOutputFormat format)
            throws XMLStreamException {
        MTOMXMLStreamWriter writer = new MTOMXMLStreamWriter(output, format);
        internalSerializeAndConsume(writer);
        writer.flush();
    }

    public void serializeAndConsume(Writer writer2, OMOutputFormat format)
            throws XMLStreamException {
        MTOMXMLStreamWriter writer = new MTOMXMLStreamWriter(StAXUtils
                .createXMLStreamWriter(writer2));
        writer.setOutputFormat(format);
        internalSerializeAndConsume(writer);
        writer.flush();
    }

    /**
     * Returns the <code>OMFactory</code> that created this node
     */
    public OMFactory getOMFactory() {
        return this.factory;
    }
}
