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

  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.

=========================================================================*/
#include "vtkVVWidgetInterface.h"

#include "vtkCommand.h"
#include "vtkObjectFactory.h"
#include "vtkAbstractWidget.h"

#include "vtkContourSegmentationFrame.h"
#include "vtkContourRepresentation.h"

#include "vtkKWEntry.h"
#include "vtkKWEntryWithLabel.h"
#include "vtkKWFrameWithLabel.h"
#include "vtkKWIcon.h"
#include "vtkKWInternationalization.h"
#include "vtkKWMenuButton.h"
#include "vtkKWMultiColumnList.h"
#include "vtkKWMultiColumnListWithScrollbars.h"

#include "vtkKWContourWidget.h"
#include "vtkKWImageWidget.h"

#include "vtkVVInteractorWidgetSelector.h"
#include "vtkVVSelectionFrame.h"
#include "vtkVVSelectionFrameLayoutManager.h"
#include "vtkVVWindow.h"
#include "vtkVVHandleWidget.h"
#include "vtkVVPaintbrushWidgetEditor.h"

#include "vtkKWEWidgetGroup.h"
#include "vtkKWEPaintbrushWidget.h"
#include "vtkKWEPaintbrushRepresentation2D.h"
#include "vtkKWEPaintbrushDrawing.h"

#include <vtksys/SystemTools.hxx>

#define max(x,y) ((x>y) ? (x) : (y))

//---------------------------------------------------------------------------
vtkStandardNewMacro(vtkVVWidgetInterface);
vtkCxxRevisionMacro(vtkVVWidgetInterface, "$Revision: 1.10 $");

//---------------------------------------------------------------------------
vtkVVWidgetInterface::vtkVVWidgetInterface()
{
  this->SetName(ks_("Widget Panel|Title|Widgets"));
  this->PageId = 0;

  // Measurements

  this->InteractorWidgetFrame = NULL;
  this->InteractorWidgetSelector = NULL;

  // Property widgets

  this->SegmentationFrame = NULL;
  this->PaintbrushWidgetEditor = NULL;
}

//---------------------------------------------------------------------------
vtkVVWidgetInterface::~vtkVVWidgetInterface()
{
  // Measurements

  if (this->InteractorWidgetFrame)
    {
    this->InteractorWidgetFrame->Delete();
    this->InteractorWidgetFrame = NULL;
    }

  if (this->InteractorWidgetSelector)
    {
    this->InteractorWidgetSelector->Delete();
    this->InteractorWidgetSelector = NULL;
    }

  // Property widgets

  if (this->SegmentationFrame)
    {
    this->SegmentationFrame->Delete();
    this->SegmentationFrame = NULL;
    }

  if (this->PaintbrushWidgetEditor)
    {
    this->PaintbrushWidgetEditor->Delete();
    this->PaintbrushWidgetEditor = NULL;
    }
}

