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

  Copyright (c) Kitware, Inc.
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/VolViewCopyright.htm 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 vtkVVInteractorWidgetSelector - a measurement widget selector.
// .SECTION Description
// This class is a widget that can be used to store measurement widget.
// .SECTION See Also
// vtkKWPresetSelector

#ifndef __vtkVVInteractorWidgetSelector_h
#define __vtkVVInteractorWidgetSelector_h

#include "vtkKWPresetSelector.h"

class vtkVVWindowBase;
class vtkAbstractWidget;
class vtkContourStatistics;
class vtkVVSelectionFrame;
class vtkKWFrameWithLabel;
class vtkKWEntryWithLabel;
class vtkKWMenuButtonWithSpinButtons;
class vtkKWCaptionWidget;
class vtkVVInteractorWidgetSelectorInternals;

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

  // Description:
  // Set/Get the 3d widget associated to the preset in the pool.
  // Return 1 on success, 0 on error
  virtual int SetPresetInteractorWidget(int id, vtkAbstractWidget *interactor);
  virtual vtkAbstractWidget* GetPresetInteractorWidget(int id);

  // Description:
  // Set/Get the selection frame associated to the preset in the pool.
  // Return 1 on success, 0 on error
  virtual int SetPresetSelectionFrame(int id, vtkVVSelectionFrame *sel_frame);
  virtual vtkVVSelectionFrame* GetPresetSelectionFrame(int id);

  // Description:
  // Query if the pool has a given interactor widget in a group
  virtual int HasPresetWithGroupWithInteractorWidget(
    const char *group, vtkAbstractWidget *interactor);

  // Description:
  // Get the ID of an interactor widget if present. Returns -1 if absent.
  int GetIdOfInteractorWidget(vtkAbstractWidget *interactor);

  // Description:
  // Any type of abtract interactor widget can be added, but some of them
  // are supported by default (i.e. will show with a specific icon and
  // will be updated in the UI) and can be added through the toolbar.
  //BTX
  enum DefaultInteractorWidgetType
  {
    DistanceWidget = 0,
    BiDimensionalWidget,
    AngleWidget,
    ContourWidget,
    ContourSegmentWidget,
    Label2DWidget,
    HandleWidget,
    PaintbrushWidget
  };
  //ETX

  // Description:
  // Specifies a command to be invoked when the one of the default interactor
  // widget button is pressed (say distance, angle, contour).
  // This gives the opportunity for the application to check and collect the
  // relevant information to store in a new preset. The application is then
  // free to add the preset (using the AddPreset() method) and set its
  // fields independently (using the SetPresetGroup(), SetPresetComment(),
  // SetPreset...() methods).
  // The type of the default interactor widget is passed to the command (see
  // the DefaultInteractorWidgetType enumeration).
  // This can be used to create the corresponding widget
  // (say vtkKWDistanceWidget), add a preset (using AddPreset()) and set
  // its interactor widget member accordingly (SetPresetInteractorWidget).
  virtual void SetPresetAddDefaultInteractorCommand(
    vtkObject* object, const char *method);

  // Description:
  // Specifies a command to be invoked to check if a default interactor
  // widget is currently supported given the application context. If not,
  // the corresponding button will be disabled in the interface.
  // Make sure you call the Update() method to refresh the interface state.
  // For example, if this whole class is used to add interactor widgets
  // for different classes of visualization scene, it may make sense to 
  // support an angle widget for 2D scenes, but not for 3D scenes (unless
  // you have a solid angle widget handy). In that case, this command
  // gives the opportunity for the application to check which type of
  // scene is currently selected (or in effect), and return if the
  // default interactor widget is supported.
  // The type of the default interactor widget is passed to the command (see
  // the DefaultInteractorWidgetType enumeration). This command is called
  // once per default type.
  // It should return 1 if the interactor widget is supported, 0 otherwise.
  virtual void SetPresetDefaultInteractorIsSupportedCommand(
    vtkObject* object, const char *method);

  // Description:
  // Specifies a command to be invoked when the interactor widget preset details
  // widget is to be updated for a specific preset.
  // The 'object' argument is the object that will have the method called on
  // it. The 'method' argument is the name of the method to be called and any
  // arguments in string form. If the object is NULL, the method is still
  // evaluated as a simple command. 
  // The following parameters are also passed to the command:
  // - the id of the preset to update: int
  virtual void SetPresetUpdateInteractorWidgetPropertiesCommand(
    vtkObject* object, const char *method);

  // Description:
  // Callback invoked when the user successfully updated the preset field
  // located at ('row', 'col') with the new contents 'text', as a result
  // of editing the corresponding cell interactively.
  virtual void PresetCellUpdatedCallback(int row, int col, const char *text);

  // Description:
  // Callbacks
  virtual void InteractorWidgetAddCallback(int type);
  virtual void PresetSelectionCallback();

  // Description:
  // Set/Get the window so that its contents can be updated after contour 
  // segmentation 
  vtkGetObjectMacro(Window, vtkVVWindowBase);
  virtual void SetWindow(vtkVVWindowBase*);

  // Description:
  // Tools visibility. Default ON.
  vtkGetMacro(DistanceWidgetVisibility, int);
  virtual void SetDistanceWidgetVisibility(int);
  vtkBooleanMacro(DistanceWidgetVisibility, int);
  vtkGetMacro(BiDimensionalWidgetVisibility, int);
  virtual void SetBiDimensionalWidgetVisibility(int);
  vtkBooleanMacro(BiDimensionalWidgetVisibility, int);
  vtkGetMacro(AngleWidgetVisibility, int);
  virtual void SetAngleWidgetVisibility(int);
  vtkBooleanMacro(AngleWidgetVisibility, int);
  vtkGetMacro(ContourWidgetVisibility, int);
  virtual void SetContourWidgetVisibility(int);
  vtkBooleanMacro(ContourWidgetVisibility, int);
  vtkGetMacro(Label2DWidgetVisibility, int);
  virtual void SetLabel2DWidgetVisibility(int);
  vtkBooleanMacro(Label2DWidgetVisibility, int);
  vtkGetMacro(HandleWidgetVisibility, int);
  virtual void SetHandleWidgetVisibility(int);
  vtkBooleanMacro(HandleWidgetVisibility, int);
  vtkGetMacro(PaintbrushWidgetVisibility, int);
  virtual void SetPaintbrushWidgetVisibility(int);
  vtkBooleanMacro(PaintbrushWidgetVisibility, int);

  // Description:
  // Query if all current preset interactor widgets are "defined", i.e.
  // if they have been correctly setup (and not in the middle of being set)
  virtual int IsPresetInteractorWidgetDefined(int id);
  virtual int IsPresetInteractorWidgetDefined(vtkAbstractWidget *widget);
  virtual int ArePresetInteractorWidgetsDefined();

  // Description:
  // Refresh the interface.
  virtual void Update();

  // Description:
  // Update the "enable" state of the object and its internal parts.
  // Depending on different Ivars (this->Enabled, the application's 
  // Limited Edition Mode, etc.), the "enable" state of the object is updated
  // and propagated to its internal parts/subwidgets. This will, for example,
  // enable/disable parts of the widget UI, enable/disable the visibility
  // of 3D widgets, etc.
  virtual void UpdateEnableState();

  // Description:
  // Callback invoked when the user successfully updated the preset field
  // located at ('row', 'col') with the new contents 'text', as a result
  // of editing the corresponding cell interactively.
  virtual void InteractorWidgetPropertiesCellUpdatedCallback(
    int id, int row, int col, const char *text);

