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

  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 "vtkKWLightboxWidget.h"

#include "vtkCallbackCommand.h"
#include "vtkCamera.h"
#include "vtkCellArray.h"
#include "vtkColorTransferFunction.h"
#include "vtkCornerAnnotation.h"
#include "vtkImageActor.h"
#include "vtkImageData.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper2D.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include "vtkRendererCollection.h"
#include "vtkSideAnnotation.h"
#include "vtkTextActor.h"

#include "vtkKW3DMarkersWidget.h"
#include "vtkKWEvent.h"
#include "vtkKWIcon.h"
#include "vtkKWGenericRenderWindowInteractor.h"
#include "vtkKWImageMapToWindowLevelColors.h"
#include "vtkKWInteractorStyleLightboxView.h"
#include "vtkKWInternationalization.h"
#include "vtkKWMenu.h"
#include "vtkKWScaleWithEntry.h"
#include "vtkKWWindow.h"

#include <vtksys/ios/sstream>

vtkStandardNewMacro(vtkKWLightboxWidget);
vtkCxxRevisionMacro(vtkKWLightboxWidget, "$Revision: 1.113 $");

#ifdef KWCommonPro_USE_XML_RW
#include "XML/vtkXMLKWLightboxWidgetReader.h"
#include "XML/vtkXMLKWLightboxWidgetWriter.h"
#endif
vtkKWGetXMLReaderWriterObjectsImplementationMacro(vtkKWLightboxWidget, vtkXMLKWLightboxWidgetReader, vtkXMLKWLightboxWidgetWriter);

//----------------------------------------------------------------------------
vtkKWLightboxWidget::vtkKWLightboxWidget()
{
  this->Resolution[0] = 2;
  this->Resolution[1] = 2;

  vtkPoints *pts = vtkPoints::New();
  vtkPolyData *pSource = vtkPolyData::New();
  pSource->SetPoints(pts);
  pts->Delete();
  vtkCellArray *lines = vtkCellArray::New();
  pSource->SetLines(lines);
  lines->Delete();
  pSource->GetPoints()->InsertNextPoint(0,0,0);
  pSource->GetPoints()->InsertNextPoint(1,0,0);
  pSource->GetPoints()->InsertNextPoint(1,1,0);
  pSource->GetPoints()->InsertNextPoint(0,1,0);  
  pSource->GetLines()->InsertNextCell(4);
  pSource->GetLines()->InsertCellPoint(0);
  pSource->GetLines()->InsertCellPoint(1);
  pSource->GetLines()->InsertCellPoint(2);
  pSource->GetLines()->InsertCellPoint(3);
  this->BoxFrame = vtkActor2D::New();
  vtkPolyDataMapper2D *pdm = vtkPolyDataMapper2D::New();
  vtkCoordinate *tcoord = vtkCoordinate::New();
  tcoord->SetCoordinateSystemToNormalizedViewport();
  pdm->SetTransformCoordinate(tcoord);
  tcoord->Delete();
  this->BoxFrame->SetMapper(pdm);
  pdm->SetInput(pSource);
  pdm->Delete();
  pSource->Delete();
  
  this->Images = NULL;
  this->NumberOfImages = 0;
  
  this->UpdateExtent[0] = 0;
  this->UpdateExtent[1] = 0;
  this->UpdateExtent[2] = 0;
  this->UpdateExtent[3] = 0;
  this->UpdateExtent[4] = 0;
  this->UpdateExtent[5] = 0;
  
  this->InteractorStyle = vtkKWInteractorStyleLightboxView::New();

  vtkRenderWindowInteractor *interactor = this->GetRenderWindowInteractor();
  if (interactor)
    {
    interactor->SetInteractorStyle(this->InteractorStyle);
    }
  
  this->InteractiveMap = vtkKWImageMapToWindowLevelColors::New();

  this->InteractorStyle->SetInteractiveMap(this->InteractiveMap);
  this->InteractorStyle->SetEventMap(this->EventMap);
}

