/*
 * The contents of this file are subject to the terms 
 * of the Common Development and Distribution License 
 * (the License).  You may not use this file except in
 * compliance with the License.
 * 
 * You can obtain a copy of the license at 
 * https://glassfish.dev.java.net/public/CDDLv1.0.html or
 * glassfish/bootstrap/legal/CDDLv1.0.txt.
 * See the License for the specific language governing 
 * permissions and limitations under the License.
 * 
 * When distributing Covered Code, include this CDDL 
 * Header Notice in each file and include the License file 
 * at glassfish/bootstrap/legal/CDDLv1.0.txt.  
 * If applicable, add the following below the CDDL Header, 
 * with the fields enclosed by brackets [] replaced by
 * you own identifying information: 
 * "Portions Copyrighted [year] [name of copyright owner]"
 * 
 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 */

/*
 * CommonHandlers.java
 *
 */

package com.sun.enterprise.tools.admingui.handlers;

import java.util.ArrayList;
import javax.servlet.http.HttpServletRequest;
import com.iplanet.jato.RequestContext;
import com.iplanet.jato.RequestContextImpl;
import com.iplanet.jato.RequestManager;
import com.iplanet.jato.view.ViewBean;

import com.sun.enterprise.tools.admingui.util.Util;
import com.sun.enterprise.tools.admingui.tree.IndexTreeNode;
import com.sun.enterprise.tools.admingui.tree.IndexTreeModelImpl;
import com.sun.enterprise.tools.admingui.tree.IndexTreeModel;

import com.sun.enterprise.tools.guiframework.view.HandlerContext;
import com.sun.enterprise.tools.guiframework.exception.FrameworkException;

/**
 *
 */
public class TreeHandlers {

    public void refreshTreeNode(RequestContext ctx, HandlerContext handlerCtx) {
        ctx.getRequest().setAttribute("refreshTree", new Boolean("true"));
        Util.getSelectedNode().setRefresh(true);
    }

    public void refreshTreeNodeById(RequestContext ctx, HandlerContext handlerCtx) {
        ctx.getRequest().setAttribute("refreshTree", new Boolean("true"));
        String nodeId = (String)handlerCtx.getInputValue("nodeId");
        IndexTreeNode node = 
            Util.getCurrentTreeModel().getNodeByUniqueID(nodeId, null, null);
        if (node != null)
            node.setRefresh(true);
    }

    public void refreshParentNode(RequestContext ctx, HandlerContext handlerCtx) {
        ctx.getRequest().setAttribute("refreshTree", new Boolean("true"));
        Util.getSelectedNode().getParent().setRefresh(true);
    }

    public void openTreeNode(RequestContext ctx, HandlerContext handlerCtx) {
        Util.getSelectedNode().openNode(ctx);
    }
    
    public void getNumberOfChildNodes(RequestContext ctx, HandlerContext handlerCtx) {
        int count = Util.getSelectedNode().getChildren().size();
        handlerCtx.setOutputValue("count", new Integer(count));
    }
    
    public void getAttributeFromTree(RequestContext ctx, HandlerContext handlerCtx) {
        HttpServletRequest req = ctx.getRequest();
        String attrName = (String)handlerCtx.getInputValue("attrName");
        boolean lookInHierarchy = true;
        Boolean look = (Boolean)handlerCtx.getInputValue("lookInHierarchy");
        if (look != null)
            lookInHierarchy = look.booleanValue();
        Object attrValue = Util.getSelectedNode().getAttribute(attrName, lookInHierarchy);
        handlerCtx.setOutputValue(VALUE, attrValue);
    }

    public void changeTreeModel(RequestContext ctx, HandlerContext handlerCtx) {
        Util.setCurrentTreeModelType(ctx, (String)handlerCtx.getInputValue("modelName"));
        // set a flag to make the tree view refresh the right side with a new page.
        ctx.getRequest().setAttribute("refreshRightSide", new Boolean("true"));
    }

    public void getTreeModelType(RequestContext ctx, HandlerContext handlerCtx) {
        handlerCtx.setOutputValue(VALUE, Util.getCurrentTreeModelType(ctx));
    }
    
