/*
 * 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 http://www.netbeans.org/cddl.html
 * or http://www.netbeans.org/cddl.txt.
 * 
 * When distributing Covered Code, include this CDDL Header Notice in each file
 * and include the License file at http://www.netbeans.org/cddl.txt.
 * If applicable, add the following below the CDDL Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 * 
 * The Original Software is NetBeans. The Initial Developer of the Original
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.core.execution;

import java.util.Collection;
import java.util.Collections;
import java.util.ResourceBundle;
import org.openide.util.HelpCtx;
import org.openide.nodes.*;
import org.openide.util.NbBundle;

/** Node which represents list of running processes.
*
* @author Ales Novak, Jesse Glick
*/
public final class ProcessNode extends AbstractNode {

    static final ResourceBundle getBundle() {
        return NbBundle.getBundle(ProcessNode.class);
    }

    /** Reference to an instance of this class */
    private static Node processNode;
    
    /**
    *  @param parent is a parent node
    */
    private ProcessNode () {
        super(new ProcessChildren());
        setIconBase("org/netbeans/core/resources/processes"); // NOI18N
        setName(getBundle().getString("Processes"));
        setShortDescription(getBundle().getString("Processes_HINT"));
    }

    public HelpCtx getHelpCtx () {
        return new HelpCtx (ProcessNode.class);
    }

    public Node.Handle getHandle () {
        return new ProcessHandle();
    }

    static final class ProcessHandle implements Node.Handle {
        static final long serialVersionUID =-6979883764640743928L;

        public Node getNode () {
            return getExecutionNode();
        }
    }

    /**
     * Get the default instance of the "Execution" node.
     * It is a singleton so be sure to clone it before adding to any parents.
     * @return the execution node
     */
    public static Node getExecutionNode() {
        if (processNode == null) {
            processNode = new ProcessNode();
        }
        return processNode;
    }

    private static final class ProcessChildren extends Children.Keys/*<DefaultSysProcess>*/ implements ExecutionListener {
        
        public ProcessChildren() {}
        
        /** key representing no processes running */
        private static final Object KEY_NONE = "NONE"; // NOI18N
        
        private void updateKeys() {
            Collection c = ExecutionEngine.getExecutionEngine().getRunningTasks();
            setKeys(c.isEmpty() ? Collections.singleton(KEY_NONE) : c);
        }
        
        protected void addNotify() {
            super.addNotify();
            updateKeys();
            ExecutionEngine.getExecutionEngine().addExecutionListener(this);
        }
        
        protected void removeNotify() {
            ExecutionEngine.getExecutionEngine().removeExecutionListener(this);
            setKeys(Collections.EMPTY_SET);
            super.removeNotify();
        }

        protected Node[] createNodes(Object key) {
            if (key == KEY_NONE) {
                AbstractNode n = new AbstractNode(Children.LEAF);
                n.setName(getBundle().getString("CTL_No_processes"));
                n.setShortDescription(getBundle().getString("HINT_No_processes"));
                n.setIconBase("org/netbeans/core/resources/noProcesses"); // NOI18N
                return new Node[] {n};
            } else {
                return new Node[] {new ProcessNodeItem((DefaultSysProcess)key)};
            }
        }
        
        public void finishedExecution(ExecutionEvent ev) {
            updateKeys();
        }
        
        public void startedExecution(ExecutionEvent ev) {
            updateKeys();
        }
        
    }
    
}
