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

  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 vtkVVSelectionFrame - Selection Frame 
// .SECTION Description
// The selection frame is what contains a render widget.  

#ifndef __vtkVVSelectionFrame_h
#define __vtkVVSelectionFrame_h

#include "vtkKWSelectionFrame.h"
#include "XML/vtkXMLIOBaseMacros.h" // Needed for XML reader/writer macros

class vtkKWRenderWidget;
class vtkVVDataItem;
class vtkVVSelectionFrameInternals;
class vtkAbstractWidget;
class vtkKWContourWidget;

class VTK_EXPORT vtkVVSelectionFrame : public vtkKWSelectionFrame
{
public:
  static vtkVVSelectionFrame* New();
  vtkTypeRevisionMacro(vtkVVSelectionFrame, vtkKWSelectionFrame);
  void PrintSelf(ostream& os, vtkIndent indent);
  //BTX
  vtkKWGetXMLReaderWriterObjectsMacro();
  //ETX
  
  // Description:
  // Set/Get the render widget this selection frame is associated to.
  // It is ref counted.
  virtual void SetRenderWidget(vtkKWRenderWidget *widget);
  vtkGetObjectMacro(RenderWidget, vtkKWRenderWidget);

  // Description:
  // Select/Deselect the window
  vtkSetMacro(BindRenderWidgetOnlyWhenSelected, int);
  vtkGetMacro(BindRenderWidgetOnlyWhenSelected, int);
  vtkBooleanMacro(BindRenderWidgetOnlyWhenSelected, int);

  // Description:
  // Set/Get the data item this selection frame is associated to.
  // It is ref counted.
  virtual void SetDataItem(vtkVVDataItem *data);
  vtkGetObjectMacro(DataItem, vtkVVDataItem);

  // Description:
  // Manage the interactor widget (ref counted).
  // Return 1 on success, 0 otherwise
  virtual int AddInteractorWidget(vtkAbstractWidget*);
  virtual int GetNumberOfInteractorWidgets();
  virtual int HasInteractorWidget(vtkAbstractWidget *data);
  virtual vtkAbstractWidget* GetNthInteractorWidget(int i);
  virtual void RemoveInteractorWidget(vtkAbstractWidget*);
  virtual void RemoveAllInteractorWidgets();
  static void AddInteractorWidgetObservers(vtkKWObject *, vtkAbstractWidget*);
  static void RemoveInteractorWidgetObservers(vtkKWObject *, vtkAbstractWidget*);
  virtual int GetNumberOfPaintbrushWidgets();

  // Description:
  // Show/Hide (enable/disable) an interactor widget.
  virtual void SetInteractorWidgetVisibility(vtkAbstractWidget*, int);
  virtual int GetInteractorWidgetVisibility(vtkAbstractWidget*);

  // Description:
  // Lock/unlock an interactor widget. If supported by the RenderWidget
  // locking will make sure the interactor is stuck to a given view of
  // the renderwidget. For example, locking an interactor for a 2D image
  // widget will make sure the interactor is bound/linked to the specific
  // slice it was created on (i.e. only visible at that location).
  // See SetInteractorWidgetOriginalSlice.
  // The GoToInteractorWidget will make sure the interactor is visible, 
  // possibly by automatically going to the slice it was created on.
  // GetInteractorWidgetLock will return -1 if lock is not supported, 
  // 0 if supported and not locked, 1 if supported and locked.
  virtual void SetInteractorWidgetLock(vtkAbstractWidget*, int);
  virtual int GetInteractorWidgetLock(vtkAbstractWidget*);
  virtual void GoToInteractorWidget(vtkAbstractWidget*);

  // Description:
  // Set/Get the original slice an interactor widget was defined on, if
  // supported by RenderWidget.
  // Return -1 if not defined.
  virtual void SetInteractorWidgetOriginalSlice(vtkAbstractWidget*, int);
  virtual int GetInteractorWidgetOriginalSlice(vtkAbstractWidget*);