protected:
  vtkVVInteractorWidgetSelector();
  ~vtkVVInteractorWidgetSelector();

  // Description:
  // Create the widget.
  virtual void CreateWidget();
  
  // Description:
  // Create the columns.
  // Subclasses should override this method to add their own columns and
  // display their own preset fields (do not forget to call the superclass
  // first).
  virtual void CreateColumns();

  // Description:
  // Create the preset buttons in the toolbar.
  // Subclasses should override this method to add their own toolbar buttons
  // (do not forget to call the superclass first).
  virtual void CreateToolbarPresetButtons(vtkKWToolbar*, int use_separators);

  // Description:
  // Update the toolbar preset buttons state/visibility.
  virtual void UpdateToolbarPresetButtons(vtkKWToolbar*);

  // Description:
  // Set the toolbar preset buttons icons.
  // Subclasses should override this method to set their own icons
  // (do not forget to call the superclass first).
  virtual void SetToolbarPresetButtonsIcons(vtkKWToolbar*);

  // Description:
  // Set the toolbar preset buttons balloon help strings
  // Subclass can override this method to change the help strings
  // associated to the buttons.
  virtual void SetToolbarPresetButtonsHelpStrings(vtkKWToolbar*);

  // Description:
  // Deallocate a preset.
  // Subclasses should override this method to release the memory allocated
  // by their own preset fields  (do not forget to call the superclass
  // first).
  virtual void DeAllocatePreset(int id);

  // Description:
  // Update the preset row, i.e. add a row for that preset if it is not
  // displayed already, hide it if it does not match GroupFilter, and
  // update the table columns with the corresponding preset fields.
  // Subclass should override this method to display their own fields.
  // Return 1 on success, 0 if the row was not (or can not be) updated.
  // Subclasses should call the parent's UpdatePresetRow, and abort
  // if the result is not 1.
  virtual int UpdatePresetRow(int id);

  // Description:
  // Update the value column only in the preset row
  // User for fast refresh during 3D widget interaction
  virtual int UpdatePresetRowValueColumn(int id);

  // Description:
  // Convenience methods to get the index of a given column
  virtual int GetInteractorTypeColumnIndex();
  virtual int GetInteractionValueColumnIndex();
  virtual int GetVisibilityColumnIndex();
  virtual int GetColorColumnIndex();
  virtual int GetLockColumnIndex();

  // Description:
  // Processes the events that are passed through CallbackCommand (or others).
  // Subclasses can oberride this method to process their own events, but
  // should call the superclass too.
  virtual void ProcessCallbackCommandEvents(
    vtkObject *caller, unsigned long event, void *calldata);

  char *PresetAddDefaultInteractorCommand;
  virtual void InvokePresetAddDefaultInteractorCommand(int type);

  char *PresetDefaultInteractorIsSupportedCommand;
  virtual int InvokePresetDefaultInteractorIsSupportedCommand(int type);

  char *PresetUpdateInteractorWidgetPropertiesCommand;
  virtual int InvokePresetUpdateInteractorWidgetPropertiesCommand(int id);

  // PIMPL Encapsulation for STL containers
  //BTX
  vtkVVInteractorWidgetSelectorInternals *Internals;
  //ETX

  // Description:
  // Update the interactor widget properties area.
  virtual void UpdateInteractorWidgetProperties(int id);

  vtkKWMultiColumnListWithScrollbars *InteractorWidgetProperties;

  vtkContourStatistics         *ContourStatistics;
  vtkVVWindowBase              *Window;

  int DistanceWidgetVisibility;
  int BiDimensionalWidgetVisibility;
  int AngleWidgetVisibility;
  int ContourWidgetVisibility;
  int Label2DWidgetVisibility;
  int HandleWidgetVisibility;
  int PaintbrushWidgetVisibility;

private:

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

#endif
