package Templates.API_Support.Nodes_API;

import org.openide.actions.*;
import org.openide.nodes.*;
import org.openide.util.HelpCtx;
import org.openide.util.NbBundle;
import org.openide.util.actions.SystemAction;

/**
 * A simple node with no children.
 * Often used in conjunction with some kind of underlying data model, where
 * each node represents an element in that model. In this case, you should see
 * the Container Node template which will permit you to create a whole tree of
 * such nodes with the proper behavior.
 * @author __USER__
 */
public class __Sample_leaf__Node extends AbstractNode {

    // will frequently accept an element from some data model in the constructor:
    public __Sample_leaf__Node() {
        super(Children.LEAF);
        setIconBase("__PACKAGE_AND_NAME_SLASHES$Node$NodeIcon$MyIcon__");
        // Whatever is most relevant to a user:
        setDefaultAction(SystemAction.get(PropertiesAction.class));
        // Set FeatureDescriptor stuff:
        setName("preferablyUniqueNameForThisNodeAmongSiblings"); // or, super.setName if needed
        setDisplayName(NbBundle.getMessage(__NAME__.class, "LBL_node"));
        setShortDescription(NbBundle.getMessage(__NAME__.class, "HINT_node"));
        // Add cookies, e.g.:
        /*
        getCookieSet().add(new OpenCookie() {
		public void open() {
		    // Open something useful...
                    // will typically use the data model somehow
		}
	    });
        */
        // If this node represents an element in a data model of some sort, consider
        // creating your own cookie which captures the existence of that underlying data,
        // and add it to the cookie set. Then you can write actions sensitive to that cookie,
        // and they will not need to directly refer to this node class - only to the cookie
        // and the data model.
    }

    // Create the popup menu:
    protected SystemAction[] createActions() {
        return new SystemAction[] {
                   // SystemAction.get(MyFavoriteAction.class),
                   // null,                     // separator
                   /* according to what it can do:
                   SystemAction.get(CutAction.class),
                   SystemAction.get(CopyAction.class),
                   null,
                   SystemAction.get(DeleteAction.class),
                   SystemAction.get(RenameAction.class),
                   null,
                   */
                   SystemAction.get(ToolsAction.class),
                   null,
                   SystemAction.get(PropertiesAction.class),
               };
    }

    public HelpCtx getHelpCtx() {
        return HelpCtx.DEFAULT_HELP;
        // When you have help, change to:
        // return new HelpCtx(__NAME__.class);
    }

    // RECOMMENDED - handle cloning specially (so as not to invoke the overhead of FilterNode):
    /*
    public Node cloneNode() {
	// Try to pass in similar constructor params to what you originally got,
        // typically meaning passing in the same data model element:
	return new __NAME__();
    }
    */

    // Create a property sheet:
    /*
    protected Sheet createSheet() {
	Sheet sheet = super.createSheet();
	// Make sure there is a "Properties" set:
	Sheet.Set props = sheet.get(Sheet.PROPERTIES); // get by name, not display name
	if (props == null) {
	    props = Sheet.createPropertiesSet();
	    sheet.put(props);
	}
        // typically the property will be constructed based on some underlying data model:
	props.put(new MyProp(someParams));
        return sheet;
    }
    */

    // Handle renaming:
    /*
    public boolean canRename() {
	return true;
    }
    public void setName(String nue) {
        // Typically implemented by changing the name of an element from an underlying
        // data model. This node class should be listening to changes in the name of the
        // element and calling super.setName when it notices any (or better, override getName
        // and perhaps getDisplayName and call fireNameChange).
        // For example, if there is an instance field
        // private final MyDataElement data;
        // then you might write this method as:
        // data.setID(nue);
        // where you would also have:
        // public String getName() {return data.getID();}
        // and in the constructor, if __NAME__ implements ModelListener:
        // data.addModelListener((ModelListener)WeakListener.create(ModelListener.class, this, data));
        // where the interface is implemented as:
        // public void modelChanged(ModelEvent ev) {fireNameChange(null, null);}
    }
    */

    // Handle deleting:
    /*
    public boolean canDestroy() {
	return true;
    }
    public void destroy() throws IOException {
        // Typically implemented by removing an element from an underlying data model.
        // For example, if there is an instance field
        // private final MyDataElement data;
        // then you might write this method as:
        // data.getContainingModel().removeElement(data);
        // The parent container children should be listening to the model, notice
        // the removal, set a new key list without this data element, and thus
        // remove this node from its children list.
    }
    */

    // Handle copying and cutting specially:
    /*
    public boolean canCopy() {
	return true;
    }
    public boolean canCut() {
	return true;
    }
    public Transferable clipboardCopy() {
	// Add to, do not replace, the default node copy flavor:
	ExTransferable et = ExTransferable.create(super.clipboardCopy());
	et.put(new ExTransferable.Single(DataFlavor.stringFlavor) {
		protected Object getData() {
                    // just an example:
		    return __NAME__.this.getDisplayName();
                    // more commonly, will use some underlying data model
		}
	    });
	return et;
    }
    public Transferable clipboardCut() {
	// Add to, do not replace, the default node cut flavor:
	ExTransferable et = ExTransferable.create(super.clipboardCut());
	// This is not so useful because this node will not be destroyed afterwards
	// (it is up to the paste type to decide whether to remove the "original",
	// and it is not safe to assume that getData will only be called once):
	et.put(new ExTransferable.Single(DataFlavor.stringFlavor) {
		protected Object getData() {
                    // just an example:
		    return __NAME__.this.getDisplayName();
                    // more commonly, will use some underlying data model
		}
	    });
	return et;
    }
    */

    // Permit user to customize whole node at once (instead of per-property):
    /*
    public boolean hasCustomizer() {
	return true;
    }
    public Component getCustomizer() {
        // more commonly, will pass in underlying data:
	return new MyCustomizingPanel(this);
    }
    */

}
