/*
 * NewMarkerAction.java
 *
 * Created on June 9, 2008, 3:42 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */
package org.opensim.view.markerEditor;

import java.awt.event.ActionEvent;
import java.util.Vector;
import javax.swing.AbstractAction;
import javax.swing.undo.AbstractUndoableEdit;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import org.openide.nodes.Node;
import org.openide.util.NbBundle;
import org.opensim.modeling.Body;
import org.opensim.modeling.Marker;
import org.opensim.modeling.MarkerSet;
import org.opensim.modeling.Model;
import org.opensim.modeling.OpenSimObject;
import org.opensim.modeling.Vec3;
import org.opensim.view.ExplorerTopComponent;
import org.opensim.view.ObjectsAddedEvent;
import org.opensim.view.nodes.MarkersNode;
import org.opensim.view.pub.OpenSimDB;
import org.opensim.view.pub.ViewDB;

/**
 *
 * @author Ayman Habib
 */
public class NewMarkerAction extends AbstractAction {

   /** Creates a new instance of NewMarkerAction */
   public NewMarkerAction() {
      super(NbBundle.getMessage(NewMarkerAction.class, "CTL_NewMarkerAction"));
   }

   public void actionPerformed(ActionEvent evt) {
        Node[] selected = ExplorerTopComponent.findInstance().getExplorerManager().getSelectedNodes();
        // One MarkersNode must have been selected otherwise bail
        if (selected.length != 1 || !(selected[0] instanceof MarkersNode)) {
            return;
   }
        MarkersNode markersNode = (MarkersNode) selected[0];
        Model model = markersNode.getModelForNode();
        Vec3 offset = new Vec3(0.11, 0.22, 0.33);
        MarkerSet markerset = model.getMarkerSet();
        Body body = model.getBodySet().get(0);
        if (body == null) {
            return;
        }
        String newMarkerName = makeUniqueMarkerName(markerset);
        final Marker marker = markerset.addMarker(newMarkerName, offset, body);
        addMarker(marker, true);
    }

    public void addMarker(final Marker marker, boolean supportUndo) {
        // Update the marker name list in the ViewDB.
        final String saveMarkerName = marker.getName();
        final String saveBodyName = marker.getFrameName();
        final Vec3 saveMarkerOffset = marker.get_location();
        final Model model = marker.getModel();
        OpenSimDB.getInstance().getModelGuiElements(model).updateMarkerNames();

        Vector<OpenSimObject> objs = new Vector<OpenSimObject>(1);
        objs.add(marker);
        ObjectsAddedEvent evnt = new ObjectsAddedEvent(this, model, objs);
        OpenSimDB.getInstance().setChanged();
        OpenSimDB.getInstance().notifyObservers(evnt);
        // undo support
        if (supportUndo) {
            AbstractUndoableEdit auEdit = new AbstractUndoableEdit() {

                public void undo() throws CannotUndoException {
                    super.undo();
                    Marker toDelete = model.getMarkerSet().get(saveMarkerName);
                    OneMarkerDeleteAction.deleteMarker(toDelete, false);
                }

                public void redo() throws CannotRedoException {
                    super.redo();
                    Marker newMarker = model.getMarkerSet().addMarker(saveMarkerName, saveMarkerOffset, model.getBodySet().get(saveBodyName));
                    addMarker(newMarker, true);
                }
                @Override
                public String getRedoPresentationName() {
                    return "Redo new marker";
                }
                @Override
                public String getUndoPresentationName() {
                    return "Undo new marker";
                }
            };
            ExplorerTopComponent.addUndoableEdit(auEdit);
        }
    }

    private String makeUniqueMarkerName(MarkerSet markerset) {
        String baseName = "NewMarker";
        String newMarkerName = baseName;
        Marker existingMarker = null;

        for (int i = 0; i < markerset.getSize(); i++) {
            newMarkerName = baseName + "_" + i;
            if (markerset.contains(newMarkerName) == true) // name is being used by a current marker
            {
                continue;
            }
        }

        return newMarkerName;
    }
}

@@ -237,24 +237,52 @@
 ctionEvent;%0A
+import java.io.IOException;%0A
 import java.
@@ -294,16 +294,16 @@
 Vector;%0A
-
 import j
@@ -492,24 +492,60 @@
 nodes.Node;%0A
+import org.openide.util.Exceptions;%0A
 import org.o
@@ -675,16 +675,16 @@
 kerSet;%0A
-
 import o
@@ -710,16 +710,60 @@
 .Model;%0A
+import org.opensim.modeling.OpenSimContext;%0A
 import o
@@ -2014,80 +2014,472 @@
     
-final Marker marker = m
+Marker newMarker = new Marker();%0A        newMarker.setName(newMarkerName);%0A        newM
 arker
+.
 set
-.addMarker(newMarkerName, offset, body
+_location(offset);%0A        newMarker.setParentFrame(body);%0A        OpenSimContext context = OpenSimDB.getInstance().getContext(model);%0A        context.cacheModelAndState();%0A        markerset.adoptAndAppend(newMarker);%0A        try %7B%0A           context.restoreStateFromCachedModel();%0A       %7D catch (IOException ex) %7B%0A           Exceptions.printStackTrace(ex
 );%0A
+       %7D%0A
     
@@ -2492,17 +2492,20 @@
 dMarker(
-m
+newM
 arker, t

Use Marker constructor instead of MarkerSet method to add new marker