// --------------------------------------------------------------------------
void vtkVVWidgetInterface::Create()
{
  if (this->IsCreated())
    {
    vtkErrorMacro("The panel is already created.");
    return;
    }

  // Create the superclass instance (and set the application)

  this->Superclass::Create();

  ostrstream tk_cmd;

  vtkKWWidget *page;
  vtkKWFrame *frame;

  // --------------------------------------------------------------
  // Add a "Widget" page

  this->PageId = this->AddPage(NULL, this->GetName());
  this->SetPageIconToPredefinedIcon(
    this->PageId, vtkKWIcon::IconNuvola22x22AppsDesigner);

  page = this->GetPageWidget(this->PageId);

  // --------------------------------------------------------------
  // Measurements : frame

  if (!this->InteractorWidgetFrame)
    {
    this->InteractorWidgetFrame = vtkKWFrameWithLabel::New();
    }

  this->InteractorWidgetFrame->SetParent(this->GetPagesParentWidget());
  this->InteractorWidgetFrame->Create();
  this->InteractorWidgetFrame->SetLabelText(k_("Widgets"));
    
  tk_cmd << "pack " << this->InteractorWidgetFrame->GetWidgetName()
         << " -side top -anchor nw -fill both -expand n -padx 2 -pady 2 " 
         << " -in " << page->GetWidgetName() << endl;
  
  frame = this->InteractorWidgetFrame->GetFrame();

  // --------------------------------------------------------------
  // Interactor Widget

  if (!this->InteractorWidgetSelector)
    {
    this->InteractorWidgetSelector = vtkVVInteractorWidgetSelector::New();
    }

  this->InteractorWidgetSelector->SetParent(frame);
  this->InteractorWidgetSelector->Create();
  this->InteractorWidgetSelector->SetListHeight(10);
  this->InteractorWidgetSelector->SelectSpinButtonsVisibilityOff();
  this->InteractorWidgetSelector->ApplyPresetOnSelectionOff();
  this->InteractorWidgetSelector->SetPresetAddDefaultInteractorCommand(
    this, "InteractorWidgetAddDefaultInteractorCallback");
  this->InteractorWidgetSelector->SetPresetDefaultInteractorIsSupportedCommand(
    this, "InteractorWidgetDefaultInteractorIsSupportedCallback");
  this->InteractorWidgetSelector->SetPresetRemoveCommand(
    this, "InteractorWidgetRemoveCallback");
  this->InteractorWidgetSelector->SetPresetHasChangedCommand(
    this, "InteractorWidgetHasChangedCallback");
  this->InteractorWidgetSelector->SetPresetUpdateInteractorWidgetPropertiesCommand(
    this, "InteractorWidgetPropertiesUpdatedCallback");

  // Set the selection mode to single so that double-click on a comment or
  // color icon still works (Tablelist bug).
  // Drawback: one can not use the up/down arrow key to go from one preset
  // to the other, but such arrows are available as icons anyway below the
  // list (select next/previous preset).
  this->InteractorWidgetSelector->GetPresetList()->GetWidget()->SetSelectionModeToSingle();

  // pass the window so the InteractorWidgetSelector can update the window if 
  // inplace filters are applied.
  this->InteractorWidgetSelector->SetWindow(this->Window);

  tk_cmd << "pack " << this->InteractorWidgetSelector->GetWidgetName()
         << " -side top -anchor nw -fill both -expand t" << endl;

  // --------------------------------------------------------------
  // Pack 

  tk_cmd << ends;
  this->Script(tk_cmd.str());
  tk_cmd.rdbuf()->freeze(0);

  // Update according to the current Window

  this->Update();
}

