/*
 * $Id: DOMNodeImpl.java,v 1.2 2005/11/03 13:59:00 sugimotokenichi Exp $
 * Copyright (C) 2005 SUGIMOTO Ken-ichi
 * 作成日: 2005/10/30
 */
package feat.v1.impl.template;

import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import feat.v1.template.HTMLNode;
import feat.v1.template.NodeIterator;
import feat.v1.template.NodeListIterator;
import feat.v1.template.NodeNotFoundException;

/**
 * DOM APIのNodeの実装。
 * @author SUGIMOTO Ken-ichi
 */
abstract public class DOMNodeImpl implements Node, HTMLConvertibleNode {

    private HTMLNodeImpl htmlNode;

    DOMNodeImpl(HTMLNodeImpl htmlNode) {
        this.htmlNode = htmlNode;
    }

    public HTMLNode convertHTML() {
        return htmlNode;
    }

    public void normalize() {
    }

    public boolean hasChildNodes() {
        return getFirstChild() != null;
    }

    public String getNamespaceURI() {
        return null;
    }

    public String getPrefix() {
        return null;
    }

    public void setPrefix(String prefix) throws DOMException {
    }

    public Document getOwnerDocument() {
        try {
            return (Document)TemplateUtil.toDomNode(htmlNode.getDocument());
        }
        catch (NodeNotFoundException ex) {
            return null;
        }
    }

    public Node getFirstChild() {
        if ( htmlNode instanceof HTMLCompositeNodeImpl ) {
            return TemplateUtil.toDomNode(((HTMLCompositeNodeImpl)htmlNode).firstChild);
        }
        return null;
    }

    public Node getLastChild() {
        if ( htmlNode instanceof HTMLCompositeNodeImpl ) {
            HTMLCompositeNodeImpl cnode = (HTMLCompositeNodeImpl)htmlNode;
            if ( cnode.firstChild != null ) {
                return TemplateUtil.toDomNode(cnode.firstChild.getLast());
            }
        }
        return null;
    }

    public Node getNextSibling() {
        return TemplateUtil.toDomNode(htmlNode.next);
    }

    public Node getParentNode() {
        return TemplateUtil.toDomNode(htmlNode.parent);
    }

    public Node getPreviousSibling() {
        return TemplateUtil.toDomNode(htmlNode.prev);
    }

    public Node cloneNode(boolean deep) {
        return TemplateUtil.toDomNode(htmlNode.copy(deep));
    }

    public NodeList getChildNodes() {
        HTMLNodeListImpl ret = new HTMLNodeListImpl();
        try {
            NodeIterator it = new NodeListIterator(htmlNode.getFirstChild());
            while(it.hasNext()) {
                ret.add(it.nextNode());
            }
        }
        catch (NodeNotFoundException ex) {
        }
        return ret;
    }

    public boolean isSupported(String feature, String version) {
        return false;
    }

    public Node appendChild(Node newChild) throws DOMException {
        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "");
    }

    public Node removeChild(Node oldChild) throws DOMException {
        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "");
    }

    public Node insertBefore(Node newChild, Node refChild) throws DOMException {
        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "");
    }

    public Node replaceChild(Node newChild, Node oldChild) throws DOMException {
        throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "");
    }
}
