/*
 * 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.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;

/**
 * A convenient wrapper class for wrapping a Node in the W3C DOM API.
 */

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;
    }

    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();
                    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;
    }

    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 {
        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()];
        }

        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;
        }

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

        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)));
        }
    }
}