//---------------------------------------------------------------------------
void vtkVVWidgetInterface::PopulateInteractorWidgets()
{
  if (!this->InteractorWidgetSelector)
    {
    return;
    }

  // Remove the ones in the selector that are not used anywhere

  vtksys_stl::vector<int> ids_to_remove;
  int i, nb_presets = this->InteractorWidgetSelector->GetNumberOfPresets();
  for (i = 0; i < nb_presets; i++)
    {
    int id = this->InteractorWidgetSelector->GetIdOfNthPreset(i);
    vtkAbstractWidget *interactor = 
      this->InteractorWidgetSelector->GetPresetInteractorWidget(id);
    vtkVVSelectionFrame *sel_frame = 
      this->InteractorWidgetSelector->GetPresetSelectionFrame(id);
    vtkVVSelectionFrameLayoutManager *mgr = 
      this->Window->GetDataSetWidgetLayoutManager();
    if (interactor && 
        (!sel_frame ||
         !mgr || !mgr->HasWidget(sel_frame) || 
         !sel_frame->HasInteractorWidget(interactor)))
      {
      ids_to_remove.push_back(id);
      }
    }
  for (unsigned int rank = 0; rank < ids_to_remove.size(); rank++)
    {
    this->InteractorWidgetSelector->RemovePreset(ids_to_remove[rank]);
    }

  // Add the one in the sel frame that are not in the selector
    
  const char *group = NULL;

  vtkVVSelectionFrame *sel_frame = this->Window->GetSelectedSelectionFrame();
  if (sel_frame)
    {
    group = sel_frame->GetTclName();
    int nb_interactors = sel_frame->GetNumberOfInteractorWidgets();
    for (i = 0; i < nb_interactors; i++)
      {
      vtkAbstractWidget *interactor = sel_frame->GetNthInteractorWidget(i);
      if (interactor && !this->InteractorWidgetSelector->
          HasPresetWithGroupWithInteractorWidget(group, interactor))
        {
        int id = this->InteractorWidgetSelector->InsertPreset(
          this->InteractorWidgetSelector->GetIdOfNthPreset(0));
        this->InteractorWidgetSelector->SetPresetGroup(id, group);
        this->InteractorWidgetSelector->SetPresetSelectionFrame(
          id, sel_frame);
        this->InteractorWidgetSelector->SetPresetInteractorWidget(
          id, interactor);
        }
      }
    }

  // Make sure we are displaying only the preset for that sel frame

  if (this->InteractorWidgetSelector->GetNumberOfPresets())
    {
    this->InteractorWidgetSelector->SetPresetFilterGroupConstraint(group);
    }
}

