/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * 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.harmony.xml.dom;

import org.w3c.dom.DOMException;
import org.w3c.dom.Node;
import org.w3c.dom.Text;

/**
 * Provides a straightforward implementation of the corresponding W3C DOM
 * interface. The class is used internally only, thus only notable members that
 * are not in the original interface are documented (the W3C docs are quite
 * extensive). Hope that's ok.
 * <p>
 * Some of the fields may have package visibility, so other classes belonging to
 * the DOM implementation can easily access them while maintaining the DOM tree
 * structure.
 */
public class TextImpl extends CharacterDataImpl implements Text {

    public TextImpl(DocumentImpl document, String data) {
        super(document, data);
    }

    @Override
    public String getNodeName() {
        return "#text";
    }

    @Override
    public short getNodeType() {
        return Node.TEXT_NODE;
    }

    public final Text splitText(int offset) throws DOMException {
        Text newText = getOwnerDocument().createTextNode(
                substringData(offset, getLength() - offset));
        deleteData(0, offset);

        Node refNode = getNextSibling();
        if (refNode == null) {
            getParentNode().appendChild(newText);
        } else {
            getParentNode().insertBefore(newText, refNode);
        }

        return this;
    }

    public final boolean isElementContentWhitespace() {
        // Undefined because we don't validate. Whether whitespace characters
        // constitute "element content whitespace" is defined by the containing
        // element's declaration (DTD) and we don't parse that.
        // TODO: wire this up when we support document validation
        return false;
    }

    public final String getWholeText() {
        // TODO: support entity references. This code should expand through
        // the child elements of entity references.
        //     http://code.google.com/p/android/issues/detail?id=6807

        StringBuilder result = new StringBuilder();
        for (TextImpl n = firstTextNodeInCurrentRun(); n != null; n = n.nextTextNode()) {
            n.appendDataTo(result);
        }
        return result.toString();
    }

    public final Text replaceWholeText(String content) throws DOMException {
        // TODO: support entity references. This code should expand and replace
        // the child elements of entity references.
        //     http://code.google.com/p/android/issues/detail?id=6807

        Node parent = getParentNode();
        Text result = null;

        // delete all nodes in the current run of text...
        for (TextImpl n = firstTextNodeInCurrentRun(); n != null; ) {

            // ...except the current node if we have content for it
            if (n == this && content != null && content.length() > 0) {
                setData(content);
                result = this;
                n = n.nextTextNode();

            } else {
                Node toRemove = n; // because removeChild() detaches siblings
                n = n.nextTextNode();
                parent.removeChild(toRemove);
            }
        }

        return result;
    }

    /**
     * Returns the first text or CDATA node in the current sequence of text and
     * CDATA nodes.
     */
    private TextImpl firstTextNodeInCurrentRun() {
        TextImpl firstTextInCurrentRun = this;
        for (Node p = getPreviousSibling(); p != null; p = p.getPreviousSibling()) {
            short nodeType = p.getNodeType();
            if (nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) {
                firstTextInCurrentRun = (TextImpl) p;
            } else {
                break;
            }
        }
        return firstTextInCurrentRun;
    }

    /**
     * Returns the next sibling node if it exists and it is text or CDATA.
     * Otherwise returns null.
     */
    private TextImpl nextTextNode() {
        Node nextSibling = getNextSibling();
        if (nextSibling == null) {
            return null;
        }

        short nodeType = nextSibling.getNodeType();
        return nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE
                ? (TextImpl) nextSibling
                : null;
    }

    /**
     * Tries to remove this node using itself and the previous node as context.
     * If this node's text is empty, this node is removed and null is returned.
     * If the previous node exists and is a text node, this node's text will be
     * appended to that node's text and this node will be removed.
     *
     * <p>Although this method alters the structure of the DOM tree, it does
     * not alter the document's semantics.
     *
     * @return the node holding this node's text and the end of the operation.
     *     Can be null if this node contained the empty string.
     */
    public final TextImpl minimize() {
        if (getLength() == 0) {
            parent.removeChild(this);
            return null;
        }

        Node previous = getPreviousSibling();
        if (previous == null || previous.getNodeType() != Node.TEXT_NODE) {
            return this;
        }

        TextImpl previousText = (TextImpl) previous;
        previousText.buffer.append(buffer);
        parent.removeChild(this);
        return previousText;
    }
}
