//
// PickManipulationRendererJ2D.java
//

/*
VisAD system for interactive analysis and visualization of numerical
data.  Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/

package visad.bom;

import visad.*;
import visad.java2d.*;

import java.awt.event.*;
import javax.swing.*;
import java.rmi.RemoteException;


/**
 * PickManipulationRendererJ2D is the VisAD class for picking
 * data in 2D.
 */
// from  "Heftrich, Torsten, AVENTIS/DE" 
public class PickManipulationRendererJ2D extends
DirectManipulationRendererJ2D {

  private int mouseModifiersMask = 0;
  private int mouseModifiersValue = 0;

  /**
   * Default constructor
   */
  public PickManipulationRendererJ2D () {
    this (0, 0);
  }

  /** 
   * Construct a new PickManipulationRenderer using the mouseModifiers
   * supplied.  mmm and mmv determine whehter SHIFT or CTRL keys are 
   * required - This is needed since this is a greedy 
   * DirectManipulationRenderer that will grab any right mouse click 
   * (that intersects its 2-D sub-manifold).
   * @param mmm  mouse modifiers mask.
   * @param mmv  mouse modifiers value.
   */
  public PickManipulationRendererJ2D (int mmm, int mmv) {
    super();
    mouseModifiersMask = mmm;
    mouseModifiersValue = mmv;
  }

  /** for use in drag_direct */
  private transient DataDisplayLink link = null;
  private transient DataReference ref = null;

  private float[][] spatialValues = null;
  /** index into spatialValues found by checkClose */
  private int closeIndex = -1;

  private int directManifoldDimension = -1;

  /** information calculated by checkDirect */
  /** explanation for invalid use of DirectManipulationRenderer */
  private String whyNotDirect = null;

  /** possible values for whyNotDirect */
  private final static String notSimpleField =
    "not simple field";
  private final static String notSimpleTuple =
    "not simple tuple";

  private boolean stop = false;

  /**
   * Check if direct manipulation is possible.  
   */
  public void checkDirect() throws VisADException, RemoteException {
    setIsDirectManipulation(false);

    DisplayImpl display = getDisplay();

    DataDisplayLink[] Links = getLinks();
    if (Links == null || Links.length == 0) {
      link = null;
      return;
    }
    link = Links[0];

    ref = link.getDataReference();

    ShadowType shadow = link.getShadow().getAdaptedShadowType();
    MathType type = link.getType();

    if (type instanceof FunctionType) {
      if (shadow.getLevelOfDifficulty() != ShadowType.SIMPLE_FIELD) {
        whyNotDirect = notSimpleField;
        return;
      }
    }
    else if (type instanceof SetType) {
      if (shadow.getLevelOfDifficulty() != ShadowType.SIMPLE_FIELD) {
        whyNotDirect = notSimpleField;
        return;
      }
    }
    else {
      if (shadow.getLevelOfDifficulty() != ShadowType.SIMPLE_TUPLE) {
        whyNotDirect = notSimpleTuple;
        return;
      }
    }

    setIsDirectManipulation(true);
  }

  private int getDirectManifoldDimension() {
    return directManifoldDimension;
  }

  /**
   * If direct manipulation is not possible, get the error message
   * explaining why.
   * @return error message. Will be null if no errors.
   */
  public String getWhyNotDirect() {
    return whyNotDirect;
  }

  /**
   * Add a point.  a no-op at this point.  
   * @param x  point value.
   */
  public void addPoint(float[] x) throws VisADException {
    // may need to do this for performance
  }

// methods customized from DataRenderer:

  /**
   * Get the CoordinateSystem for the display side.
   * @return  null for this DataRenderer
   */
  public CoordinateSystem getDisplayCoordinateSystem() {
    return null;
  }

  /** 
   * Set spatialValues from ShadowType.doTransform 
   * @param spatial_values  X, Y, Z values
   */
  public synchronized void setSpatialValues(float[][] spatial_values) {
    // these are X, Y, Z values
    spatialValues = spatial_values;
  }

  /** 
   * Check if ray intersects sub-manifold.  
   * @param origin  x,y,z values of the ray
   * @param direction x,y,z values of the ray?
   * @return distance from the spatial values.
   */
  public synchronized float checkClose(double[] origin, double[]
direction)
{
    int mouseModifiers = getLastMouseModifiers();
    if ((mouseModifiers & mouseModifiersMask) != mouseModifiersValue) {
      return Float.MAX_VALUE;
    }

    float distance = Float.MAX_VALUE;
    if (spatialValues == null) return distance;
    float o_x = (float) origin[0];
    float o_y = (float) origin[1];
    float o_z = (float) origin[2];
    float d_x = (float) direction[0];
    float d_y = (float) direction[1];
    float d_z = (float) direction[2];
 /*
System.out.println("origin = " + o_x + " " + o_y + " " + o_z);
System.out.println("direction = " + d_x + " " + d_y + " " + d_z);
  */
    for (int i=0; i 

Ads help maintain this website.