// First we import the VTK package that will make available all
// of the VTK commands to Java.

import vtk.*;

public class AnimDataCone {

  // this is an array of transforms to apply to the vtkPolyData.
  static double moves[][] =
      {{1.11, 1., 1.}, // expand on x
          {1.11, 1., 1.}, // expand on x
          {1.11, 1., 1.}, // expand on x
          {.9009, 1., 1.}, // contract on x
          {.9009, 1., 1.}, // contract on x
          {.9009, 1., 1.}, // contract on x
          {1., 1.11, 1.}, // expand on y
          {1., 1.11, 1.}, // expand on y
          {1., 1.11, 1.}, // expand on y
          {1., .9009, 1.}, // contract on y
          {1., .9009, 1.}, // contract on y
          {1., .9009, 1.}, // contract on y
          {1., 1., 1.11}, // expand on z
          {1., 1., 1.11}, // expand on z
          {1., 1., 1.11}, // expand on z
          {1., 1., .9009}, // contract on z
          {1., 1., .9009}, // contract on z
          {1., 1., .9009} // contract on z
      };

  /**
   * @param args
   */
  // load the necessary interface libraries on first reference to the
  // class.
  // Loading Native Libraries.
  // Now it works in eclipse without any issues.
  static {
    if (!vtkNativeLibrary.LoadAllNativeLibraries()) {
      for (vtkNativeLibrary lib : vtkNativeLibrary.values()) {
        if (!lib.IsLoaded()) {
          System.out.println(lib.GetLibraryName() + " not loaded");
        }
      }
    }
    vtkNativeLibrary.DisableOutputWindow(null);
  }

  // declare the interactor as an instance variable so we can refer to it
  // in the timer callback. we will pass the instance pointer to this
  // class for the callback to be invoked on.
  vtkRenderWindowInteractor iren = null;
  // create an instance polydata object to hold the animated polydata
  vtkAppendPolyData pd = null;
  // create the Transform as an instance variable so we can interact
  // with it from the interaction call back.
  vtkTransform Transform = null;
  // animState is how we manage the transform choices.
  // each animState is a frame of animation. in this case
  // a selected scale transform in the array of scale settings
  // in the moves array.
  int animState = 0;

  public static void main(String[] args) {
    // We will start by creating an instance of our AnimDataCone example
    // This example uses callbacks, and for Java that requires an instance
    // object to own the callback logic.

    AnimDataCone myCone = new AnimDataCone();
    myCone.doit();
  }

  /*
   * The TimerEvent is specified as the TimerEvent callback
   * to the RenderWindowInteractor. The polydata modification
   * is done here as well as the call to the renderWindow to
   * render the updated scene.
   */
  void StartRender() {

    vtkPolyData mpd = pd.GetPolyDataInput(0);
    vtkPoints pts = mpd.GetPoints();
    int ptct = pts.GetNumberOfPoints();
    Transform.Identity();
    Transform.Scale(AnimDataCone.moves[animState]);
    // this would probably be better done with a property or assembly,
    // but this clearly illustrates the modification of point data
    // cycle through the animation frames
    animState = (++animState) % 18;
    // Actually, marking the polydata as modified
    // is the key to the animation.
    // Comment the following pd.modified() and nothing
    // will appear to happen, inspite of all the preceding.
    // the pipeline UpdateExtent() only processes data that
    // a modification time stamp more recent than the last render.
    pd.Modified();
    // Uncomment the following to get a log of time in milliseconds 
    // for each rendered frame. 
    //	System.out.println("Render:" + System.currentTimeMillis());
  }

  /*
   * The doit() function is simply the instance function to perform the
   * construction of the vtk pipeline for this example.
   */
  void doit() {
    vtkNamedColors colors = new vtkNamedColors();

    double bkg[] = new double[]{0.1, 0.2, 0.4, 1.0};
    double actorColor[] = new double[4];
    colors.GetColor("White", actorColor);

    // This example illustrates animation via the startrender callback/
    //
    Transform = new vtkTransform();
    // Next we create an instance of vtkConeSource and set some of its
    // properties. The instance of vtkConeSource "cone" is part of a
    // visualization pipeline (it is a source process object); it produces
    // data (output type is vtkPolyData) which other filters may process.
    vtkConeSource cone = new vtkConeSource();
    cone.SetHeight(3.0);
    cone.SetRadius(1.0);
    cone.SetResolution(10);

    pd = new vtkAppendPolyData();

    pd.SetInputConnection(cone.GetOutputPort());
    // In this example we terminate the pipeline with a mapper process
    // object.
    // (Intermediate filters such as vtkShrinkPolyData could be inserted in
    // between the source and the mapper.) We create an instance of
    // vtkPolyDataMapper to map the polygonal data into graphics primitives.
    // We connect the output of the cone source to the input of this mapper.
    vtkPolyDataMapper coneMapper = new vtkPolyDataMapper();
    coneMapper.SetInputConnection(pd.GetOutputPort());

    // Create an actor to represent the cone. The actor orchestrates
    // rendering of
    // the mapper's graphics primitives. An actor also refers to properties
    // via a
    // vtkProperty instance, and includes an internal transformation matrix.
    // We
    // set this actor's mapper to be coneMapper which we created above.
    vtkActor coneActor = new vtkActor();
    coneActor.SetMapper(coneMapper);
    coneActor.GetProperty().SetColor(actorColor);

    // Create the Renderer and assign actors to it. A renderer is like a
    // viewport. It is part or all of a window on the screen and it is
    // responsible for drawing the actors it has. We also set the
    // background color here.
    vtkRenderer ren1 = new vtkRenderer();
    ren1.AddActor(coneActor);
    ren1.SetBackground(bkg);

    // Finally we create the render window which will show up on the screen
    // We put our renderer into the render window using AddRenderer. We
    // also set the size to be 300 pixels by 300.
    vtkRenderWindow renWin = new vtkRenderWindow();
    renWin.AddRenderer(ren1);
    renWin.SetSize(600, 600);

    // The vtkRenderWindowInteractor class watches for events (e.g.,
    // keypress,
    // mouse) in the vtkRenderWindow. These events are translated into
    // event invocations that VTK understands (see VTK/Common/vtkCommand.h
    // for all events that VTK processes). Then observers of these VTK
    // events can process them as appropriate.
    iren = new vtkRenderWindowInteractor();
    iren.SetRenderWindow(renWin);

    // By default the vtkRenderWindowInteractor instantiates an instance
    // of vtkInteractorStyle. vtkInteractorStyle translates a set of events
    // it observes into operations on the camera, actors, and/or properties
    // in the vtkRenderWindow associated with the vtkRenderWinodwInteractor.
    // Here we specify a particular interactor style.
    vtkInteractorStyleTrackballCamera style = new vtkInteractorStyleTrackballCamera();
    iren.SetInteractorStyle(style);

    // Start the event loop.
    iren.Initialize();
    ren1.Render();
    // Now for every window render we call our callback function to update
    // the model
    // resulting in another render.
    ren1.AddObserver("StartEvent", this, "StartRender");
    iren.CreateRepeatingTimer(50);
    iren.Start();
  }
}