    // This method needs to be called when a child node is selected from the right
    // hand frame. This is required to make the tree highlighting and the breadcrumb
    // track properly.
    public void moveSelectedNode(RequestContext ctx, HandlerContext handlerCtx) {
        String childName = (String)handlerCtx.getInputValue("editKeyValue");
        if (childName == null) {
	    throw new FrameworkException("\"editKeyValue\" not defined!",
		null, handlerCtx.getView());
        }
        IndexTreeNode selectedNode = Util.getSelectedNode();
        IndexTreeNode childNode = selectedNode.getChild(childName);
        if (childNode == null) {
            if (Util.isLoggableFINE()) {
                Util.logFINE("Child node ("+childName+") not found!");
            }
            handlerCtx.setOutputValue(OBJECT_NAME, null);
            return;
	    //throw new FrameworkException("Child node ("+childName+
            //	") not found!", null, handlerCtx.getView());
        }
        Util.setSelectedNode(childNode);
        handlerCtx.setOutputValue(OBJECT_NAME, childNode.getAttribute(OBJECT_NAME, false));
    }
    
    public void warpToNode(RequestContext ctx, HandlerContext handlerCtx) {
        ArrayList parentIDs = (ArrayList)handlerCtx.getInputValue("parentID");
        if (parentIDs == null) {
	    throw new FrameworkException("warpToNode: \"parentID\" not defined!",
		null, handlerCtx.getView());
        }
        String childName = (String)handlerCtx.getInputValue("childName");
        
        IndexTreeNode childNode = null;
        for (int i=0; i<parentIDs.size(); i++) {
            String parentID = (String)parentIDs.get(i);
            childNode = 
                Util.getCurrentTreeModel().getNodeByUniqueID(parentID, childName, null);
            if (childNode != null)
                break;
        }
        if (childNode == null)
            return;
        
        String grandChildId = (String)handlerCtx.getInputValue("grandChildId");
        if (grandChildId != null) {
            IndexTreeNode node = Util.getCurrentTreeModel().
                getNodeByUniqueID(grandChildId, null, childNode);
            if (node != null)
		childNode = node;
        }
        
        IndexTreeNode parentNode = childNode.getParent();
        if (parentNode != null) { // parentNode is null if childNode is root    
            parentNode.setRefresh(true);
            parentNode.openNode(ctx);
        }
        Util.setSelectedNode(childNode);
        handlerCtx.setOutputValue(OBJECT_NAME, childNode.getAttribute(OBJECT_NAME, false));
    }

    // Typically called for a back button on a page.
    public void moveSelectedNodeToParent(RequestContext ctx, HandlerContext handlerCtx) {
        IndexTreeNode selectedNode = Util.getSelectedNode();
        IndexTreeNode parent = selectedNode.getParent();
        Util.setSelectedNode(parent);
        if (parent != null)
            handlerCtx.setOutputValue(OBJECT_NAME, parent.getAttribute(OBJECT_NAME, false));
        else
            // should never happen
            handlerCtx.setOutputValue(OBJECT_NAME, null);
    }
    
    // This method is used to set the current node of the tree to the first node
    // under the root.  This is required for the tree highlighting and bread 
    // crumb to work properly.  It needs to be called only once at begin display
    // of the TopFrameSet
    public void initializeCurrentNode(RequestContext ctx, HandlerContext handlerCtx) {
        IndexTreeModel model = Util.getCurrentTreeModel();
        IndexTreeNode root = model.getRoot();
        if (root != null) {
            model.setCurrentNode(root);
            Util.setSelectedNode(root);
        }
    }

    /**
     * This procedure provides a quick check to make sure the tree view is 
     * showing the correct number of nodes. This method should be called
     * when filling the table. An attribute will have the objects which are
     * about to be loaded in the table. A check of the correct counts is made.
     * If there is a mismatch in the counts, the tree will be refreashed.
     */
    public void syncTreeView(RequestContext ctx, HandlerContext handlerCtx) {
        Object[] keys = (Object[])handlerCtx.getInputValue("keys");
        if (keys == null)
            return;
        
        IndexTreeNode node = Util.getSelectedNode();
        if (node == null) 
            return;
        
        if (node.getChildren().size() != keys.length) {
            ctx.getRequest().setAttribute("refreshTree", new Boolean("true"));
            node.setRefresh(true);
        }
    }
    
    public static final String VALUE = "value";
    public static final String OBJECT_NAME = "objectName";
}