  // Description:
  // Convenience method to check if a default interactor widget type is 
  // supported, and add the corresponding type.
  // Add*Widget() will return a new instance of the specific widget (i.e.
  // AddDistanceWidget will return an instance of vtkKWDistanceWidget) and
  // initialize it.
  // Add*Widget(vtkAbstractWidget*) will do the same thing but not create
  // a new instance, using the one passed as parameter instead.
  virtual int DistanceWidgetIsSupported();
  virtual vtkAbstractWidget* AddDistanceWidget();
  virtual int AddDistanceWidget(vtkAbstractWidget*);
  virtual int BiDimensionalWidgetIsSupported();
  virtual vtkAbstractWidget* AddBiDimensionalWidget();
  virtual int AddBiDimensionalWidget(vtkAbstractWidget*);
  virtual int AngleWidgetIsSupported();
  virtual vtkAbstractWidget* AddAngleWidget();
  virtual int AddAngleWidget(vtkAbstractWidget*);
  virtual int ContourWidgetIsSupported();
  virtual vtkAbstractWidget* AddContourWidget();
  virtual int AddContourWidget(vtkAbstractWidget*);
  virtual int Label2DWidgetIsSupported();
  virtual vtkAbstractWidget* AddLabel2DWidget();
  virtual int AddLabel2DWidget(vtkAbstractWidget*);
  virtual int HandleWidgetIsSupported();
  virtual vtkAbstractWidget* AddHandleWidget();
  virtual int AddHandleWidget(vtkAbstractWidget*);
  virtual int PaintbrushWidgetIsSupported();
  virtual vtkAbstractWidget* AddPaintbrushWidget();
  virtual int AddPaintbrushWidget(vtkAbstractWidget*);

  // Description:
  // Close the selection frame. It can be re-implemented by
  // subclasses to add more functionalities, release resources, etc.
  // The only thing it does in this implementation is invoking the
  // CloseCommand.
  virtual void Close();

  // Description:
  // Select/Deselect the window. 
  // Override superclass to automatically focus on the render widget.
  virtual void SetSelected(int);

  // Description:
  // Add all the default observers needed by that object, or remove
  // all the observers that were added through AddCallbackCommandObserver.
  // Subclasses can override these methods to add/remove their own default
  // observers, but should call the superclass too.
  virtual void AddCallbackCommandObservers();
  virtual void RemoveCallbackCommandObservers();

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

protected:
  vtkVVSelectionFrame();
  ~vtkVVSelectionFrame();

  // Description:
  // Create the widget.
  virtual void CreateWidget();
  
  // Description:
  // The render widget
  vtkKWRenderWidget *RenderWidget;

  // Description:
  // The data item
  vtkVVDataItem *DataItem;

  // Description:
  // Create the render widget (if needed)
  virtual void CreateRenderWidget();

  // PIMPL Encapsulation for STL containers

  vtkVVSelectionFrameInternals *Internals;

  int BindRenderWidgetOnlyWhenSelected;

  // Description:
  // Pack
  virtual void Pack();

  // Description:
  // Add/Remove bindings
  virtual void Bind();
  virtual void UnBind();
  virtual void BindRenderWidget();
  virtual void UnBindRenderWidget();

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

  // Description:
  // Sets up the representation and properties for contours drawn on the image 
  // widgets (axial/ coronal/ sagittal/ oblique) and attaches the representation
  // the interactor.
  virtual void AddImageWidgetContourRepresentation( 
    vtkKWContourWidget *interactor);
    
  // Description:
  // Sets up the representation and properties for contours drawn on the volume 
  // widget and attaches the representation the interactor.
  virtual void AddVolumeWidgetContourRepresentation( 
    vtkKWContourWidget *interactor);
   
  // Description:
  // Update the enabled state of interactor widget(s) given its lock and
  // visibility status.
  virtual void UpdateInteractorWidgetEnabledState(
    vtkAbstractWidget*, int visibility, int lock, int orig_slice);
  virtual void UpdateInteractorWidgetsEnabledState();

  // Description:
  // Update window interactor state.
  virtual void UpdateRenderWindowInteractorState();

private:
  vtkVVSelectionFrame(const vtkVVSelectionFrame&);  // Not implemented
  void operator=(const vtkVVSelectionFrame&);  // Not implemented
};

#endif

