/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 freemarker.template.utility;

import java.util.HashMap;
import java.util.List;

import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

import freemarker.ext.dom.NodeModel;
import freemarker.template.SimpleHash;
import freemarker.template.SimpleScalar;
import freemarker.template.TemplateBooleanModel;
import freemarker.template.TemplateHashModel;
import freemarker.template.TemplateMethodModel;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;
import freemarker.template.TemplateSequenceModel;
import freemarker.template._TemplateAPI;

/**
 * A convenient wrapper class for wrapping a Node in the W3C DOM API.
 *
 * @deprecated Use {@link NodeModel} instead
 */
@Deprecated
public class DOMNodeModel implements TemplateHashModel {

    static private HashMap equivalenceTable = new HashMap();
    static {
        equivalenceTable.put("*", "children");
        equivalenceTable.put("@*", "attributes");
    }

    private Node node;
    private HashMap cache = new HashMap();

    public DOMNodeModel(Node node) {
        this.node = node;
    }

    @Override
    public TemplateModel get(String key) throws TemplateModelException {
        TemplateModel result = null;
        if (equivalenceTable.containsKey(key)) {
            key = (String) equivalenceTable.get(key);
        }
        if (cache.containsKey(key)) {
            result = (TemplateModel) cache.get(key);
        }
        if (result == null) {
            if ("attributes".equals(key)) {
                NamedNodeMap attributes = node.getAttributes();
                if (attributes != null) {
                    SimpleHash hash = new SimpleHash(_TemplateAPI.SAFE_OBJECT_WRAPPER);
                    for (int i = 0; i < attributes.getLength(); i++) {
                        Attr att = (Attr) attributes.item(i);
                        hash.put(att.getName(), att.getValue());
                    }
                    result = hash;
                }
            } else if (key.charAt(0) == '@') {
                if (node instanceof Element) {
                    String attValue = ((Element) node).getAttribute(key.substring(1));
                    result = new SimpleScalar(attValue);
                } else {
                    throw new TemplateModelException("Trying to get an attribute value for a non-element node");
                }
            } else if ("is_element".equals(key)) {
                result = (node instanceof Element) ?
                    TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
            } else if ("is_text".equals(key)) {
                result = (node instanceof Text) ?
                    TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
            } else if ("name".equals(key)) {
                result = new SimpleScalar(node.getNodeName());
            } else if ("children".equals(key)) {
                result = new NodeListTM(node.getChildNodes());
            } else if ("parent".equals(key)) {
                Node parent = node.getParentNode();
                result = (parent == null) ? null : new DOMNodeModel(parent);
            } else if ("ancestorByName".equals(key)) {
                result = new AncestorByName();
            } else if ("nextSibling".equals(key)) {
                Node next = node.getNextSibling();
                result = (next == null) ? null : new DOMNodeModel(next);
            } else if ("previousSibling".equals(key)) {
                Node previous = node.getPreviousSibling();
                result = (previous == null) ? null : new DOMNodeModel(previous);
            } else if ("nextSiblingElement".equals(key)) {
                Node next = nextSiblingElement(node);
                result = (next == null) ? null : new DOMNodeModel(next);
            } else if ("previousSiblingElement".equals(key)) {
                Node previous = previousSiblingElement(node);
                result = (previous == null) ? null : new DOMNodeModel(previous);
            } else if ("nextElement".equals(key)) {
                Node next = nextElement(node);
                result = (next == null) ? null : new DOMNodeModel(next);
            } else if ("previousElement".equals(key)) {
                Node previous = previousElement(node);
                result = (previous == null) ? null : new DOMNodeModel(previous);
            } else if ("text".equals(key)) {
                result = new SimpleScalar(getText(node));
            }
            cache.put(key, result);
        }
        return result;
    }

    @Override
    public boolean isEmpty() {
        return false;
    }

    static private String getText(Node node) {
        String result = "";
        if (node instanceof Text) {
            result = ((Text) node).getData();
        } else if (node instanceof Element) {
            NodeList children = node.getChildNodes();
            for (int i = 0; i < children.getLength(); i++) {
                result += getText(children.item(i));
            }
        }
        return result;
    }

    static private Element nextSiblingElement(Node node) {
        Node next = node;
        while (next != null) {
            next = next.getNextSibling();
            if (next instanceof Element) {
                return (Element) next;
            }
        }
        return null;
    }

    static private Element previousSiblingElement(Node node) {
        Node previous = node;
        while (previous != null) {
            previous = previous.getPreviousSibling();
            if (previous instanceof Element) {
                return (Element) previous;
            }
        }
        return null;
    }

    static private Element nextElement(Node node) {
        if (node.hasChildNodes()) {
            NodeList children = node.getChildNodes();
            for (int i = 0; i < children.getLength(); i++) {
                Node child = children.item(i);
                if (child instanceof Element) {
                    return (Element) child;
                }
            }
        }
        Element nextSiblingElement = nextSiblingElement(node);
        if (nextSiblingElement != null) {
            return nextSiblingElement;
        }
        Node parent = node.getParentNode();
        while (parent instanceof Element) {
            Element next = nextSiblingElement(parent);
            if (next != null) {
                return next;
            }
            parent = parent.getParentNode();
        }
        return null;
    }

    static private Element previousElement(Node node) {
        Element result = previousSiblingElement(node);
        if (result != null) {
            return result;
        }
        Node parent = node.getParentNode();
        if (parent instanceof Element) {
            return (Element) parent;
        }
        return null;
    }

    void setParent(DOMNodeModel parent) {
        if (parent != null) {
            cache.put("parent", parent);
        }
    }

    String getNodeName() {
        return node.getNodeName();
    }


    class AncestorByName implements TemplateMethodModel {
        @Override
        public Object exec(List arguments) throws TemplateModelException {
            if (arguments.size() != 1) {
                throw new TemplateModelException("Expecting exactly one string argument here");
            }
            String nodeName = (String) arguments.get(0);
            DOMNodeModel ancestor = (DOMNodeModel) DOMNodeModel.this.get("parent");
            while (ancestor != null) {
                if (nodeName.equals(ancestor.getNodeName())) {
                    return ancestor;
                }
                ancestor = (DOMNodeModel) ancestor.get("parent");
            }
            return null;
        }
    }


    class NodeListTM implements TemplateSequenceModel, TemplateMethodModel {

        private NodeList nodeList;
        private TemplateModel[] nodes;

        NodeListTM(NodeList nodeList) {
            this.nodeList = nodeList;
            nodes = new TemplateModel[nodeList.getLength()];
        }

        @Override
        public TemplateModel get(int index) {
            DOMNodeModel result = (DOMNodeModel) nodes[index];
            if (result == null) {
                result = new DOMNodeModel(nodeList.item(index));
                nodes[index] = result;
                result.setParent(DOMNodeModel.this);
            }
            return result;
        }

        @Override
        public int size() {
            return nodes.length;
        }

        @Override
        public Object exec(List arguments) throws TemplateModelException {
            if (arguments.size() != 1) {
                throw new TemplateModelException("Expecting exactly one string argument here");
            }
            if (!(node instanceof Element)) {
                throw new TemplateModelException("Expecting element here.");
            }
            Element elem = (Element) node;
            return new NodeListTM(elem.getElementsByTagName((String) arguments.get(0)));
        }
    }
}

