/* -------------------------------------------------------------------------- *
 * OpenSim: OneFrameNode.java                                                 *
 * -------------------------------------------------------------------------- *
 * OpenSim is a toolkit for musculoskeletal modeling and simulation,          *
 * developed as an open source project by a worldwide community. Development  *
 * and support is coordinated from Stanford University, with funding from the *
 * U.S. NIH and DARPA. See http://opensim.stanford.edu and the README file    *
 * for more information including specific grant numbers.                     *
 *                                                                            *
 * Copyright (c) 2005-2017 Stanford University and the Authors                *
 * Author(s): Ayman Habib                                                     *
 *                                                                            *
 * Licensed 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.                                             *
 * -------------------------------------------------------------------------- */
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package org.opensim.view.nodes;

import java.awt.Image;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;
import javax.swing.ImageIcon;
import javax.swing.Action;
import org.openide.nodes.Children;
import org.openide.nodes.Node;
import org.openide.util.NbBundle;
import org.opensim.modeling.Frame;
import org.opensim.modeling.Geometry;
import org.opensim.view.FrameToggleVisibilityAction;

/**
 *
 * @author Ayman
 */
public class OneFrameNode extends OneModelComponentNode {
   private static ResourceBundle bundle = NbBundle.getBundle(OneFrameNode.class);
   Frame frame;
    public OneFrameNode(Frame comp) {
        super(comp);
        frame = comp;
        setShortDescription(bundle.getString("HINT_FrameNode"));
        createGeometryNodes();
    }
   
    protected final void createGeometryNodes() {
        
        int geomSize = frame.getPropertyByName("attached_geometry").size();
        // Create node for geometry
        Children children = getChildren();
        for (int g = 0; g < geomSize; g++) {
            Geometry oneG = frame.get_attached_geometry(g);
            OneGeometryNode node = new OneGeometryNode(oneG);
            Node[] arrNodes = new Node[1];
            arrNodes[0] = node;
            children.add(arrNodes);
        }
    }
    
   @Override
    public Node cloneNode() {
        return new OneFrameNode((Frame)getOpenSimObject());
    }
    /**
     * Icon for the body node 
     **/
   @Override
    public Image getIcon(int i) {
        URL imageURL = this.getClass().getResource("/org/opensim/view/nodes/icons/body.png");
        if (imageURL != null) {
            return new ImageIcon(imageURL, "Frame").getImage();
        } else {
            return null;
        }
    }

   @Override
    public Image getOpenedIcon(int i) {
        return getIcon(i);
    }
    
   @Override
    public Action[] getActions(boolean b) {
        Action[] superActions = (Action[]) super.getActions(b);
        // Arrays are fixed size, onvert to a List
        List<Action> actions = java.util.Arrays.asList(superActions);
        // Create new Array of proper size
        Action[] retActions = new Action[actions.size() + 1];
        actions.toArray(retActions);
        try {
            // append new command to the end of the list of actions
            retActions[actions.size()] = (FrameToggleVisibilityAction) FrameToggleVisibilityAction.findObject(
                    (Class) Class.forName("org.opensim.view.FrameToggleVisibilityAction"), true);
        } catch (ClassNotFoundException ex) {
            ex.printStackTrace();
        }
        return retActions;
    }  
}

@@ -2226,24 +2226,154 @@
 l.NbBundle;%0A
+import org.opensim.modeling.Component;%0Aimport org.opensim.modeling.ComponentIterator;%0Aimport org.opensim.modeling.ComponentsList;%0A
 import org.o
@@ -2395,16 +2395,16 @@
 .Frame;%0A
-
 import o
@@ -2911,24 +2911,812 @@
 ) %7B%0A        
+// attached_geometry doesn't reach geometry mounted on %0A%09%09// offset frames, use iterator instead%0A%09%09// Caveat if nested bodies or components have geometry %0A%09%09// it may appear multiple times%0A        ComponentsList compList = frame.getComponentsList();%0A        ComponentIterator compIter = compList.begin();%0A        Children children = getChildren();%0A        while (!compIter.equals(compList.end())) %7B%0A            Component comp = compIter.__deref__();%0A            Geometry oneG = Geometry.safeDownCast(comp);%0A            if (oneG!=null)%7B%0A                OneGeometryNode node = new OneGeometryNode(oneG);%0A                Node%5B%5D arrNodes = new Node%5B1%5D;%0A                arrNodes%5B0%5D = node;%0A                children.add(arrNodes);%0A            %7D%0A            compIter.next();%0A        %7D%0A        /*
 %0A        int
@@ -4129,32 +4129,32 @@
 .add(arrNodes);%0A
-
         %7D%0A    %7D%0A
@@ -4142,24 +4142,26 @@
 );%0A        %7D
+*/
 %0A    %7D%0A    %0A

Use iterator for components under Frame rather than attached_gometry to account for geometry anchored to offset_frames