/*******************************************************************************
 * 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 org.ofbiz.widget.model;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.ParserConfigurationException;

import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.GeneralException;
import org.ofbiz.base.util.StringUtil;
import org.ofbiz.base.util.UtilCodec;
import org.ofbiz.base.util.UtilGenerics;
import org.ofbiz.base.util.UtilHttp;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.base.util.UtilXml;
import org.ofbiz.base.util.collections.MapStack;
import org.ofbiz.base.util.string.FlexibleStringExpander;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.entity.model.ModelEntity;
import org.ofbiz.entity.model.ModelField;
import org.ofbiz.entity.util.EntityListIterator;
import org.ofbiz.entity.util.EntityQuery;
import org.ofbiz.widget.WidgetWorker;
import org.ofbiz.widget.model.CommonWidgetModels.Parameter;
import org.ofbiz.widget.renderer.ScreenRenderException;
import org.ofbiz.widget.renderer.ScreenStringRenderer;
import org.ofbiz.widget.renderer.TreeStringRenderer;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

/**
 * Models the &lt;tree&gt; element.
 * 
 * @see <code>widget-tree.xsd</code>
 */
@SuppressWarnings("serial")
public class ModelTree extends ModelWidget {

    /*
     * ----------------------------------------------------------------------- *
     *                     DEVELOPERS PLEASE READ
     * ----------------------------------------------------------------------- *
     * 
     * This model is intended to be a read-only data structure that represents
     * an XML element. Outside of object construction, the class should not
     * have any behaviors.
     * 
     * Instances of this class will be shared by multiple threads - therefore
     * it is immutable. DO NOT CHANGE THE OBJECT'S STATE AT RUN TIME!
     * 
     */

    public static final String module = ModelTree.class.getName();

    private final String defaultEntityName;
    private final String defaultRenderStyle;
    private final FlexibleStringExpander defaultWrapStyleExdr;
    private final FlexibleStringExpander expandCollapseRequestExdr;
    private final boolean forceChildCheck;
    private final String location;
    private final Map<String, ModelNode> nodeMap;
    private final int openDepth;
    private final int postTrailOpenDepth;
    private final String rootNodeName;
    private final FlexibleStringExpander trailNameExdr;

    public ModelTree(Element treeElement, String location) {
        super(treeElement);
        this.location = location;
        this.rootNodeName = treeElement.getAttribute("root-node-name");
        String defaultRenderStyle = UtilXml.checkEmpty(treeElement.getAttribute("default-render-style"), "simple");
        // A temporary hack to accommodate those who might still be using "render-style" instead of "default-render-style"
        if (defaultRenderStyle.isEmpty() || defaultRenderStyle.equals("simple")) {
            String rStyle = treeElement.getAttribute("render-style");
            if (!rStyle.isEmpty())
                defaultRenderStyle = rStyle;
        }
        this.defaultRenderStyle = defaultRenderStyle;
        this.defaultWrapStyleExdr = FlexibleStringExpander.getInstance(treeElement.getAttribute("default-wrap-style"));
        this.expandCollapseRequestExdr = FlexibleStringExpander.getInstance(treeElement.getAttribute("expand-collapse-request"));
        this.trailNameExdr = FlexibleStringExpander.getInstance(UtilXml.checkEmpty(treeElement.getAttribute("trail-name"),
                "trail"));
        this.forceChildCheck = !"false".equals(treeElement.getAttribute("force-child-check"));
        this.defaultEntityName = treeElement.getAttribute("entity-name");
        int openDepth = 0;
        if (treeElement.hasAttribute("open-depth")) {
            try {
                openDepth = Integer.parseInt(treeElement.getAttribute("open-depth"));
            } catch (NumberFormatException e) {
                throw new IllegalArgumentException("Invalid open-depth attribute value for the tree definition with name: "
                        + getName());
            }
        }
        this.openDepth = openDepth;
        int postTrailOpenDepth = 999;
        if (treeElement.hasAttribute("post-trail-open-depth")) {
            try {
                postTrailOpenDepth = Integer.parseInt(treeElement.getAttribute("post-trail-open-depth"));
            } catch (NumberFormatException e) {
                throw new IllegalArgumentException(
                        "Invalid post-trail-open-depth attribute value for the tree definition with name: " + getName());
            }
        }
        this.postTrailOpenDepth = postTrailOpenDepth;
        List<? extends Element> nodeElements = UtilXml.childElementList(treeElement, "node");
        if (nodeElements.size() == 0) {
            throw new IllegalArgumentException("No node elements found for the tree definition with name: " + getName());
        }
        Map<String, ModelNode> nodeMap = new HashMap<String, ModelNode>();
        for (Element nodeElementEntry : UtilXml.childElementList(treeElement, "node")) {
            ModelNode node = new ModelNode(nodeElementEntry, this);
            String nodeName = node.getName();
            nodeMap.put(nodeName, node);
        }
        this.nodeMap = Collections.unmodifiableMap(nodeMap);
    }

