/*=========================================================================

  Program:   ParaView
  Module:    vtkPVComparativeVis.h

  Copyright (c) Kitware, Inc.
  All rights reserved.
  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
// .NAME vtkPVComparativeVis - Comparative visualization
// .SECTION Description
// vtkPVComparativeVis objects store comparative visualization
// information including the definition and the geometry. The definition
// consists of the names of properties, how they are to be varied  and 
// the number of values for each property. The comparative visualization 
// is generated by keeping all parameters but one constant, changing that 
// parameter value and storing the geometry for each case. This is repeated 
// for every parameter. The resulting "frames" are then presented to
// the user in a way to allow comparing them easily. Usually, the 
// properties correspond to some (simulation or experiment) parameters
// and the user wants to compare the results obtained by varying these
// parameters. Currently, the "frames" (or cells) are presented in
// a two dimensional, uniform grid. One or more actors are placed in
// each frame and the user interaction is passed to all. For example,
// rotation is applied to all frames equally.
// This class uses the animation framework present in VTK and ParaView.
// In this framework, the variation of a property over time is described
// with the help of cues. Each cue describes the variation of the 
// property over time.  "Key frames" are used for this purpose. A key
// frame describe the value of the property at a given time. For frames
// between key frames, the property value is computed using an interpolation
// scheme described by the surrounding key frames. In comparative vis,
// time is replaced by frame number.
// .SECTION See Also
// vtkPVSimpleAnimationCue

#ifndef __vtkPVComparativeVis_h
#define __vtkPVComparativeVis_h

#include "vtkObject.h"

class vtkPVAnimationCue;
class vtkPVApplication;
class vtkPVSimpleAnimationCue;
class vtkSMProxy;
//BTX
struct vtkPVComparativeVisInternals;
//ETX

class VTK_EXPORT vtkPVComparativeVis : public vtkObject
{
public:
  static vtkPVComparativeVis* New();
  vtkTypeRevisionMacro(vtkPVComparativeVis, vtkObject);
  void PrintSelf(ostream& os ,vtkIndent indent);

  // Description:
  // Application should be set before first call to Generate().
  void SetApplication(vtkPVApplication*);

  // Description:
  // Given properties, generate comparative visualization. This
  // actually generates each frame by creating appropriate animation
  // objects and playing different cases. As a result, new
  // geometry is created and stored.
  void Generate();

  // Description:
  // Returns false if comparative vis cannot be shown without
  // calling Generate().
  vtkGetMacro(IsGenerated, int);

  // Description:
  // Puts all displays on the window. Returns 0 on failure. Only
  // call after Generate().
  int Show();

  // Description:
  // Remove all displays from the window. Has no effect if Generate()
  // and Show() has not been called before.
  void Hide();

  // Description:
  // Add the property associated with the given cue. Here, the animation
  // cue (acue) is the one from ParaView and is not actually used in
  // generating the visualization. It is stored because the user interface
  // needs it when populating a dialog from the visualization. I would like
  // to get rid of this in the future. The simple cue (cue) is the one
  // actually used to create the visualization. While all other properties
  // are kept constant, this cue is run for generate one "row" of the
  // comparative visualization. The number of values determines the number
  // of frames in one "row".
  void AddProperty(vtkPVAnimationCue* acue, 
                   vtkPVSimpleAnimationCue* cue, 
                   int numValues);

  // Description:
  // Removes all properties and initializes internal data structures.
  // Hide() is called before releasing the reference to the geometry.
  void RemoveAllProperties();

  // Description:
  // Delete all cached data: geometry, displays etc... Does not
  // delete the cues (i.e. the comparative vis description). Therefore,
  // it is possible to call Generate() after Initialize() and recover
  // the comparative visualization.
  void Initialize();

  // Description:
  // Returns the number of assigned properties (parameters).
  unsigned int GetNumberOfProperties();

  // Description:
  // Returns the number of values (frames) of a given property.
  unsigned int GetNumberOfPropertyValues(unsigned int idx);

  // Description:
  // Returns the animation cue associated with a property.
  // This is not the cue used in generating the vis but is
  // used by the gui components.
  vtkPVAnimationCue* GetAnimationCue(unsigned int idx);

  // Description:
  // Returns the cue associated with a property.
  // This is the cue used in generating the vis.
  vtkPVSimpleAnimationCue* GetCue(unsigned int idx);

  // Description:
  // MultiActorHelper stores pointer to all actors in the scene.
  // The interactor later transforms these.
  vtkGetObjectMacro(MultiActorHelper, vtkSMProxy);

  // Description:
  // Set/Get the comparative vis name. Used by the comparative vis
  // manager.
  vtkSetStringMacro(Name);
  vtkGetStringMacro(Name);

protected:
  vtkPVComparativeVis();
  ~vtkPVComparativeVis();

  vtkPVApplication* Application;

  // Create all the geometry for a property (and all the properties
  // after it). Call PlayOne(0) to create the geometry for all.
  void PlayOne(unsigned int idx);

  // Set the number of values for a given property
  void SetNumberOfPropertyValues(unsigned int idx, unsigned int numValues);

  // Create geometry caches and displays for one case (i.e. fixed set 
  // of property values)
  void StoreGeometry();

  // All geometry caches and displays are stored consecutively in a vector.
  // To figure out which property indices an entry in the vector corresponds
  // to, call ComputeIndices(entryIdx). After this call, 
  // Internal->Indices vector will contain the right indices pointing to
  // the properties
  void ComputeIndices(unsigned int gidx);
  void ComputeIndex(unsigned int paramIdx, unsigned int gidx);

  // Used during comparative vis. generation. Called by the animation
  // scene proxy
  void ExecuteEvent(vtkObject* , unsigned long event, unsigned int paramIdx);

  // Gather two bounds (result is stored in the second argument)
  static void AddBounds(double bounds[6], double totalB[6]);

  vtkSMProxy* MultiActorHelper;

  char* Name;

  int InFirstShow;

  int IsGenerated;

//BTX
  friend class vtkCVAnimationSceneObserver;
//ETX

private:
  // Private implementation
  vtkPVComparativeVisInternals* Internal;

  vtkPVComparativeVis(const vtkPVComparativeVis&); // Not implemented.
  void operator=(const vtkPVComparativeVis&); // Not implemented.
};

#endif