//---------------------------------------------------------------------------
void vtkVVWidgetInterface::InteractorWidgetAddDefaultInteractorCallback(
  int type)
{
  vtkVVSelectionFrame *sel_frame = this->Window->GetSelectedSelectionFrame();
  if (!sel_frame)
    {
    return;
    }

  vtkAbstractWidget *interactor = NULL;
  int is_defined_after_end_interaction_event = 1;

  switch (type)
    {
    case vtkVVInteractorWidgetSelector::DistanceWidget:
      interactor = sel_frame->AddDistanceWidget();
      break;
    case vtkVVInteractorWidgetSelector::BiDimensionalWidget:
      interactor = sel_frame->AddBiDimensionalWidget();
      break;
    case vtkVVInteractorWidgetSelector::AngleWidget:
      interactor = sel_frame->AddAngleWidget();
      break;
    case vtkVVInteractorWidgetSelector::ContourWidget:
      interactor = sel_frame->AddContourWidget();
      break;
    case vtkVVInteractorWidgetSelector::Label2DWidget:
      interactor = sel_frame->AddLabel2DWidget();
      break;
    case vtkVVInteractorWidgetSelector::PaintbrushWidget:
    {
      // Paintbrush widgets exist on all the views for the selected 
      // dataitem. The corresponding widgets on these views are 
      // synchronized through a widget group
      interactor = sel_frame->AddPaintbrushWidget();
      vtkKWEPaintbrushWidget *painbrush_widget = 
        vtkKWEPaintbrushWidget::SafeDownCast(interactor);
      vtkKWEPaintbrushRepresentation2D *rep2d = 
        vtkKWEPaintbrushRepresentation2D::SafeDownCast(
          painbrush_widget->GetRepresentation());
      vtkKWEPaintbrushDrawing *drawing = rep2d->GetPaintbrushDrawing();
      vtkKWEWidgetGroup *widget_group = vtkKWEWidgetGroup::New();
      widget_group->AddWidget(painbrush_widget);
      const int nb_sel_frames = 
        this->Window->GetNumberOfSelectionFramesUsingSelectedDataItem();
      for (int i = 0; i < nb_sel_frames; i++)
        {
        vtkVVSelectionFrame *another_sel_frame = 
          this->Window->GetNthSelectionFrameUsingSelectedDataItem(i);
        if (another_sel_frame != sel_frame && 
            another_sel_frame->PaintbrushWidgetIsSupported())
          {
          vtkKWEPaintbrushWidget *another_painbrush_widget = 
            vtkKWEPaintbrushWidget::SafeDownCast(
              another_sel_frame->AddPaintbrushWidget());
          vtkKWEPaintbrushRepresentation2D *another_rep2d = 
            vtkKWEPaintbrushRepresentation2D::SafeDownCast(
              another_painbrush_widget->GetRepresentation());
          another_rep2d->SetSingleSliceThickBrush(
            rep2d->GetSingleSliceThickBrush());
          another_rep2d->SetPaintbrushDrawing(drawing);
          widget_group->AddWidget(another_painbrush_widget);
          vtkVVSelectionFrame::AddInteractorWidgetObservers(
            this, another_painbrush_widget);
          }
        }
      widget_group->SetEnabled(1);
      widget_group->Delete();
      is_defined_after_end_interaction_event = 0;
    }
      break;
    case vtkVVInteractorWidgetSelector::HandleWidget:
      {
      // Handle widgets exist on all the renderwindows/views for the selected 
      // dataitem. The corresponding widgets on multiple views are 
      // synchronized through events. To uniquely identify the set of widgets
      // that represent the same seed, the handle widgets have an ID. 
      // We need to assign a unique ID. Find the max ID that exists for this 
      // dataitem. new_id = MaxID + 1
      const int new_id = vtkVVHandleWidget::GetNewUniqueID(sel_frame);

      // Now find all the selection frames for this data-item and add a seed
      // widget to all of them. This point should be visible in all the views.

      interactor = sel_frame->AddHandleWidget();
      (static_cast<vtkVVHandleWidget*>(interactor))->PlaceInteractivelyOn();
      (static_cast<vtkVVHandleWidget*>(interactor))->SetID(new_id);
      
      const int nb_sel_frames = 
        this->Window->GetNumberOfSelectionFramesUsingSelectedDataItem();
      for (int i = 0; i < nb_sel_frames; i++)
        {
        vtkVVSelectionFrame *another_sel_frame = 
          this->Window->GetNthSelectionFrameUsingSelectedDataItem(i);

        // Make sure we aren't stepping on our own toes.
        // If this selection frame supports seeds, add a seed
        if (another_sel_frame != sel_frame && 
            another_sel_frame->HandleWidgetIsSupported())
          {
          vtkVVHandleWidget *hw = vtkVVHandleWidget::SafeDownCast(
            another_sel_frame->AddHandleWidget());
          hw->SetID(new_id);
          if (hw)
            {
            vtkVVSelectionFrame::AddInteractorWidgetObservers(this, hw);
            }
          }
        }

      break;
      }
    }

  if (interactor)
    {
    vtkVVSelectionFrame::AddInteractorWidgetObservers(this, interactor);
    if (is_defined_after_end_interaction_event)
      {
      sel_frame->SetOuterSelectionFrameBlinking(1);
      }
    }

  this->PopulateInteractorWidgets();
  this->Raise();
  if (interactor && this->InteractorWidgetSelector)
    {
    this->InteractorWidgetSelector->SelectPreset(
      this->InteractorWidgetSelector->GetIdOfInteractorWidget(interactor));
    }
}