    @Override
    public void accept(ModelWidgetVisitor visitor) throws Exception {
        visitor.visit(this);
    }

    @Override
    public String getBoundaryCommentName() {
        return location + "#" + getName();
    }

    public String getDefaultEntityName() {
        return this.defaultEntityName;
    }

    public String getDefaultPkName(Map<String, Object> context) {
        ModelEntity modelEntity = WidgetWorker.getDelegator(context).getModelEntity(this.defaultEntityName);
        if (modelEntity.getPksSize() == 1) {
            ModelField modelField = modelEntity.getOnlyPk();
            return modelField.getName();
        }
        return null;
    }

    public String getExpandCollapseRequest(Map<String, Object> context) {
        String expColReq = this.expandCollapseRequestExdr.expandString(context);
        if (UtilValidate.isEmpty(expColReq)) {
            HttpServletRequest request = (HttpServletRequest) context.get("request");
            String s1 = request.getRequestURI();
            int pos = s1.lastIndexOf("/");
            if (pos >= 0)
                expColReq = s1.substring(pos + 1);
            else
                expColReq = s1;
        }
        //append also the request parameters
        Map<String, Object> paramMap = UtilGenerics.checkMap(context.get("requestParameters"));
        if (UtilValidate.isNotEmpty(paramMap)) {
            Map<String, Object> requestParameters = new HashMap<String, Object>(paramMap);
            requestParameters.remove(this.getTrailName(context));
            if (UtilValidate.isNotEmpty(requestParameters)) {
                String queryString = UtilHttp.urlEncodeArgs(requestParameters, false);
                if (expColReq.indexOf("?") < 0) {
                    expColReq += "?";
                } else {
                    expColReq += "&amp;";
                }
                expColReq += queryString;
            }
        }
        return expColReq;
    }

    public int getOpenDepth() {
        return openDepth;
    }

    public int getPostTrailOpenDepth() {
        return postTrailOpenDepth;
    }

    public String getRenderStyle() {
        return this.defaultRenderStyle;
    }

    public String getRootNodeName() {
        return rootNodeName;
    }

    public String getTrailName(Map<String, Object> context) {
        return this.trailNameExdr.expandString(context);
    }

    public String getWrapStyle(Map<String, Object> context) {
        return this.defaultWrapStyleExdr.expandString(context);
    }

