/*
 * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
 *
 * The contents of this file are subject to the CCM Public
 * License (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.redhat.com/licenses/ccmpl.html.
 *
 * Software distributed under the License is distributed on an
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
 * or implied. See the License for the specific language
 * governing rights and limitations under the License.
 *
 */
package com.arsdigita.bebop.jsp;

import javax.servlet.jsp.JspException;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.Text;

public class ShowContainer extends ShowComponent {

    public static final String versionId = "$Id: //core-platform/dev/src/com/arsdigita/bebop/jsp/ShowContainer.java#8 $ by $Author: dennis $, $DateTime: 2004/04/07 16:07:11 $";

    private Node m_inputContext;
    private Node m_outputContext;
    private boolean m_empty = true;

    Node getInputContext() {
        if (m_inputContext == null) {
            return getContainerTag().getInputContext();
        } else {
            return m_inputContext;
        }
    }

    Node getOutputContext() {
        // unless otherwise specified, our output context is unchanged
        // from our parent tag's.  So walk up the tree of show:...
        // until we find some base case like page or form.
        if (m_outputContext == null) {
            ShowContainer parentTag = getContainerTag();
            return parentTag.getOutputContext();
        } else {
            return m_outputContext;
        }
    }

    void setOutputContext(Node n) {
        m_outputContext = n;
    }

    void setInputContext(Node n) {
        if (n != null) {
            m_inputContext = n;
        }
    }

    /**
     * When we open a container tag, by default we introduce a new
     * scoping level in our input context.  Any tree walkers we build
     * within this container will start their traversal rooted at the
     * element that corresponds with this container itself.  (Note that
     * page is a special case.)
     */
    public int doStartTag() throws JspException {
        m_inputContext = findFirstMatch(getName());
        setOutputContext(getContainerTag().getOutputContext());
        return super.doStartTag();
    }

    public int doEndTag() throws JspException {
        if (isEmpty()) {
            // do deep copy and add to parent output context
            return super.doEndTag();
        } else {
            // nested tags have already added stuff we want,
            // so do nothing.
            return EVAL_PAGE;
        }
    }

    /**
     * Literal text is turned into &lt;bebop:label> nodes with
     * output escaping disabled.
     */
    void handleText() throws JspException {
        if (bodyContent == null) {
            return;
        }

        String text = bodyContent.getString();
        if (text != null && text.length() > 0) {
            m_empty = false;
            Element label =
                getResultDocument().createElementNS(BEBOP_XMLNS,
                                                    "bebop:label");
            label.setAttribute("escape", "yes");
            Text textNode = getResultDocument().createTextNode(text);
            label.appendChild(textNode);
            getOutputContext().appendChild(label);
            try {
                bodyContent.clear();
            } catch (java.io.IOException ioe) {
                throw new JspException(ioe.toString());
            }
        }
    }

    public int doAfterBody() throws JspException {
        handleText();
        return SKIP_BODY;
    }

    boolean isEmpty() {
        return m_empty;
    }
}