//---------------------------------------------------------------------------
int vtkVVWidgetInterface::InteractorWidgetRemoveCallback(int id)
{
  if (!this->InteractorWidgetSelector)
    {
    return 0;
    }

  vtkAbstractWidget *interactor = 
    this->InteractorWidgetSelector->GetPresetInteractorWidget(id);
  vtkVVSelectionFrame *sel_frame = 
    this->InteractorWidgetSelector->GetPresetSelectionFrame(id);

  // For the handle widgets which form a group, we have to remove them from
  // all the selection frames for this data-item

  vtkVVHandleWidget *handle_widget = 
    vtkVVHandleWidget::SafeDownCast(interactor);
  if (handle_widget)
    {
    int nb_handles_in_group = handle_widget->GetNumberOfHandlesInGroup();
    for (int i = nb_handles_in_group; i >= 0; i--)
      {
      vtkVVHandleWidget *another_handle_widget = 
        handle_widget->GetNthHandleInGroup(i);
      if (another_handle_widget)
        {
        this->InteractorWidgetRemoveCallbackInternal(
          another_handle_widget, another_handle_widget->GetSelectionFrame());
        }
      }
    return 1;
    }

  // Paintbrush widgets exist on all the views for the selected 
  // dataitem. The corresponding widgets on these views are 
  // synchronized through a widget group

  vtkKWEPaintbrushWidget *painbrush_widget = 
    vtkKWEPaintbrushWidget::SafeDownCast(interactor);
  if (painbrush_widget)
    {
    vtkKWEWidgetGroup *widget_group = painbrush_widget->GetWidgetGroup();
    widget_group->SetEnabled(0); // will also render
    unsigned int nb_widgets = widget_group->GetNumberOfWidgets();
    if (nb_widgets)
      {
      vtksys_stl::vector<vtkVVSelectionFrame *> sel_frames;
      int nb_sel_frames = 
        this->Window->GetNumberOfSelectionFramesUsingSelectedDataItem();
      for (int j = 0; j < nb_sel_frames; j++)
        {
        vtkVVSelectionFrame *another_sel_frame = 
          this->Window->GetNthSelectionFrameUsingSelectedDataItem(j);
        if (another_sel_frame->PaintbrushWidgetIsSupported())
          {
          sel_frames.push_back(another_sel_frame);
          }
        }
      for (int i = nb_widgets - 1; i >= 0; i--)
        {
        vtkAbstractWidget *another_paintbrush_widget = 
          widget_group->GetNthWidget(i);
        if (another_paintbrush_widget)
          {
          vtksys_stl::vector<vtkVVSelectionFrame *>::iterator it = 
            sel_frames.begin();
          vtksys_stl::vector<vtkVVSelectionFrame *>::iterator end = 
            sel_frames.end();
          for (; it != end; ++it)
            {
            if ((*it)->HasInteractorWidget(another_paintbrush_widget))
              {
              this->InteractorWidgetRemoveCallbackInternal(
                another_paintbrush_widget, *it);
              widget_group->RemoveWidget(another_paintbrush_widget);
              (*it)->GetRenderWidget()->Render();
              sel_frames.erase(it);
              break;
              }
            }
          }
        }
      }
    return 1;
    }

  // For all other widgets ..

  return this->InteractorWidgetRemoveCallbackInternal(interactor, sel_frame);
}

//---------------------------------------------------------------------------
int vtkVVWidgetInterface::InteractorWidgetRemoveCallbackInternal(
    vtkAbstractWidget *interactor, vtkVVSelectionFrame *sel_frame)
{  
  if (interactor && sel_frame)
    {
    if (!this->InteractorWidgetSelector->IsPresetInteractorWidgetDefined(
          interactor))
      {
      sel_frame->SetOuterSelectionFrameBlinking(0);
      }
    vtkVVSelectionFrame::RemoveInteractorWidgetObservers(this, interactor);
    sel_frame->RemoveInteractorWidget(interactor);
    }

  return 1;
}

//---------------------------------------------------------------------------
int 
vtkVVWidgetInterface::InteractorWidgetDefaultInteractorIsSupportedCallback(
  int type)
{
  vtkVVSelectionFrame *sel_frame = this->Window->GetSelectedSelectionFrame();
  if (!sel_frame)
    {
    return 0;
    }

  switch (type)
    {
    case vtkVVInteractorWidgetSelector::DistanceWidget:
      return sel_frame->DistanceWidgetIsSupported();
      break;
    case vtkVVInteractorWidgetSelector::BiDimensionalWidget:
      return sel_frame->BiDimensionalWidgetIsSupported();
      break;
    case vtkVVInteractorWidgetSelector::AngleWidget:
      return sel_frame->AngleWidgetIsSupported();
      break;
    case vtkVVInteractorWidgetSelector::ContourWidget:
      return sel_frame->ContourWidgetIsSupported();
      break;
    case vtkVVInteractorWidgetSelector::Label2DWidget:
      return sel_frame->Label2DWidgetIsSupported();
      break;
    case vtkVVInteractorWidgetSelector::HandleWidget:
      return sel_frame->HandleWidgetIsSupported();
      break;
    case vtkVVInteractorWidgetSelector::PaintbrushWidget:
      return sel_frame->PaintbrushWidgetIsSupported();
      break;
    }

  return 0;
}