    /**
     * Renders this model.
     *
     * @param writer
     * @param context
     * @param treeStringRenderer
     */
    @SuppressWarnings("rawtypes")
    public void renderTreeString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer)
            throws GeneralException {
        Map<String, Object> parameters = UtilGenerics.checkMap(context.get("parameters"));
        ModelNode node = nodeMap.get(rootNodeName);
        String trailName = trailNameExdr.expandString(context);
        String treeString = (String) context.get(trailName);
        if (UtilValidate.isEmpty(treeString)) {
            treeString = (String) parameters.get(trailName);
        }
        List<String> trail = null;
        if (UtilValidate.isNotEmpty(treeString)) {
            trail = StringUtil.split(treeString, "|");
            if (UtilValidate.isEmpty(trail))
                throw new RuntimeException("Tree 'trail' value is empty.");
            context.put("rootEntityId", trail.get(0));
            context.put(getDefaultPkName(context), trail.get(0));
        } else {
            trail = new LinkedList<String>();
        }
        context.put("targetNodeTrail", trail);
        context.put("currentNodeTrail", new LinkedList());
        try {
            node.renderNodeString(writer, context, treeStringRenderer, 0);
        } catch (IOException e2) {
            String errMsg = "Error rendering included label with name [" + getName() + "] : " + e2.toString();
            Debug.logError(e2, errMsg, module);
            throw new RuntimeException(errMsg);
        }

    }

    public String getDefaultRenderStyle() {
        return defaultRenderStyle;
    }

    public FlexibleStringExpander getDefaultWrapStyleExdr() {
        return defaultWrapStyleExdr;
    }

    public FlexibleStringExpander getExpandCollapseRequestExdr() {
        return expandCollapseRequestExdr;
    }

    public boolean getForceChildCheck() {
        return forceChildCheck;
    }

    public String getLocation() {
        return location;
    }

    public Map<String, ModelNode> getNodeMap() {
        return nodeMap;
    }

    public FlexibleStringExpander getTrailNameExdr() {
        return trailNameExdr;
    }

    /**
     * Models the &lt;node&gt; element.
     * 
     * @see <code>widget-tree.xsd</code>
     */
    public static class ModelNode extends ModelWidget {

        private final List<ModelAction> actions;
        // TODO: Make this a generic condition object.
        private final ModelTreeCondition condition;
        private final String entityName;
        private final String entryName;
        private final String expandCollapseStyle;
        private final Label label;
        private final Link link;
        private final ModelTree modelTree;
        private final String pkName;
        private final String renderStyle;
        private final FlexibleStringExpander screenLocationExdr;
        private final FlexibleStringExpander screenNameExdr;
        private final String shareScope;
        private final List<ModelSubNode> subNodeList;
        private final FlexibleStringExpander wrapStyleExdr;

        public ModelNode(Element nodeElement, ModelTree modelTree) {
            super(nodeElement);
            this.modelTree = modelTree;
            this.expandCollapseStyle = nodeElement.getAttribute("expand-collapse-style");
            this.wrapStyleExdr = FlexibleStringExpander.getInstance(nodeElement.getAttribute("wrap-style"));
            this.renderStyle = nodeElement.getAttribute("render-style");
            this.entryName = nodeElement.getAttribute("entry-name");
            this.entityName = nodeElement.getAttribute("entity-name");
            this.pkName = nodeElement.getAttribute("join-field-name");
            ArrayList<ModelAction> actions = new ArrayList<ModelAction>();
            // FIXME: Validate child elements, should be only one of actions, entity-one, service, script.
            Element actionsElement = UtilXml.firstChildElement(nodeElement, "actions");
            if (actionsElement != null) {
                actions.addAll(ModelTreeAction.readNodeActions(this, actionsElement));
            }
            Element actionElement = UtilXml.firstChildElement(nodeElement, "entity-one");
            if (actionElement != null) {
                actions.add(new AbstractModelAction.EntityOne(this, actionElement));
            }
            actionElement = UtilXml.firstChildElement(nodeElement, "service");
            if (actionElement != null) {
                actions.add(new ModelTreeAction.Service(this, actionElement));
            }
            actionElement = UtilXml.firstChildElement(nodeElement, "script");
            if (actionElement != null) {
                actions.add(new ModelTreeAction.Script(this, actionElement));
            }
            actions.trimToSize();
            this.actions = Collections.unmodifiableList(actions);
            Element screenElement = UtilXml.firstChildElement(nodeElement, "include-screen");
            if (screenElement != null) {
                this.screenNameExdr = FlexibleStringExpander.getInstance(screenElement.getAttribute("name"));
                this.screenLocationExdr = FlexibleStringExpander.getInstance(screenElement.getAttribute("location"));
                this.shareScope = screenElement.getAttribute("share-scope");
            } else {
                this.screenNameExdr = FlexibleStringExpander.getInstance("");
                this.screenLocationExdr = FlexibleStringExpander.getInstance("");
                this.shareScope = "";
            }
            Element labelElement = UtilXml.firstChildElement(nodeElement, "label");
            if (labelElement != null) {
                this.label = new Label(labelElement);
            } else {
                this.label = null;
            }
            Element linkElement = UtilXml.firstChildElement(nodeElement, "link");
            if (linkElement != null) {
                this.link = new Link(linkElement);
            } else {
                this.link = null;
            }
            Element conditionElement = UtilXml.firstChildElement(nodeElement, "condition");
            if (conditionElement != null) {
                this.condition = new ModelTreeCondition(modelTree, conditionElement);
            } else {
                this.condition = null;
            }
            List<? extends Element> nodeElements = UtilXml.childElementList(nodeElement, "sub-node");
            if (!nodeElements.isEmpty()) {
                List<ModelSubNode> subNodeList = new ArrayList<ModelSubNode>();
                for (Element subNodeElementEntry : nodeElements) {
                    ModelSubNode subNode = new ModelSubNode(subNodeElementEntry, this);
                    subNodeList.add(subNode);
                }
                this.subNodeList = Collections.unmodifiableList(subNodeList);
            } else {
                this.subNodeList = Collections.emptyList();
            }
        }

        @Override
        public void accept(ModelWidgetVisitor visitor) throws Exception {
            visitor.visit(this);
        }

        private List<Object[]> getChildren(Map<String, Object> context) {
            List<Object[]> subNodeValues = new ArrayList<Object[]>();
            for (ModelSubNode subNode : subNodeList) {
                String nodeName = subNode.getNodeName(context);
                ModelNode node = modelTree.nodeMap.get(nodeName);
                List<ModelAction> subNodeActions = subNode.getActions();
                //if (Debug.infoOn()) Debug.logInfo(" context.currentValue:" + context.get("currentValue"), module);
                AbstractModelAction.runSubActions(subNodeActions, context);
                // List dataFound = (List)context.get("dataFound");
                Iterator<? extends Map<String, ? extends Object>> dataIter = subNode.getListIterator(context);
                if (dataIter instanceof EntityListIterator) {
                    EntityListIterator eli = (EntityListIterator) dataIter;
                    Map<String, Object> val = null;
                    while ((val = eli.next()) != null) {
                        Object[] arr = { node, val };
                        subNodeValues.add(arr);
                    }
                    try {
                        eli.close();
                    } catch (GenericEntityException e) {
                        Debug.logError(e, module);
                        throw new RuntimeException(e.getMessage());
                    }
                } else if (dataIter != null) {
                    while (dataIter.hasNext()) {
                        Map<String, ? extends Object> val = dataIter.next();
                        Object[] arr = { node, val };
                        subNodeValues.add(arr);
                    }
                }
            }
            return subNodeValues;
        }

        public String getEntityName() {
            if (!this.entityName.isEmpty()) {
                return this.entityName;
            } else {
                return this.modelTree.getDefaultEntityName();
            }
        }

        public String getEntryName() {
            return this.entryName;
        }

        public String getExpandCollapseStyle() {
            return expandCollapseStyle;
        }

        public ModelTree getModelTree() {
            return this.modelTree;
        }

        public String getPkName(Map<String, Object> context) {
            if (UtilValidate.isNotEmpty(this.pkName)) {
                return this.pkName;
            } else {
                return this.modelTree.getDefaultPkName(context);
            }
        }

        public String getRenderStyle() {
            if (this.renderStyle.isEmpty())
                return modelTree.getRenderStyle();
            return this.renderStyle;
        }

        public String getWrapStyle(Map<String, Object> context) {
            String val = this.wrapStyleExdr.expandString(context);
            if (val.isEmpty()) {
                val = this.modelTree.getWrapStyle(context);
            }
            return val;
        }

        public boolean hasChildren(Map<String, Object> context) {
            List<Object[]> subNodeValues = getChildren(context);
            boolean hasChildren = false;
            Long nodeCount = null;
            String countFieldName = "childBranchCount";
            Object obj = null;
            if (!this.entryName.isEmpty()) {
                Map<String, Object> map = UtilGenerics.cast(context.get(this.entryName));
                if (map instanceof GenericValue) {
                    ModelEntity modelEntity = ((GenericValue) map).getModelEntity();
                    if (modelEntity.isField(countFieldName)) {
                        obj = map.get(countFieldName);
                    }
                }
            } else {
                obj = context.get(countFieldName);
            }
            if (obj != null) {
                nodeCount = (Long) obj;
            }
            String entName = this.getEntityName();
            Delegator delegator = WidgetWorker.getDelegator(context);
            ModelEntity modelEntity = delegator.getModelEntity(entName);
            ModelField modelField = null;
            if (modelEntity.isField(countFieldName)) {
                modelField = modelEntity.getField(countFieldName);
            }
            if (nodeCount == null && modelField != null || this.modelTree.forceChildCheck) {
                getChildren(context);
                /*
                String id = (String)context.get(modelTree.getPkName());
                if (UtilValidate.isNotEmpty(id)) {
                    try {
                        int leafCount = ContentManagementWorker.updateStatsTopDown(delegator, id, UtilMisc.toList("SUB_CONTENT", "PUBLISH_LINK"));
                        GenericValue entity = delegator.findOne(entName, UtilMisc.toMap(modelTree.getPkName(), id), true);
                        obj = entity.get("childBranchCount");
                       if (obj != null)
                           nodeCount = (Long)obj;
                    } catch (GenericEntityException e) {
                        Debug.logError(e, module);
                       throw new RuntimeException(e.getMessage());
                    }
                }
                */
                nodeCount = Long.valueOf(subNodeValues.size());
                String pkName = this.getPkName(context);
                String id = null;
                if (!this.entryName.isEmpty()) {
                    id = UtilGenerics.<Map<String, String>> cast(context.get(this.entryName)).get(pkName);
                } else {
                    id = (String) context.get(pkName);
                }
                try {
                    if (id != null && modelEntity.getPksSize() == 1) {
                        GenericValue entity = EntityQuery.use(delegator).from(entName).where(pkName, id).queryOne();
                        if (modelEntity.isField("childBranchCount")) {
                            entity.put("childBranchCount", nodeCount);
                            entity.store();
                        }
                    }
                } catch (GenericEntityException e) {
                    Debug.logError(e, module);
                    throw new RuntimeException(e.getMessage());
                }
            } else if (nodeCount == null) {
                getChildren(context);
                if (subNodeValues != null) {
                    nodeCount = Long.valueOf(subNodeValues.size());
                }
            }
            if (nodeCount != null && nodeCount.intValue() > 0) {
                hasChildren = true;
            }
            return hasChildren;
        }

        public boolean isExpandCollapse() {
            boolean isExpCollapse = false;
            String rStyle = getRenderStyle();
            if (rStyle != null && rStyle.equals("expand-collapse"))
                isExpCollapse = true;
            return isExpCollapse;
        }

        public boolean isFollowTrail() {
            boolean isFollowTrail = false;
            String rStyle = getRenderStyle();
            if (rStyle != null && (rStyle.equals("follow-trail") || rStyle.equals("show-peers") || rStyle.equals("follow-trail"))) {
                isFollowTrail = true;
            }
            return isFollowTrail;
        }

        public boolean isRootNode() {
            return getName().equals(modelTree.getRootNodeName());
        }

        public void renderNodeString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer,
                int depth) throws IOException, GeneralException {
            boolean passed = true;
            if (this.condition != null) {
                if (!this.condition.getCondition().eval(context)) {
                    passed = false;
                }
            }
            //Debug.logInfo("in ModelMenu, name:" + this.getName(), module);
            if (passed) {
                List<String> currentNodeTrail = UtilGenerics.toList(context.get("currentNodeTrail"));
                context.put("processChildren", Boolean.TRUE);
                // this action will usually obtain the "current" entity
                ModelTreeAction.runSubActions(this.actions, context);
                String pkName = getPkName(context);
                String id = null;
                if (!this.entryName.isEmpty()) {
                    id = UtilGenerics.<Map<String, String>> cast(context.get(this.entryName)).get(pkName);
                } else {
                    id = (String) context.get(pkName);
                }
                currentNodeTrail.add(id);
                treeStringRenderer.renderNodeBegin(writer, context, this, depth);
                //if (Debug.infoOn()) Debug.logInfo(" context:" +
                // context.entrySet(), module);
                try {
                    String screenName = null;
                    if (!screenNameExdr.isEmpty())
                        screenName = screenNameExdr.expandString(context);
                    String screenLocation = null;
                    if (!screenLocationExdr.isEmpty())
                        screenLocation = screenLocationExdr.expandString(context);
                    if (screenName != null && screenLocation != null) {
                        ScreenStringRenderer screenStringRenderer = treeStringRenderer.getScreenStringRenderer(context);
                        ModelScreen modelScreen = ScreenFactory.getScreenFromLocation(screenLocation, screenName);
                        modelScreen.renderScreenString(writer, context, screenStringRenderer);
                    }
                    if (label != null) {
                        label.renderLabelString(writer, context, treeStringRenderer);
                    }
                    if (link != null) {
                        link.renderLinkString(writer, context, treeStringRenderer);
                    }
                    treeStringRenderer.renderLastElement(writer, context, this);
                    Boolean processChildren = (Boolean) context.get("processChildren");
                    //if (Debug.infoOn()) Debug.logInfo(" processChildren:" + processChildren, module);
                    if (processChildren.booleanValue()) {
                        List<Object[]> subNodeValues = getChildren(context);
                        int newDepth = depth + 1;
                        for (Object[] arr : subNodeValues) {
                            ModelNode node = (ModelNode) arr[0];
                            Map<String, Object> val = UtilGenerics.checkMap(arr[1]);
                            //GenericPK pk = val.getPrimaryKey();
                            //if (Debug.infoOn()) Debug.logInfo(" pk:" + pk,
                            // module);
                            String thisPkName = node.getPkName(context);
                            String thisEntityId = (String) val.get(thisPkName);
                            MapStack<String> newContext = MapStack.create(context);
                            newContext.push();
                            String nodeEntryName = node.getEntryName();
                            if (!nodeEntryName.isEmpty()) {
                                newContext.put(nodeEntryName, val);
                            } else {
                                newContext.putAll(val);
                            }
                            String targetEntityId = null;
                            List<String> targetNodeTrail = UtilGenerics.checkList(context.get("targetNodeTrail"));
                            if (newDepth < targetNodeTrail.size()) {
                                targetEntityId = targetNodeTrail.get(newDepth);
                            }
                            if ((targetEntityId != null && targetEntityId.equals(thisEntityId))
                                    || this.showPeers(newDepth, context)) {
                                node.renderNodeString(writer, newContext, treeStringRenderer, newDepth);
                            }
                        }
                    }
                } catch (ScreenRenderException e) {
                    String errMsg = "Error rendering included label with name [" + getName() + "] : " + e.toString();
                    Debug.logError(e, errMsg, module);
                    throw new RuntimeException(errMsg);
                } catch (SAXException e) {
                    String errMsg = "Error rendering included label with name [" + getName() + "] : " + e.toString();
                    Debug.logError(e, errMsg, module);
                    throw new RuntimeException(errMsg);
                } catch (ParserConfigurationException e3) {
                    String errMsg = "Error rendering included label with name [" + getName() + "] : " + e3.toString();
                    Debug.logError(e3, errMsg, module);
                    throw new RuntimeException(errMsg);
                } catch (IOException e2) {
                    String errMsg = "Error rendering included label with name [" + getName() + "] : " + e2.toString();
                    Debug.logError(e2, errMsg, module);
                    throw new RuntimeException(errMsg);
                }
                treeStringRenderer.renderNodeEnd(writer, context, this);
                int removeIdx = currentNodeTrail.size() - 1;
                if (removeIdx >= 0)
                    currentNodeTrail.remove(removeIdx);
            }
        }

        public boolean showPeers(int currentDepth, Map<String, Object> context) {
            int trailSize = 0;
            List<?> trail = UtilGenerics.checkList(context.get("targetNodeTrail"));
            int openDepth = modelTree.getOpenDepth();
            int postTrailOpenDepth = modelTree.getPostTrailOpenDepth();
            if (trail != null)
                trailSize = trail.size();

            boolean showPeers = false;
            String rStyle = getRenderStyle();
            if (rStyle == null) {
                showPeers = true;
            } else if (!isFollowTrail()) {
                showPeers = true;
            } else if ((currentDepth < trailSize) && (rStyle != null)
                    && (rStyle.equals("show-peers") || rStyle.equals("expand-collapse"))) {
                showPeers = true;
            } else if (openDepth >= currentDepth) {
                showPeers = true;
            } else {
                int depthAfterTrail = currentDepth - trailSize;
                if (depthAfterTrail >= 0 && depthAfterTrail <= postTrailOpenDepth)
                    showPeers = true;
            }
            return showPeers;
        }
        
        public List<ModelAction> getActions() {
            return actions;
        }

        public ModelTreeCondition getCondition() {
            return condition;
        }

        public Label getLabel() {
            return label;
        }

        public Link getLink() {
            return link;
        }

        public String getPkName() {
            return pkName;
        }

        public FlexibleStringExpander getScreenLocationExdr() {
            return screenLocationExdr;
        }

        public FlexibleStringExpander getScreenNameExdr() {
            return screenNameExdr;
        }

        public String getShareScope() {
            return shareScope;
        }

        public List<ModelSubNode> getSubNodeList() {
            return subNodeList;
        }

        public FlexibleStringExpander getWrapStyleExdr() {
            return wrapStyleExdr;
        }

        /**
         * Models the &lt;image&gt; element.
         * 
         * @see <code>widget-tree.xsd</code>
         */
        public static class Image {

            private final FlexibleStringExpander borderExdr;
            private final FlexibleStringExpander heightExdr;
            private final FlexibleStringExpander idExdr;
            private final FlexibleStringExpander srcExdr;
            private final FlexibleStringExpander styleExdr;
            private final String urlMode;
            private final FlexibleStringExpander widthExdr;

            public Image(Element imageElement) {
                this.borderExdr = FlexibleStringExpander
                        .getInstance(UtilXml.checkEmpty(imageElement.getAttribute("border"), "0"));
                this.heightExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("height"));
                this.idExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("id"));
                this.srcExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("src"));
                this.styleExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("style"));
                this.urlMode = UtilXml.checkEmpty(imageElement.getAttribute("url-mode"), "content");
                this.widthExdr = FlexibleStringExpander.getInstance(imageElement.getAttribute("width"));
            }

            public String getBorder(Map<String, Object> context) {
                return this.borderExdr.expandString(context);
            }

            public String getHeight(Map<String, Object> context) {
                return this.heightExdr.expandString(context);
            }

            public String getId(Map<String, Object> context) {
                return this.idExdr.expandString(context);
            }

            public String getSrc(Map<String, Object> context) {
                return this.srcExdr.expandString(context);
            }

            public String getStyle(Map<String, Object> context) {
                return this.styleExdr.expandString(context);
            }

            public String getUrlMode() {
                return this.urlMode;
            }

            public String getWidth(Map<String, Object> context) {
                return this.widthExdr.expandString(context);
            }

            public void renderImageString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer) {
                try {
                    treeStringRenderer.renderImage(writer, context, this);
                } catch (IOException e) {
                    String errMsg = "Error rendering image with id [" + getId(context) + "]: " + e.toString();
                    Debug.logError(e, errMsg, module);
                    throw new RuntimeException(errMsg);
                }
            }
        }

        /**
         * Models the &lt;label&gt; element.
         * 
         * @see <code>widget-tree.xsd</code>
         */
        public static final class Label {
            private final FlexibleStringExpander idExdr;
            private final FlexibleStringExpander styleExdr;
            private final FlexibleStringExpander textExdr;

            public Label(Element labelElement) {
                String textAttr = labelElement.getAttribute("text");
                String pcdata = UtilXml.checkEmpty(UtilXml.elementValue(labelElement), "");
                this.textExdr = FlexibleStringExpander.getInstance(textAttr + pcdata);
                this.idExdr = FlexibleStringExpander.getInstance(labelElement.getAttribute("id"));
                this.styleExdr = FlexibleStringExpander.getInstance(labelElement.getAttribute("style"));
            }

            public String getId(Map<String, Object> context) {
                return this.idExdr.expandString(context);
            }

            public String getStyle(Map<String, Object> context) {
                return this.styleExdr.expandString(context);
            }

            public String getText(Map<String, Object> context) {
                String text = this.textExdr.expandString(context);
                // FIXME: Encoding should be done by the renderer, not by the model.
                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
                if (simpleEncoder != null) {
                    text = simpleEncoder.encode(text);
                }
                return text;
            }

            public void renderLabelString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer) {
                try {
                    treeStringRenderer.renderLabel(writer, context, this);
                } catch (IOException e) {
                    String errMsg = "Error rendering label with id [" + getId(context) + "]: " + e.toString();
                    Debug.logError(e, errMsg, module);
                    throw new RuntimeException(errMsg);
                }
            }

            public FlexibleStringExpander getIdExdr() {
                return idExdr;
            }

            public FlexibleStringExpander getStyleExdr() {
                return styleExdr;
            }

            public FlexibleStringExpander getTextExdr() {
                return textExdr;
            }
        }

        /**
         * Models the &lt;link&gt; element.
         * 
         * @see <code>widget-tree.xsd</code>
         */
        public static class Link {
            private final boolean encode;
            private final boolean fullPath;
            private final FlexibleStringExpander idExdr;
            private final Image image;
            private final String linkType;
            private final FlexibleStringExpander nameExdr;
            private final List<Parameter> parameterList;
            private final FlexibleStringExpander prefixExdr;
            private final boolean secure;
            private final FlexibleStringExpander styleExdr;
            private final FlexibleStringExpander targetExdr;
            private final FlexibleStringExpander targetWindowExdr;
            private final FlexibleStringExpander textExdr;
            private final FlexibleStringExpander titleExdr;
            private final String urlMode;

            public Link(Element linkElement) {
                this.encode = "true".equals(linkElement.getAttribute("encode"));
                this.fullPath = "true".equals(linkElement.getAttribute("full-path"));
                this.idExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("id"));
                Element imageElement = UtilXml.firstChildElement(linkElement, "image");
                if (imageElement != null) {
                    this.image = new Image(imageElement);
                } else {
                    this.image = null;
                }
                this.linkType = linkElement.getAttribute("link-type");
                this.nameExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("name"));
                List<? extends Element> parameterElementList = UtilXml.childElementList(linkElement, "parameter");
                if (!parameterElementList.isEmpty()) {
                    List<Parameter> parameterList = new ArrayList<Parameter>(parameterElementList.size());
                    for (Element parameterElement : parameterElementList) {
                        parameterList.add(new Parameter(parameterElement));
                    }
                    this.parameterList = Collections.unmodifiableList(parameterList);
                } else {
                    this.parameterList = Collections.emptyList();
                }
                this.prefixExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("prefix"));
                this.secure = "true".equals(linkElement.getAttribute("secure"));
                this.styleExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("style"));
                this.targetExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("target"));
                this.targetWindowExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("target-window"));
                this.textExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("text"));
                this.titleExdr = FlexibleStringExpander.getInstance(linkElement.getAttribute("title"));
                this.urlMode = UtilXml.checkEmpty(linkElement.getAttribute("link-type"), "intra-app");
            }

            // FIXME: Using a widget model in this way is an ugly hack.
            public Link(String style, String target, String text) {
                this.encode = false;
                this.fullPath = false;
                this.idExdr = FlexibleStringExpander.getInstance("");
                this.image = null;
                this.linkType = "";
                this.nameExdr = FlexibleStringExpander.getInstance("");
                this.parameterList = Collections.emptyList();
                this.prefixExdr = FlexibleStringExpander.getInstance("");
                this.secure = false;
                this.styleExdr = FlexibleStringExpander.getInstance(style);
                this.targetExdr = FlexibleStringExpander.getInstance(target);
                this.targetWindowExdr = FlexibleStringExpander.getInstance("");
                this.textExdr = FlexibleStringExpander.getInstance(text);
                this.titleExdr = FlexibleStringExpander.getInstance("");
                this.urlMode = "intra-app";
            }

            public boolean getEncode() {
                return this.encode;
            }

            public boolean getFullPath() {
                return this.fullPath;
            }

            public String getId(Map<String, Object> context) {
                return this.idExdr.expandString(context);
            }

            public Image getImage() {
                return this.image;
            }

            public String getLinkType() {
                return this.linkType;
            }

            public String getName(Map<String, Object> context) {
                return this.nameExdr.expandString(context);
            }

            public Map<String, String> getParameterMap(Map<String, Object> context) {
                Map<String, String> fullParameterMap = new HashMap<String, String>();
                /* leaving this here... may want to add it at some point like the hyperlink element:
                Map<String, String> addlParamMap = this.parametersMapAcsr.get(context);
                if (addlParamMap != null) {
                    fullParameterMap.putAll(addlParamMap);
                }
                */
                for (CommonWidgetModels.Parameter parameter : this.parameterList) {
                    fullParameterMap.put(parameter.getName(), parameter.getValue(context));
                }
                return fullParameterMap;
            }

            public String getPrefix(Map<String, Object> context) {
                return this.prefixExdr.expandString(context);
            }

            public boolean getSecure() {
                return this.secure;
            }

            public String getStyle(Map<String, Object> context) {
                return this.styleExdr.expandString(context);
            }

            public String getTarget(Map<String, Object> context) {
                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
                if (simpleEncoder != null) {
                    return this.targetExdr.expandString(UtilCodec.HtmlEncodingMapWrapper.getHtmlEncodingMapWrapper(context,
                            simpleEncoder));
                } else {
                    return this.targetExdr.expandString(context);
                }
            }

            public String getTargetWindow(Map<String, Object> context) {
                return this.targetWindowExdr.expandString(context);
            }

            public String getText(Map<String, Object> context) {
                String text = this.textExdr.expandString(context);
                // FIXME: Encoding should be done by the renderer, not by the model.
                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
                if (simpleEncoder != null) {
                    text = simpleEncoder.encode(text);
                }
                return text;
            }

            public String getTitle(Map<String, Object> context) {
                String title = this.titleExdr.expandString(context);
                // FIXME: Encoding should be done by the renderer, not by the model.
                UtilCodec.SimpleEncoder simpleEncoder = (UtilCodec.SimpleEncoder) context.get("simpleEncoder");
                if (simpleEncoder != null) {
                    title = simpleEncoder.encode(title);
                }
                return title;
            }

            public String getUrlMode() {
                return this.urlMode;
            }

            public void renderLinkString(Appendable writer, Map<String, Object> context, TreeStringRenderer treeStringRenderer) {
                try {
                    treeStringRenderer.renderLink(writer, context, this);
                } catch (IOException e) {
                    String errMsg = "Error rendering link with id [" + getId(context) + "]: " + e.toString();
                    Debug.logError(e, errMsg, module);
                    throw new RuntimeException(errMsg);
                }
            }

            public FlexibleStringExpander getIdExdr() {
                return idExdr;
            }

            public FlexibleStringExpander getNameExdr() {
                return nameExdr;
            }

            public List<Parameter> getParameterList() {
                return parameterList;
            }

            public FlexibleStringExpander getPrefixExdr() {
                return prefixExdr;
            }

            public FlexibleStringExpander getStyleExdr() {
                return styleExdr;
            }

            public FlexibleStringExpander getTargetExdr() {
                return targetExdr;
            }

            public FlexibleStringExpander getTargetWindowExdr() {
                return targetWindowExdr;
            }

            public FlexibleStringExpander getTextExdr() {
                return textExdr;
            }

            public FlexibleStringExpander getTitleExdr() {
                return titleExdr;
            }
        }

        /**
         * Models the &lt;sub-node&gt; element.
         * 
         * @see <code>widget-tree.xsd</code>
         */
        public static class ModelSubNode extends ModelWidget {

            private final List<ModelAction> actions;
            private final FlexibleStringExpander nodeNameExdr;
            private final ModelNode rootNode;
            private final String iteratorKey;

            public ModelSubNode(Element subNodeElement, ModelNode modelNode) {
                super(subNodeElement);
                this.rootNode = modelNode;
                this.nodeNameExdr = FlexibleStringExpander.getInstance(subNodeElement.getAttribute("node-name"));
                ArrayList<ModelAction> actions = new ArrayList<ModelAction>();
                // FIXME: Validate child elements, should be only one of actions, entity-and, entity-condition, service, script.
                Element actionsElement = UtilXml.firstChildElement(subNodeElement, "actions");
                if (actionsElement != null) {
                    actions.addAll(ModelTreeAction.readSubNodeActions(this, actionsElement));
                }
                Element actionElement = UtilXml.firstChildElement(subNodeElement, "entity-and");
                if (actionElement != null) {
                    actions.add(new ModelTreeAction.EntityAnd(this, actionElement));
                }
                actionElement = UtilXml.firstChildElement(subNodeElement, "service");
                if (actionElement != null) {
                    actions.add(new ModelTreeAction.Service(this, actionElement));
                }
                actionElement = UtilXml.firstChildElement(subNodeElement, "entity-condition");
                if (actionElement != null) {
                    actions.add(new ModelTreeAction.EntityCondition(this, actionElement));
                }
                actionElement = UtilXml.firstChildElement(subNodeElement, "script");
                if (actionElement != null) {
                    actions.add(new ModelTreeAction.Script(this, actionElement));
                }
                actions.trimToSize();
                this.actions = Collections.unmodifiableList(actions);
                this.iteratorKey = this.rootNode.getName().concat(".").concat(this.nodeNameExdr.getOriginal())
                        .concat(".ITERATOR");
            }

            @Override
            public void accept(ModelWidgetVisitor visitor) throws Exception {
                visitor.visit(this);
            }

            public List<ModelAction> getActions() {
                return actions;
            }

            @SuppressWarnings("unchecked")
            public ListIterator<? extends Map<String, ? extends Object>> getListIterator(Map<String, Object> context) {
                return (ListIterator<? extends Map<String, ? extends Object>>) context.get(this.iteratorKey);
            }

            public ModelTree.ModelNode getNode() {
                return this.rootNode;
            }

            public String getNodeName(Map<String, Object> context) {
                return this.nodeNameExdr.expandString(context);
            }

            public FlexibleStringExpander getNodeNameExdr() {
                return nodeNameExdr;
            }

            public void setListIterator(ListIterator<? extends Map<String, ? extends Object>> iter, Map<String, Object> context) {
                context.put(this.iteratorKey, iter);
            }
        }
    }
}
