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

  Program:   ParaView
  Module:    vtkSMComparativeVisProxy.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 vtkSMComparativeVisProxy - Comparative visualization
// .SECTION Description
// vtkSMComparativeVisProxy 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 __vtkSMComparativeVisProxy_h
#define __vtkSMComparativeVisProxy_h

#include "vtkSMProxy.h"

class vtkSMAnimationCueProxy;
class vtkSMPropertyAdaptor;
class vtkSMProxy;
class vtkSMRenderModuleProxy;
//BTX
struct vtkSMComparativeVisProxyInternals;
//ETX

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

  // 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 a cue to be used in comparative vis.
  // The  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 AddCue(vtkSMProxy* cueProxy);
  void SetCue(unsigned int idx, vtkSMProxy* cueProxy);
  void SetNumberOfCues(unsigned int num);
  void SetNumberOfFramesInCue(unsigned int idx, unsigned int numValues);

  // Description:
  // Removes all cues.
  void RemoveAllCues();

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

  // 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 RemoveAllCache();

  // Description:
  // Returns the number of assigned cues (parameters).
  unsigned int GetNumberOfCues();

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

  // Description:
  // Returns the cue associated with a property.
  // This is the cue used in generating the vis.
  vtkSMAnimationCueProxy* 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);

  // Description:
  // Set this to 1 to abort before generating next frame. Automatically
  // resetted to 0 once aborted.
  vtkSetMacro(ShouldAbort, int);
  vtkGetMacro(ShouldAbort, int);

  // Description:
  // RenderModule is needed to render.
  void SetRenderModule(vtkSMRenderModuleProxy* ren);
  vtkGetObjectMacro(RenderModule, vtkSMRenderModuleProxy);

  // Description:
  // Stored to help gui select sources.
  void SetSourceName(unsigned int idx, const char* sourceName);
  const char* GetSourceName(unsigned int idx);

  // Description:
  // Stored to help gui save scripts.
  void SetSourceTclName(unsigned int idx, const char* sourceName);
  const char* GetSourceTclName(unsigned int idx);

  // Description:
  // Set the number of frames in X
  vtkSetMacro(NumberOfXFrames, unsigned int);
  vtkGetMacro(NumberOfXFrames, unsigned int);

  // Description:
  // Set the number of frames in Y
  vtkSetMacro(NumberOfYFrames, unsigned int);
  vtkGetMacro(NumberOfYFrames, unsigned int);

protected:
  vtkSMComparativeVisProxy();
  ~vtkSMComparativeVisProxy();

  // 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);

  // 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;

  char* SourceName;

  int InFirstShow;

  int IsGenerated;

  unsigned int NumberOfXFrames;
  unsigned int NumberOfYFrames;

  void UpdateProgress(double progress);

  vtkSMRenderModuleProxy* RenderModule;

//BTX
  friend class vtkCVAnimationSceneObserver;
//ETX

private:
  void ComputeNumberOfFrames();

  unsigned int NumberOfFrames;
  unsigned int CurrentFrame;

  unsigned int  PropertyIndex;

  // Private implementation
  vtkSMComparativeVisProxyInternals* Internal;

  int ShouldAbort;

  static const double BorderWidth;

  vtkSMPropertyAdaptor* Adaptor;

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

#endif