//---------------------------------------------------------------------------
void vtkVVWidgetInterface::InteractorWidgetHasChangedCallback(int )
{
}

//---------------------------------------------------------------------------
void vtkVVWidgetInterface::InteractorWidgetPropertiesUpdatedCallback(int id)
{
  this->UpdateContourSegmentationFrame(id);
  this->UpdatePaintbrushWidgetEditor(id);
}

//----------------------------------------------------------------------------
void vtkVVWidgetInterface::ProcessCallbackCommandEvents(
  vtkObject *caller,
  unsigned long event,
  void *calldata)
{
  vtkAbstractWidget *interactor = vtkAbstractWidget::SafeDownCast(caller);
  if (interactor)
    {
    int i, nb_presets = this->InteractorWidgetSelector->GetNumberOfPresets();
    for (i = 0; i < nb_presets; i++)
      {
      int id = this->InteractorWidgetSelector->GetIdOfNthPreset(i);
      if (this->InteractorWidgetSelector->GetPresetInteractorWidget(id) == 
          interactor)
        {
        vtkVVSelectionFrame *sel_frame = (vtkVVSelectionFrame*)
          this->InteractorWidgetSelector->GetPresetSelectionFrame(id);
        if (sel_frame && event == vtkCommand::EndInteractionEvent)
          {
          sel_frame->SetOuterSelectionFrameBlinking(0);
          }
        }
      }
    }

  this->Superclass::ProcessCallbackCommandEvents(caller, event, calldata);
}

//---------------------------------------------------------------------------
void vtkVVWidgetInterface::Update()
{
  this->Superclass::Update();

  vtkVVDataItem *data = 
    this->Window ? this->Window->GetSelectedDataItem() : NULL;

  if (this->InteractorWidgetSelector)
    {
    this->PopulateInteractorWidgets();
    this->InteractorWidgetSelector->Update();
    this->InteractorWidgetSelector->SetEnabled(data ? this->GetEnabled() : 0);
    this->InteractorWidgetPropertiesUpdatedCallback(
      this->InteractorWidgetSelector->GetIdOfVisibleSelectedPreset());
    }
}