//----------------------------------------------------------------------------
vtkKWLightboxWidget::~vtkKWLightboxWidget()
{
  if (this->BoxFrame)
    {
    this->BoxFrame->Delete();
    this->BoxFrame = NULL;
    }
  
  if (this->NumberOfImages)
    {
    for (int i = 0; i < this->NumberOfImages; i++)
      {
      if (this->Images[i])
        {
        this->Images[i]->Delete();
        this->Images[i] = NULL;
        }
      }
    delete [] this->Images;
    this->Images = 0;
    }
  
  if (this->InteractorStyle)
    {
    this->InteractorStyle->Delete();
    this->InteractorStyle = NULL;
    }

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

//----------------------------------------------------------------------------
void vtkKWLightboxWidget::SetResolution(int i, int j)
{
  if (i < 0 || j < 0 || 
      (i == this->Resolution[0] && j == this->Resolution[1]))
    {
    return;
    }

  this->Resolution[0] = i;
  this->Resolution[1] = j;

  this->Modified();

  this->UpdateResolution();

  this->InvokeEvent(
    vtkKWEvent::LightboxResolutionChangedEvent, this->Resolution);
}
  
//----------------------------------------------------------------------------
void vtkKWLightboxWidget::CreateDefaultRenderers()
{
  this->Superclass::CreateDefaultRenderers();

  double rgb[3], rgb2[3];
  this->GetRendererBackgroundColor(rgb, rgb + 1, rgb + 2);
  this->GetRendererBackgroundColor2(rgb2, rgb2 + 1, rgb2 + 2);
  int gb = this->GetRendererGradientBackground();

  // Check if we need to create more renderers to match the resolution

  int nb_renderers_required = this->Resolution[0] * this->Resolution[1];
  while (this->GetNumberOfRenderers() < nb_renderers_required)
    {
    vtkRenderer *ren = vtkRenderer::New();
    ren->SetActiveCamera(this->GetRenderer()->GetActiveCamera());
    ren->SetBackground(rgb);
    ren->SetBackground2(rgb2);
    ren->SetGradientBackground(gb ? true : false);
    this->AddRenderer(ren);
    ren->Delete();
    }

  // Make sure we have all the actors

  for (int i = 0; i < nb_renderers_required; i++)
    {
    vtkRenderer *ren = this->GetNthRenderer(i);
    if (ren)
      {
      ren->AddViewProp(this->BoxFrame);
      if (this->CornerAnnotation->GetVisibility())
        {
        ren->AddViewProp(this->CornerAnnotation);
        }
      if (this->SideAnnotation->GetVisibility())
        {
        ren->AddViewProp(this->SideAnnotation);
        }
      if (this->HeaderAnnotation->GetVisibility())
        {
        ren->AddViewProp(this->HeaderAnnotation);
        }
      }
    }
}

//----------------------------------------------------------------------------
void vtkKWLightboxWidget::InstallRenderers()
{
  this->Superclass::InstallRenderers();

  // Do not bother installing if we do not have the right number of 
  // renderers yet

  int nb_renderers_required = this->Resolution[0] * this->Resolution[1];
  if (this->GetNumberOfRenderers() >= nb_renderers_required)
    {
    for (int idx1 = 0; idx1 < this->Resolution[1]; idx1++)
      {
      for (int idx2 = 0; idx2 < this->Resolution[0]; idx2++)
        {
        int idx = idx1 * this->Resolution[0] + idx2;
        vtkRenderer *ren = this->GetNthRenderer(idx);
        if (ren)
          {
          ren->SetViewport(
            static_cast<double>(idx2) / this->Resolution[0],
            static_cast<double>(this->Resolution[1] - idx1 - 1) / 
            this->Resolution[1],
            static_cast<double>(idx2 + 1) / this->Resolution[0],
            static_cast<double>(this->Resolution[1] - idx1) / 
            this->Resolution[1]);
          }
        }
      }
    }
}

//----------------------------------------------------------------------------
void vtkKWLightboxWidget::UpdateResolution()
{
  int idx1, idx2, idx;

  // Free the old images

  if (this->Images)
    {
    for (idx = 0; idx < this->NumberOfImages; idx++)
      {
      this->Images[idx]->Delete();
      }
    delete [] this->Images;
    }

  // Allocate more renderers if needed

  this->RemoveAllRenderers();
  this->CreateDefaultRenderers();
  this->SetRenderersDefaultValues();

  // Install the renderers

  this->InstallRenderers();

  // Setup the image actor in each renderer

  int nb_renderers_required = this->Resolution[0] * this->Resolution[1];
  if (nb_renderers_required)
    {
    this->NumberOfImages = nb_renderers_required;
    this->Images = new vtkImageActor *[this->NumberOfImages];
    this->InteractorStyle->SetImageActors(this->Images);
    for (idx1 = 0; idx1 < this->Resolution[1]; idx1++)
      {
      for (idx2 = 0; idx2 < this->Resolution[0]; idx2++)
        {
        idx = idx1 * this->Resolution[0] + idx2;
        this->Images[idx] = vtkImageActor::New();
        this->AddViewPropToNthRenderer(this->Images[idx], idx);
        }
      }
    }

  // Make sure the pipeline is completely connected

  this->ConnectInternalPipeline();

  this->CornerAnnotation->Modified();

  if (this->Input)
    {
    this->SetSlice(this->GetSlice());
    }

  this->UpdateDisplayExtent();
  this->ResetCamera(); // Do not remove, see 1.90 commit

  this->Render();
}

//----------------------------------------------------------------------------
int vtkKWLightboxWidget::ConnectInternalPipeline()
{
  // Have a look at the documentation for this method (see .h).

  if (!this->Superclass::ConnectInternalPipeline())
    {
    return 0;
    }

  // Connect all the images

  vtkKWImageMapToWindowLevelColors *map = this->GetImageMapToRGBA();
  if (map)
    {
    for (int idx = 0; idx < this->NumberOfImages; idx++)
      {
      if (this->Images && this->Images[idx])
        {
        if (map->GetInput())
          {
          this->Images[idx]->SetInput(map->GetOutput());
          }
        else
          {
          this->Images[idx]->SetInput(NULL);
          }
        this->Images[idx]->Modified();
        }
      }

    if (this->InteractorStyle)
      {
      this->InteractorStyle->SetImageMapToRGBA(map);
      }
    }

  return 1;
}

//----------------------------------------------------------------------------
void vtkKWLightboxWidget::UpdateColorMapping()
{
  if (!this->Input || !this->InteractiveMap)
    {
    return;
    }

  vtkKWImageMapToWindowLevelColors *map = this->GetImageMapToRGBA();
  if (!map)
    {
    return;
    }

  this->Superclass::UpdateColorMapping();

  // The interactive map should reflect our image map

  this->InteractiveMap->SetIndependentComponents(
    map->GetIndependentComponents());

  this->InteractiveMap->SetUseOpacityModulation(
    map->GetUseOpacityModulation());

  this->InteractiveMap->SetDisplayChannels(
    map->GetDisplayChannels());
  
  for (int comp = 0; comp < VTK_MAX_VRCOMP; comp++)
    {
    this->InteractiveMap->SetLookupTable(
      comp, map->GetLookupTable(comp));
    this->InteractiveMap->SetWeight(
      comp, map->GetWeight(comp));
    }
}

//----------------------------------------------------------------------------
void vtkKWLightboxWidget::UpdateDisplayExtent()
{
  if (!this->Input)
    {
    return;
    }

  // Go to the default slice if we are just out of the range
  // - GoToDefaultSlice() will call UpdateDisplayExtent()

  if (this->HasSliceControl && !this->IsSliceInRange(this->GetSlice()))
    {
    this->UpdateSliceScale();
    this->GoToDefaultSlice();
    return;
    }

  int slice = this->GetSlice();

  int display_extent[6];
  int *wExt = this->Input->GetWholeExtent();
  int j;
  int snum = 0;
  for (j = 0; j < this->NumberOfImages; ++j)
    {
    if (this->Images && this->Images[j])
      {
      snum = slice + j;
      if (snum > wExt[this->SliceOrientation * 2 + 1])
        {
        snum = wExt[this->SliceOrientation * 2 + 1];
        }
      this->GetSliceDisplayExtent(snum, display_extent);
      this->Images[j]->SetDisplayExtent(display_extent);
      }
    }

  this->UpdateExtent[0] = 
    this->SliceOrientation != vtkKW2DRenderWidget::SLICE_ORIENTATION_YZ ? 
    wExt[0] : slice;
  this->UpdateExtent[1] = 
    this->SliceOrientation != vtkKW2DRenderWidget::SLICE_ORIENTATION_YZ ? 
    wExt[1] : snum;
  this->UpdateExtent[2] = 
    this->SliceOrientation != vtkKW2DRenderWidget::SLICE_ORIENTATION_XZ ? 
    wExt[2] : slice;
  this->UpdateExtent[3] = 
    this->SliceOrientation != vtkKW2DRenderWidget::SLICE_ORIENTATION_XZ ? 
    wExt[3] : snum;
  this->UpdateExtent[4] = 
    this->SliceOrientation != vtkKW2DRenderWidget::SLICE_ORIENTATION_XY ? 
    wExt[4] : slice;
  this->UpdateExtent[5] = 
    this->SliceOrientation != vtkKW2DRenderWidget::SLICE_ORIENTATION_XY ? 
    wExt[5] : snum;
  
  this->UpdateImageMap();
}

//----------------------------------------------------------------------------
void vtkKWLightboxWidget::UpdateImageMap()
{
  vtkKWImageMapToWindowLevelColors *map = this->GetImageMapToRGBA();
  if (map && map->GetInput() && map->GetOutput())
    {
    vtkImageData *output = map->GetOutput();
    output->UpdateInformation();
    map->SetMinimumUpdateExtent(this->UpdateExtent);
    if (vtkMath::ExtentIsWithinOtherExtent(
          this->UpdateExtent, output->GetWholeExtent()))
      {
      output->SetUpdateExtent(this->UpdateExtent);
      output->PropagateUpdateExtent();
      }
    }

  this->Superclass::UpdateImageMap();
}

//----------------------------------------------------------------------------
void vtkKWLightboxWidget::SetSlice(int slice)
{
  if (!this->Input)
    {
    return;
    }
  
  this->Input->UpdateInformation();
  int *wExt = this->Input->GetWholeExtent();
  
  if (slice < wExt[this->SliceOrientation * 2])
    {
    slice = wExt[this->SliceOrientation * 2];
    }
  else if (slice > (wExt[this->SliceOrientation * 2 + 1] - 
                    this->NumberOfImages + 1))
    {
    slice = wExt[this->SliceOrientation * 2 + 1] - this->NumberOfImages + 1;
    if (slice < wExt[this->SliceOrientation * 2])
      {
      slice = wExt[this->SliceOrientation * 2];
      }
    }

  // Just set the value of the slider, don't invoke anything

  int disabled = this->SliceScale->GetDisableCommands();
  this->SliceScale->DisableCommandsOn();
  this->SliceScale->SetValue(slice);
  this->SliceScale->SetDisableCommands(disabled);
  
  this->UpdateDisplayExtent();
  
  this->Render();
}

//----------------------------------------------------------------------------
void vtkKWLightboxWidget::SliceSelectedCallback(double value)
{
  this->Superclass::SliceSelectedCallback(value);

  int args[2];
  args[0] = this->GetSlice();
  args[1] = this->InteractorStyle->GetEventIdentifier();
  this->InvokeEvent(vtkKWEvent::ImageSliceChangedEvent, args);
}

//----------------------------------------------------------------------------
void vtkKWLightboxWidget::IncrementPage()
{
  this->SetSlice(this->GetSlice() + this->NumberOfImages);
}

//----------------------------------------------------------------------------
void vtkKWLightboxWidget::DecrementPage()
{
  this->SetSlice(this->GetSlice() - this->NumberOfImages);
}

//----------------------------------------------------------------------------
int vtkKWLightboxWidget::GoToDefaultSlice()
{
  this->SetSlice(0);
  return this->GetSlice();
}

//----------------------------------------------------------------------------
int vtkKWLightboxWidget::ComputeWorldCoordinate(
  int x, int y, double *result, int *id)
{
  int *size = this->RenderWindow->GetSize();
  
  // Find the poked viewport

  int xpos = (this->Resolution[0]*x)/size[0];
  if (xpos >= this->Resolution[0] || xpos < 0)
    {
    return 0;
    }

  int ypos = (this->Resolution[1]*y)/size[1];
  if (ypos >= this->Resolution[1] || ypos < 0)
    {
    return 0;
    }
  ypos = this->Resolution[1] - ypos - 1;
  
  int renNum = ypos*this->Resolution[0] + xpos;
  if (id)
    {
    *id = renNum;
    }

  if (!this->Images || 
      !this->Images[renNum] || 
      !this->Images[renNum]->GetInput())
    {
    return 0;
    }

  // Convert 0,0,0 into display coordinates to get the depth

  double *bnds = this->Images[renNum]->GetBounds();
  vtkRenderer *ren = this->GetNthRenderer(renNum);
  ren->SetWorldPoint(bnds[0], bnds[2], bnds[4], 1.0);
  ren->WorldToDisplay();
  double *DPoint = ren->GetDisplayPoint();
  double focalDepth = DPoint[2];
  
  // Convert the x,y probe location to world coordinates using the
  // computed depth

  ren->SetDisplayPoint(x, y, focalDepth);
  ren->DisplayToWorld();
  double *RPoint = ren->GetWorldPoint();
  if (RPoint[3] != 0.0)
    {
    RPoint[0] = (double)((double)RPoint[0] / (double)RPoint[3]);
    RPoint[1] = (double)((double)RPoint[1] / (double)RPoint[3]);
    RPoint[2] = (double)((double)RPoint[2] / (double)RPoint[3]);
    }

  int idx1 = (this->SliceOrientation + 1) % 3;
  int idx2 = (this->SliceOrientation + 2) % 3;
  
  // Do a quick check to make sure we are in the image

  if (RPoint[idx1] < bnds[idx1 * 2] || 
      RPoint[idx1] > bnds[idx1 * 2 + 1] ||
      RPoint[idx2] < bnds[idx2 * 2] || 
      RPoint[idx2] > bnds[idx2 * 2 + 1])
    {
    return 0;
    }

  if (result)
    {
    result[0] = RPoint[0];
    result[1] = RPoint[1];
    result[2] = RPoint[2];
    }

  return 1;
}

//----------------------------------------------------------------------------
void vtkKWLightboxWidget::CreateWidget()
{
  if (this->IsCreated())
    {
    vtkErrorMacro("widget already created " << this->GetClassName());
    return;
    }

  this->Superclass::CreateWidget();

  this->UpdateResolution();

  this->UpdateAccordingToUnits();
}

//----------------------------------------------------------------------------
void vtkKWLightboxWidget::SetMarkers3DVisibility(int v)
{
  if (this->GetMarkers3DVisibility() == v)
    {
    return;
    }

  // always be disabled
  this->Markers3D->SetEnabled(0);
}

//----------------------------------------------------------------------------
vtkKWInteractorStyle2DView* vtkKWLightboxWidget::GetInteractorStyle()
{
  return this->InteractorStyle; 
}

//----------------------------------------------------------------------------
void vtkKWLightboxWidget::SetInterpolate(int state)
{
  if (this->GetInterpolate() != state)
    {
    for (int i = 0; i < this->NumberOfImages; i++)
      {
      this->Images[i]->SetInterpolate(state);
      }
    this->Render();
    this->InvokeEvent(vtkKWEvent::ImageInterpolateEvent, &state);
    }
}

//----------------------------------------------------------------------------
int vtkKWLightboxWidget::GetInterpolate()
{
  return this->NumberOfImages ? this->Images[0]->GetInterpolate() : 0;
}

//----------------------------------------------------------------------------
void vtkKWLightboxWidget::PopulateContextMenuWithOptionEntries(vtkKWMenu *menu)
{
  this->Superclass::PopulateContextMenuWithOptionEntries(menu);

  if (!menu)
    {
    return;
    }

  int tcl_major, tcl_minor, tcl_patch_level;
  Tcl_GetVersion(&tcl_major, &tcl_minor, &tcl_patch_level, NULL);
  int show_icons = (tcl_major > 8 || (tcl_major == 8 && tcl_minor >= 5));

  int index, cascade_index;

  // Resolution

  vtkKWMenu *columns_menu = vtkKWMenu::New();
  columns_menu->SetParent(this->ContextMenu);
  columns_menu->Create();

  int column;
  for (column = 1; column < 6; column++)
    {
    vtksys_ios::ostringstream cmd_name;
    cmd_name << column;

    vtksys_ios::ostringstream cmd;
    cmd << "SetResolution " << column << " " << this->Resolution[1];

    // Add a new entry
    // If the entry we have added match the current value, select it

    cascade_index = columns_menu->AddRadioButton(
      cmd_name.str().c_str(), this, cmd.str().c_str());
    columns_menu->SetItemSelectedValueAsInt(cascade_index, column);
    }

  columns_menu->SelectItemWithSelectedValueAsInt(this->Resolution[0]);

  index = menu->AddCascade(k_("Columns"), columns_menu);
  if (show_icons)
    {
    menu->SetItemImageToPredefinedIcon(
      index, vtkKWIcon::IconColumns);
    menu->SetItemCompoundModeToLeft(index);
    }
  columns_menu->Delete();

  vtkKWMenu *rows_menu = vtkKWMenu::New();
  rows_menu->SetParent(this->ContextMenu);
  rows_menu->Create();

  int row;
  for (row = 1; row < 6; row++)
    {
    vtksys_ios::ostringstream cmd_name;
    cmd_name << row;

    vtksys_ios::ostringstream cmd;
    cmd << "SetResolution " << this->Resolution[0] << " " << row;

    // Add a new entry
    // If the entry we have added match the current value, select it

    cascade_index = rows_menu->AddRadioButton(
      cmd_name.str().c_str(), this, cmd.str().c_str());
    rows_menu->SetItemSelectedValueAsInt(cascade_index, row);
    }
  
  rows_menu->SelectItemWithSelectedValueAsInt(this->Resolution[1]);

  index = menu->AddCascade(k_("Rows"), rows_menu);
  if (show_icons)
    {
    menu->SetItemImageToPredefinedIcon(
      index, vtkKWIcon::IconRows);
    menu->SetItemCompoundModeToLeft(index);
    }
  rows_menu->Delete();
}

//----------------------------------------------------------------------------
void vtkKWLightboxWidget::PopulateContextMenuWithCameraEntries(vtkKWMenu *menu)
{
  this->Superclass::PopulateContextMenuWithCameraEntries(menu);

  if (!menu)
    {
    return;
    }

  int tcl_major, tcl_minor, tcl_patch_level;
  Tcl_GetVersion(&tcl_major, &tcl_minor, &tcl_patch_level, NULL);
  int show_icons = (tcl_major > 8 || (tcl_major == 8 && tcl_minor >= 5));

  int index, cascade_index;

  // Slice Orientation

  vtkKWMenu *orientation_menu = vtkKWMenu::New();
  orientation_menu->SetParent(this->ContextMenu);
  orientation_menu->Create();

  int orientations[] = 
    { 
    vtkKW2DRenderWidget::SLICE_ORIENTATION_XY,
    vtkKW2DRenderWidget::SLICE_ORIENTATION_XZ,
    vtkKW2DRenderWidget::SLICE_ORIENTATION_YZ
    };

  int is_medical = 
    this->GetSliceType() == vtkKW2DRenderWidget::SLICE_TYPE_MEDICAL;

  int i;
  for (i = 0; i < sizeof(orientations) / sizeof(orientations[0]); i++)
    {
    const char *cmd_name;
    if (is_medical)
      {
      cmd_name = 
        vtkKW2DRenderWidget::GetSliceOrientationAsMedicalOrientationString(
          orientations[i]);
      }
    else
      {
      cmd_name = 
        vtkKW2DRenderWidget::GetSliceOrientationAsDefaultOrientationString(
          orientations[i]);
      }

    vtksys_ios::ostringstream cmd;
    cmd << "SetSliceOrientation " << orientations[i];

    // Add a new entry
    // If the entry we have added match the current value, select it

    cascade_index = orientation_menu->AddRadioButton(
      cmd_name, this, cmd.str().c_str());
    orientation_menu->SetItemSelectedValueAsInt(cascade_index, orientations[i]);
    }

  orientation_menu->SelectItemWithSelectedValueAsInt(
    this->GetSliceOrientation());
  
  index = menu->AddCascade(k_("Slice Orientation"), orientation_menu);
  if (show_icons)
    {
    menu->SetItemImageToPredefinedIcon(
      index, vtkKWIcon::IconStandardView);
    menu->SetItemCompoundModeToLeft(index);
    }
  orientation_menu->Delete();
}

//----------------------------------------------------------------------------
void vtkKWLightboxWidget::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  
  os << indent << "Resolution: " << this->Resolution << endl;
  os << indent << "InteractorStyle: " << this->InteractorStyle << endl;
}