//----------------------------------------------------------------------------
void vtkVVWidgetInterface::UpdateContourSegmentationFrame(int id)
{
  if (!this->IsCreated())
    {
    return;
    }
  
  int active = 0;

  vtkAbstractWidget *interactor = 
    this->InteractorWidgetSelector->GetPresetInteractorWidget(id);
  vtkKWContourWidget *contour_widget = 
    vtkKWContourWidget::SafeDownCast(interactor);
  vtkKWRenderWidgetPro *rwp = NULL;
  if (contour_widget)
    {
    vtkContourRepresentation *rep = vtkContourRepresentation::SafeDownCast(
      contour_widget->GetRepresentation());
    vtkVVSelectionFrame *sel_frame = 
      this->InteractorWidgetSelector->GetPresetSelectionFrame(id);
    rwp = vtkKWRenderWidgetPro::SafeDownCast(sel_frame->GetRenderWidget());
    if (rep && rep->GetClosedLoop() && 
        vtkContourSegmentationFrame::RenderWidgetSupportSegmentation(rwp))
      {
      active = 1;
      }
    }

  // If we are enabling contour segmentation, check with the frame if it 
  // supports segmentation on this render widget.

  if (active)
    {
    if (!this->SegmentationFrame)
      {
      this->SegmentationFrame = vtkContourSegmentationFrame::New();
      this->SegmentationFrame->SetParent(this->GetPagesParentWidget());
      this->SegmentationFrame->Create();
      this->SegmentationFrame->SetEnabled(this->GetEnabled());
      this->SegmentationFrame->SetInteractorWidgetSelector(
        this->InteractorWidgetSelector);
      }

    this->SegmentationFrame->SetRenderWidget(rwp);
    this->SegmentationFrame->EnableContourSegmentationGUI(this->GetEnabled());

    vtkKWWidget *page = this->GetPageWidget(this->PageId);
    this->Script("pack %s -side top -anchor nw -fill both -expand f -padx 2 -pady 2 -in %s", 
                 this->SegmentationFrame->GetWidgetName(), 
                 page->GetWidgetName());
    }
  else
    {
    if (this->SegmentationFrame)
      {
      this->Script("pack forget %s", this->SegmentationFrame->GetWidgetName());
      this->SegmentationFrame->EnableContourSegmentationGUI(0);
      }
    }
}

//----------------------------------------------------------------------------
void vtkVVWidgetInterface::UpdatePaintbrushWidgetEditor(int id)
{
  if (!this->IsCreated())
    {
    return;
    }

  vtkAbstractWidget *interactor = 
    this->InteractorWidgetSelector->GetPresetInteractorWidget(id);
  vtkKWEPaintbrushWidget *paintbrush_widget = 
    vtkKWEPaintbrushWidget::SafeDownCast(interactor);
  int active = paintbrush_widget ? 1 : 0;

  if (active)
    {
    if (!this->PaintbrushWidgetEditor)
      {
      this->PaintbrushWidgetEditor = vtkVVPaintbrushWidgetEditor::New();
      this->PaintbrushWidgetEditor->SetParent(this->GetPagesParentWidget());
      this->PaintbrushWidgetEditor->Create();
      this->PaintbrushWidgetEditor->SetEnabled(this->GetEnabled());
      }

    this->PaintbrushWidgetEditor->SetPaintbrushWidget(paintbrush_widget);

    vtkVVSelectionFrame *sel_frame = 
      this->InteractorWidgetSelector->GetPresetSelectionFrame(id);
    this->PaintbrushWidgetEditor->SetImageWidget(
      vtkKWImageWidget::SafeDownCast(sel_frame->GetRenderWidget()));

    vtkKWWidget *page = this->GetPageWidget(this->PageId);
    this->Script("pack %s -side top -anchor nw -fill both -expand f -padx 2 -pady 2 -in %s", 
                 this->PaintbrushWidgetEditor->GetWidgetName(), 
                 page->GetWidgetName());
    }
  else
    {
    if (this->PaintbrushWidgetEditor)
      {
      this->Script("pack forget %s", 
                   this->PaintbrushWidgetEditor->GetWidgetName());
      }
    }
}

//---------------------------------------------------------------------------
void vtkVVWidgetInterface::UpdateEnableState()
{
  this->Superclass::UpdateEnableState();

  // Measurements

  if (this->InteractorWidgetFrame)
    {
    this->InteractorWidgetFrame->SetEnabled(this->GetEnabled());
    }

  if (this->InteractorWidgetSelector)
    {
    this->InteractorWidgetSelector->SetEnabled(this->GetEnabled());
    }

  // Property widgets
  
  if (this->SegmentationFrame)
    {
    this->SegmentationFrame->SetEnabled(this->GetEnabled());
    }

  if (this->PaintbrushWidgetEditor)
    {
    this->PaintbrushWidgetEditor->SetEnabled(this->GetEnabled());
    }
}

//---------------------------------------------------------------------------
void vtkVVWidgetInterface::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
}

