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

  Program:   ParaView
  Module:    vtkPVRenderView.cxx

  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.

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

#include "vtkSMRenderModuleProxy.h"
#include "vtkCornerAnnotation.h"
#include "vtkInstantiator.h"
#include "vtkBMPWriter.h"
#include "vtkCamera.h"
#include "vtkCollectionIterator.h"
#include "vtkCallbackCommand.h"
#include "vtkCommand.h"
#include "vtkErrorCode.h"
#include "vtkImageData.h"
#include "vtkInteractorObserver.h"
#include "vtkJPEGWriter.h"
#include "vtkKWChangeColorButton.h"
#include "vtkKWCheckButton.h"
#include "vtkPVCornerAnnotationEditor.h"
#include "vtkKWFrame.h"
#include "vtkKWFrameWithScrollbar.h"
#include "vtkKWLabel.h"
#include "vtkKWFrameWithLabel.h"
#include "vtkKWMenu.h"
#include "vtkKWMessageDialog.h"
#include "vtkKWNotebook.h"
#include "vtkPVSourceNotebook.h"
#include "vtkKWPushButton.h"
#include "vtkKWRadioButton.h"
#include "vtkKWScaleWithEntry.h"
#include "vtkKWSplitFrame.h"
#include "vtkObjectFactory.h"
#include "vtkPNGWriter.h"
#include "vtkPNMWriter.h"
#include "vtkPVApplication.h"
#include "vtkPVAxesWidget.h"
#include "vtkPVCameraControl.h"
#include "vtkPVCameraIcon.h"
#include "vtkPVDataInformation.h"
#include "vtkPVGenericRenderWindowInteractor.h"
#include "vtkPVInteractorStyleControl.h"
#include "vtkPVNavigationWindow.h"
#include "vtkSMPart.h"
#include "vtkPVProcessModule.h"
#include "vtkPVRenderModuleUI.h"
#include "vtkPVRenderView.h"
#include "vtkPVSource.h"
#include "vtkPVSourceCollection.h"
#include "vtkPVSourceList.h"
#include "vtkPVWindow.h"
#include "vtkPostScriptWriter.h"
#include "vtkRenderer.h"
#include "vtkRendererCollection.h"
#include "vtkRenderWindow.h"
#include "vtkTIFFWriter.h"
#include "vtkTimerLog.h"
#include "vtkToolkits.h"
#include "vtkWindowToImageFilter.h"
#include "vtkClientServerStream.h"
#include "vtkPVOptions.h"
#include "vtkPVTraceHelper.h"
#include "vtkKWEntry.h"
#include "vtkLightKit.h"
#include "vtkSMProxy.h"
#include "vtkSMProxyManager.h"
#include "vtkSMProperty.h"
#include "vtkSMDoubleVectorProperty.h"
#include "vtkSMIntVectorProperty.h"
#include "vtkSMDoubleRangeDomain.h"
#include "vtkKWTopLevel.h"

#include <vtkstd/string>
#include "vtkSMRenderModuleProxy.h"
#include "vtkSMIntVectorProperty.h"
#include <vtksys/SystemTools.hxx>

#ifdef _WIN32
#include "vtkWin32OpenGLRenderWindow.h"
#else
#include "vtkOpenGLRenderWindow.h"
#include "vtkOpenGLRenderer.h"
#endif

#define VTK_PV_NAV_FRAME_SIZE_REG_KEY "NavigationFrameSize"
#define VTK_PV_USE_LIGHT_KIT_REG_KEY "UseLightKit"
#define VTK_PV_ENABLE_DEFAULT_LIGHT_REG_KEY "EnableDefaultLight"
#define VTK_PV_DEFAULT_LIGHT_INTENSITY_REG_KEY "DefaultLightIntensity"
#define VTK_PV_MAINTAIN_LUMINANCE_REG_KEY "MaintainLuminance"

/* 
 * This part was generated by ImageConvert from image:
 *    properties.png (zlib, base64)
 */
#define image_properties_width         16
#define image_properties_height        14
#define image_properties_pixel_size    4
#define image_properties_length 140

static unsigned char image_properties[] = 
  "eNrdkcENgDAMAxk9gzBMRmCjACqR3NSO4Islv5pz3dTdNxe+FMzjzOJ2x8axU48czSfbZ9"
  "jjtR+yKgP5lGJrBvZPfpoVWWx/OI9dVOa8J1uYqvo+uuuX6njsT//kx/d/ceVPtN4Pmg==";

//===========================================================================
//***************************************************************************
class vtkPVRenderViewObserver : public vtkCommand
{
public:
  static vtkPVRenderViewObserver *New() 
    {return new vtkPVRenderViewObserver;};

  vtkPVRenderViewObserver()
    {
      this->PVRenderView = 0;
    }

  virtual void Execute(vtkObject* wdg, unsigned long event,  
                       void* calldata)
    {
      if ( this->PVRenderView )
        {
        this->PVRenderView->ExecuteEvent(wdg, event, calldata);
        this->AbortFlagOn();
        }
    }

  vtkPVRenderView* PVRenderView;
};
//***************************************************************************
//===========================================================================

//----------------------------------------------------------------------------
vtkStandardNewMacro(vtkPVRenderView);
vtkCxxRevisionMacro(vtkPVRenderView, "1.405");

//----------------------------------------------------------------------------
vtkPVRenderView::vtkPVRenderView()
{
  this->RenderModuleProxy = 0;

  if (getenv("PV_SEPARATE_RENDER_WINDOW") != NULL)
    {
    this->TopLevelRenderWindow = vtkKWTopLevel::New();
    this->TopLevelRenderWindow->SetParent(this->Frame);
    this->VTKWidget->SetParent(NULL);
    this->VTKWidget->SetParent(this->TopLevelRenderWindow);
    }
  else
    {
    this->TopLevelRenderWindow = NULL;
    }    

  this->SplitFrame = vtkKWSplitFrame::New();

  this->BlockRender = 0;

  this->MenuEntryUnderline = 4;
  this->SetMenuEntryName(VTK_PV_VIEW_MENU_LABEL);
  this->SetMenuEntryHelp("Show global view parameters (background color, annoations2 etc.)");

  this->StandardViewsFrame = vtkKWFrameWithLabel::New();
  this->XMaxViewButton = vtkKWPushButton::New();
  this->XMinViewButton = vtkKWPushButton::New();
  this->YMaxViewButton = vtkKWPushButton::New();
  this->YMinViewButton = vtkKWPushButton::New();
  this->ZMaxViewButton = vtkKWPushButton::New();
  this->ZMinViewButton = vtkKWPushButton::New();
  
  this->RenderParametersFrame = vtkKWFrameWithLabel::New();

  this->TriangleStripsCheck = vtkKWCheckButton::New();
  this->ParallelProjectionCheck = vtkKWCheckButton::New();
  this->ImmediateModeCheck = vtkKWCheckButton::New();

  this->RenderModuleUI = NULL;
 
  this->ManipulatorControl2D = vtkPVInteractorStyleControl::New();
  this->ManipulatorControl2D->SetRegistryName("2D");
  this->ManipulatorControl3D = vtkPVInteractorStyleControl::New();
  this->ManipulatorControl3D->SetRegistryName("3D");

  this->CameraControlFrame = vtkKWFrameWithLabel::New();
  this->CameraControl = vtkPVCameraControl::New();
  
  this->NavigationFrame = vtkKWFrameWithLabel::New();
  this->NavigationWindow = vtkPVNavigationWindow::New();
  this->SelectionWindow = vtkPVSourceList::New();

  this->NavigationWindowButton = vtkKWRadioButton::New();
  this->SelectionWindowButton = vtkKWRadioButton::New();

  this->ShowSelectionWindow = 0;
  this->ShowNavigationWindow = 0;

  this->InterfaceSettingsFrame = vtkKWFrameWithLabel::New();
  this->Display3DWidgets = vtkKWCheckButton::New();

  // Light
  this->DefaultLightFrame         = vtkKWFrameWithLabel::New();
  this->DefaultLightAmbientColor  = vtkKWChangeColorButton::New();
  this->DefaultLightSpecularColor = vtkKWChangeColorButton::New();
  this->DefaultLightDiffuseColor  = vtkKWChangeColorButton::New();
  this->DefaultLightIntensity     = vtkKWScaleWithEntry::New();
  this->DefaultLightSwitch        = vtkKWCheckButton::New();

  // Light kit
  this->LightParameterFrame = vtkKWFrameWithLabel::New();
  this->UseLightButton      = vtkKWCheckButton::New();
  this->KeyLightLabel       = vtkKWLabel::New();
  this->FillLightLabel      = vtkKWLabel::New();
  this->BackLightLabel      = vtkKWLabel::New();
  this->HeadLightLabel      = vtkKWLabel::New();
  int cc;
  for ( cc = 0; cc < 4; cc ++ )
    {
    this->KeyLightScale[cc]  = vtkKWScaleWithEntry::New();
    this->FillLightScale[cc] = vtkKWScaleWithEntry::New();
    this->BackLightScale[cc] = vtkKWScaleWithEntry::New();
    this->HeadLightScale[cc] = vtkKWScaleWithEntry::New();
    }
  this->MaintainLuminanceButton = vtkKWCheckButton::New(); 

  this->OrientationAxesFrame = vtkKWFrameWithLabel::New();
  this->OrientationAxesCheck = vtkKWCheckButton::New();
  this->OrientationAxesInteractiveCheck = vtkKWCheckButton::New();
  this->OrientationAxesOutlineColor = vtkKWChangeColorButton::New();
  this->OrientationAxesTextColor = vtkKWChangeColorButton::New();
  this->OrientationAxes = vtkPVAxesWidget::New();

  for ( cc = 0; cc < 6; cc ++ )
    {
    this->CameraIcons[cc] = vtkPVCameraIcon::New();
    }
  this->CameraIconsFrame = vtkKWFrameWithLabel::New();

  this->PropertiesButton = vtkKWPushButton::New();
  this->MenuLabelSwitchBackAndForthToViewProperties = 0;

  this->Observer = vtkPVRenderViewObserver::New();
  this->Observer->PVRenderView = this;
  
  this->RenderTimer = vtkTimerLog::New();
  this->TimerToken = NULL;

  this->SourceNotebook = 0;
}



//----------------------------------------------------------------------------
void vtkPVRenderView::AddAnnotationProp(vtkPVCornerAnnotationEditor *c)  
{  
  this->GetRenderer2D()->AddViewProp(c->GetCornerAnnotation());  
}  
   
//----------------------------------------------------------------------------
void vtkPVRenderView::RemoveAnnotationProp(vtkPVCornerAnnotationEditor *c)  
{  
  this->GetRenderer2D()->RemoveViewProp(c->GetCornerAnnotation());  
}  

//----------------------------------------------------------------------------
vtkRenderWindow* vtkPVRenderView::GetRenderWindow()
{
  if (this->RenderModuleProxy == 0)
    {
    vtkErrorMacro("Missing renderModule.");
    return NULL;
    }
  return this->RenderModuleProxy->GetRenderWindow();
}

//----------------------------------------------------------------------------
vtkRenderer* vtkPVRenderView::GetRenderer()
{
  if (this->RenderModuleProxy == 0)
    {
    vtkErrorMacro("Missing renderModule.");
    return NULL;
    }
  return this->RenderModuleProxy->GetRenderer();
}

//----------------------------------------------------------------------------
vtkRenderer* vtkPVRenderView::GetRenderer2D()
{
  if (this->RenderModuleProxy == 0)
    {
    vtkErrorMacro("Missing renderModule.");
    return NULL;
    }
  return this->RenderModuleProxy->GetRenderer2D();
}

//----------------------------------------------------------------------------
void vtkPVRenderView::ShowNavigationWindowCallback(int registry)
{
  if (!this->GetApplication())
    {
    return;
    }
  
  this->GetTraceHelper()->AddEntry("$kw(%s) ShowNavigationWindowCallback %d",
                      this->GetTclName(), registry);
  
  this->Script("catch {eval pack forget [pack slaves %s]}",
               this->NavigationFrame->GetFrame()->GetWidgetName());
  this->Script("pack %s -fill both -expand t -side top -anchor n", 
               this->NavigationWindow->GetWidgetName());
  this->NavigationFrame->SetLabelText("Navigation Window");
  this->ShowSelectionWindow = 0;
  this->ShowNavigationWindow = 1;

  this->NavigationWindowButton->SelectedStateOn();
  this->SelectionWindowButton->SelectedStateOff();
  if ( registry )
    {
    this->GetApplication()->SetRegistryValue(2, "RunTime","SourcesBrowser",
                                         "NavigationWindow");
    }
}

//----------------------------------------------------------------------------
void vtkPVRenderView::ShowSelectionWindowCallback(int registry)
{
  if ( !this->GetApplication() )
    {
    return;
    }
  
  this->GetTraceHelper()->AddEntry("$kw(%s) ShowSelectionWindowCallback %d",
                      this->GetTclName(), registry);
  
  this->Script("catch {eval pack forget [pack slaves %s]}",
               this->NavigationFrame->GetFrame()->GetWidgetName());
  this->Script("pack %s -fill both -expand t -side top -anchor n", 
               this->SelectionWindow->GetWidgetName());
  this->NavigationFrame->SetLabelText("Selection Window");
  this->ShowNavigationWindow = 0;
  this->ShowSelectionWindow = 1;

  this->NavigationWindowButton->SelectedStateOff();
  this->SelectionWindowButton->SelectedStateOn();
  if ( registry )
    {
    this->GetApplication()->SetRegistryValue(2, "RunTime","SourcesBrowser",
                                         "SelectionWindow");
    }
}

//----------------------------------------------------------------------------
vtkPVRenderView::~vtkPVRenderView()
{
  this->InterfaceSettingsFrame->Delete();
  this->Display3DWidgets->Delete();
  this->Display3DWidgets = NULL;

  this->DefaultLightFrame->Delete();
  this->DefaultLightAmbientColor->Delete();
  this->DefaultLightSpecularColor->Delete();
  this->DefaultLightDiffuseColor->Delete();
  this->DefaultLightIntensity->Delete();
  this->DefaultLightSwitch->Delete();

  this->LightParameterFrame->Delete();
  this->UseLightButton->Delete();
  this->KeyLightLabel->Delete();
  this->FillLightLabel->Delete();
  this->BackLightLabel->Delete();
  this->HeadLightLabel->Delete();
  int cc;
  for ( cc = 0; cc < 4; cc ++ )
    {
    this->KeyLightScale[cc]->Delete();
    this->FillLightScale[cc]->Delete();
    this->BackLightScale[cc]->Delete();
    this->HeadLightScale[cc]->Delete();
    }
  this->MaintainLuminanceButton->Delete(); 

  this->OrientationAxesFrame->Delete();
  this->OrientationAxesCheck->Delete();
  this->OrientationAxesInteractiveCheck->Delete();
  this->OrientationAxesOutlineColor->Delete();
  this->OrientationAxesTextColor->Delete();
  this->OrientationAxes->Delete();
  
  if ( this->SelectionWindow )
    {
    this->SelectionWindow->Delete();
    }
  this->SplitFrame->Delete();
  this->SplitFrame = NULL;
 
  this->NavigationFrame->Delete();
  this->NavigationFrame = NULL;
 
  this->NavigationWindowButton->Delete();
  this->SelectionWindowButton->Delete();

  this->NavigationWindow->Delete();
  this->NavigationWindow = NULL;

  // undo the binding we set up
  if ( this->IsCreated() )
    {
    this->Script("bind %s <Motion> {}", this->VTKWidget->GetWidgetName());
    }

  if (this->TopLevelRenderWindow)
    {
    this->TopLevelRenderWindow->Delete();
    this->TopLevelRenderWindow = NULL;
    }
  
  this->StandardViewsFrame->Delete();
  this->StandardViewsFrame = NULL;
  this->XMaxViewButton->Delete();
  this->XMaxViewButton = NULL;
  this->XMinViewButton->Delete();
  this->XMinViewButton = NULL;
  this->YMaxViewButton->Delete();
  this->YMaxViewButton = NULL;
  this->YMinViewButton->Delete();
  this->YMinViewButton = NULL;
  this->ZMaxViewButton->Delete();
  this->ZMaxViewButton = NULL;
  this->ZMinViewButton->Delete();
  this->ZMinViewButton = NULL;

  this->RenderParametersFrame->Delete();
  this->RenderParametersFrame = 0;

  this->ParallelProjectionCheck->Delete();
  this->ParallelProjectionCheck = NULL;

  this->TriangleStripsCheck->Delete();
  this->TriangleStripsCheck = NULL;

  this->ImmediateModeCheck->Delete();
  this->ImmediateModeCheck = NULL;


  this->ManipulatorControl2D->Delete();
  this->ManipulatorControl3D->Delete();

  this->CameraControlFrame->Delete();
  this->CameraControl->Delete();
  
  this->CameraIconsFrame->Delete();
  this->CameraIconsFrame = 0;
  for ( cc = 0; cc < 6; cc ++ )
    {
    if ( this->CameraIcons[cc] )
      {
      this->CameraIcons[cc]->SetRenderView(0);
      this->CameraIcons[cc]->Delete();
      this->CameraIcons[cc] = 0;
      }
    }

  this->Observer->Delete();
  this->Observer = NULL;

  this->PropertiesButton->Delete();
  this->PropertiesButton = NULL;
  this->SetMenuLabelSwitchBackAndForthToViewProperties(NULL);
  
  this->RenderTimer->Delete();
  if (this->TimerToken)
    {
    Tcl_DeleteTimerHandler( this->TimerToken );
    this->TimerToken = NULL;
    }
    
  if (this->SourceNotebook)
    {
    this->SourceNotebook->SetParent(0);
    this->SourceNotebook->Delete();
    this->SourceNotebook = 0;
    }
}

//----------------------------------------------------------------------------
void PVRenderViewAbortCheck(vtkObject*, unsigned long, void* arg, void*)
{
  vtkPVRenderView *me = (vtkPVRenderView*)arg;
  int abort;

  // if we are printing then do not abort
  if (me->GetPrinting())
    {
    return;
    }
  
  abort = me->ShouldIAbort();
  if (abort == 1)
    {
    me->GetRenderWindow()->SetAbortRender(1);
    me->EventuallyRender();
    }
  if (abort == 2)
    {
    me->GetRenderWindow()->SetAbortRender(2);
    }
}

//----------------------------------------------------------------------------
void vtkPVRenderView::CreateRenderObjects(vtkPVApplication *)
{
  // Create the call back that looks for events to abort rendering.
  this->RenderModuleProxy->RemoveObservers(vtkCommand::AbortCheckEvent);
  vtkCallbackCommand* abc = vtkCallbackCommand::New();
  abc->SetCallback(PVRenderViewAbortCheck);
  abc->SetClientData(this);
  this->RenderModuleProxy->AddObserver(vtkCommand::AbortCheckEvent, abc);
  abc->Delete();
}


//----------------------------------------------------------------------------
// Here we are going to change only the satellite procs.
void vtkPVRenderView::PrepareForDelete()
{
  // Get rid of the bindings.
  // We do not want methods called by tcl after this object has been deleted.
  // I was getting intermittent crashes from the expose binding.
  // Expose
  this->Script("bind %s <Expose> {}", 
               this->GetTclName(), this->GetTclName());
  // Configure
  this->Script("bind %s <Configure> {}", 
               this->GetTclName(), this->GetTclName());
  // I do not know if this is neccesary, but I intend to remove all 
  // pending events for this object before it gets deleted.
  this->Script("update");


  vtkPVApplication* pvapp = this->GetPVApplication();
  if (pvapp)
    {
    pvapp->SetRegistryValue(2, "RunTime", "UseParallelProjection", "%d",
                             this->ParallelProjectionCheck->GetSelectedState());
    pvapp->SetRegistryValue(2, "RunTime", "UseStrips", "%d",
                             this->TriangleStripsCheck->GetSelectedState());
    pvapp->SetRegistryValue(2, "RunTime", "UseImmediateMode", "%d",
                             this->ImmediateModeCheck->GetSelectedState());
    double *vp = this->OrientationAxes->GetViewport();
    pvapp->SetRegistryValue(2, "RunTime", "OrientationAxesViewport",
                             "%lf %lf %lf %lf", vp[0], vp[1], vp[2], vp[3]);

    // If it's the last win, save the size of the nav frame

    if (pvapp->GetNumberOfWindows() <= 1 &&
        pvapp->GetSaveUserInterfaceGeometry())
      {
      pvapp->SetRegistryValue(
        2, "Geometry", VTK_PV_NAV_FRAME_SIZE_REG_KEY, "%d", 
        this->SplitFrame->GetFrame2Size());
      }
    }

  if (this->RenderModuleUI)
    {
    this->RenderModuleUI->PrepareForDelete();
    this->RenderModuleUI->Delete();
    this->RenderModuleUI = NULL;
    }
  
  if (this->RenderModuleProxy)
    {
    this->RenderModuleProxy->UnRegister(this);
    this->RenderModuleProxy = 0;
    }

  // Circular reference.
  if ( this->ManipulatorControl2D )
    {
    this->ManipulatorControl2D->SetManipulatorCollection(0);
    }
  if ( this->ManipulatorControl3D )
    {
    this->ManipulatorControl3D->SetManipulatorCollection(0);
    }
  if ( this->SelectionWindow )
    {
    this->SelectionWindow->PrepareForDelete();
    this->SelectionWindow->Delete();
    this->SelectionWindow = 0;
    }

  int cc;
  for ( cc = 0; cc < 6; cc ++ )
    {
    if ( this->CameraIcons[cc] )
      {
      this->CameraIcons[cc]->SetRenderView(0);
      this->CameraIcons[cc]->Delete();
      this->CameraIcons[cc] = 0;
      }
    }

  if (this->TimerToken)
    {
    Tcl_DeleteTimerHandler( this->TimerToken );
    this->TimerToken = NULL;
    }
}

//----------------------------------------------------------------------------
void vtkPVRenderView::DisableRendering()
{
  if (this->TimerToken)
    {
    Tcl_DeleteTimerHandler( this->TimerToken );
    this->TimerToken = NULL;
    }

  this->StartBlockingRender();
}

//----------------------------------------------------------------------------
void vtkPVRenderView::Close()
{
  this->SourceNotebook->Close();
  vtkKWView::Close();
  this->PrepareForDelete();
}  


//----------------------------------------------------------------------------
void vtkPVRenderView::Create(vtkKWApplication *app)
{
  // Check if already created

  if (this->IsCreated())
    {
    vtkErrorMacro(<< this->GetClassName() << " already created");
    return;
    }

  // Call the superclass to create the whole widget

  this->Superclass::Create(app);

  // Need to make sure it destructs right before this view does.
  // It's the whole TKRenderWidget destruction pain.
  if (this->RenderModuleProxy == 0)
    {
    this->RenderModuleProxy = this->GetPVApplication()->GetRenderModuleProxy();
    this->RenderModuleProxy->Register(this);
    }

  // Create the frames

  this->Frame->Create(app);
  this->Frame->SetReliefToRidge();
  this->Script("pack %s -expand yes -fill both -side top -anchor nw",
               this->Frame->GetWidgetName());

  this->Frame2->Create(app);
  this->Script("pack %s -fill x -side top -anchor nw",
               this->Frame2->GetWidgetName());

  this->Label->Create(app);
  this->Label->SetText("3D View");
  this->Label->SetBorderWidth(0);
  this->Label->SetForegroundColor(0.94, 0.94, 0.94);

  this->Script("pack %s -side left -anchor w",
               this->Label->GetWidgetName());

  this->Script("bind %s <Any-ButtonPress> {%s MakeSelected}",
               this->Label->GetWidgetName(), this->GetTclName());

  // Properties button

  this->PropertiesButton->SetParent(this->Label->GetParent());
  // The -bg color is hardcoded here since the real -bg of the frame is
  // changed when it's active (it's not active at the moment). But inside
  // paraview tehre is only one view, and it's always active, so use the
  // active color.
  this->PropertiesButton->Create(app);
  this->PropertiesButton->SetBackgroundColor(0, 0, 0.5);
  this->PropertiesButton->SetBorderWidth(0);
  this->PropertiesButton->SetPadX(0);
  this->PropertiesButton->SetPadY(0);
  this->PropertiesButton->SetHighlightThickness(0);
  this->PropertiesButton->SetReliefToFlat();
  this->PropertiesButton->SetCommand(this, "SwitchBackAndForthToViewProperties");
  this->PropertiesButton->SetBalloonHelpString(
    "Switch back and forth between the current view properties and the" 
    VTK_PV_VIEW_MENU_LABEL ".");

  this->PropertiesButton->SetImageToPixels(image_properties, 
                                           image_properties_width, 
                                           image_properties_height, 
                                           image_properties_pixel_size,
                                           image_properties_length);

  this->Script("pack %s %s -side left -anchor w -padx 2",
               this->Label->GetWidgetName(),
               this->PropertiesButton->GetWidgetName());

  this->Script("bind %s <Any-ButtonPress> {%s MakeSelected}",
               this->Frame2->GetWidgetName(), this->GetTclName());

  // Create the control frame - only pack it if support option enabled

  this->ControlFrame->Create(app);
  if (this->SupportControlFrame)
    {
    this->Script("pack %s -expand t -fill both -side top -anchor nw",
                 this->ControlFrame->GetWidgetName());
    }
  
  // Separate window for the renderer.

  if (getenv("PV_SEPARATE_RENDER_WINDOW") != NULL)
    {
    this->TopLevelRenderWindow->Create(app);
    this->TopLevelRenderWindow->SetTitle(app->GetName());
    }

  // Add the -rw argument

  char local[256];
  sprintf(local, "-rw Addr=%p", this->GetRenderWindow());
  this->Script("vtkTkRenderWidget %s %s",
               this->VTKWidget->GetWidgetName(),local);

  this->Script("pack %s -expand yes -fill both -side top -anchor nw",
               this->VTKWidget->GetWidgetName());
  
  // Expose
  this->Script("bind %s <Expose> {%s Exposed}", 
               this->GetTclName(), this->GetTclName());

  // Configure
  this->Script("bind %s <Configure> {%s Configured}", 
               this->GetTclName(), this->GetTclName());

  // Configure the split frame

  this->SplitFrame->SetParent(this->GetPropertiesParent());
  this->SplitFrame->SetOrientationToVertical();
  this->SplitFrame->SetExpandableFrameToFrame1();
  this->SplitFrame->SetSeparatorSize(5);
  this->SplitFrame->SetFrame2MinimumSize(80);

  if (app->GetSaveUserInterfaceGeometry() &&
      app->HasRegistryValue(
        2, "Geometry", VTK_PV_NAV_FRAME_SIZE_REG_KEY))
    {
    this->SplitFrame->SetFrame2Size(
      app->GetIntRegistryValue(
        2, "Geometry", VTK_PV_NAV_FRAME_SIZE_REG_KEY));
    }
  else
    {
    this->SplitFrame->SetFrame2Size(80);
    }

  this->SplitFrame->Create(app);

  this->Script("pack %s -fill both -expand t -side top", 
               this->SplitFrame->GetWidgetName());

  // Configure the navigation frame

  this->NavigationFrame->SetParent(this->SplitFrame->GetFrame2());
  this->NavigationFrame->AllowFrameToCollapseOff();
  this->NavigationFrame->Create(app);
  this->NavigationFrame->SetLabelText("Navigation");
  this->Script("pack %s -fill both -expand t -side top", 
               this->NavigationFrame->GetWidgetName());

  // Configure the navigation window

  this->NavigationWindow->SetParent(this->NavigationFrame->GetFrame());
  this->NavigationWindow->SetWidth(341);
  this->NavigationWindow->SetHeight(545);
  this->NavigationWindow->Create(app); 

  // Configure the selection window

  this->SelectionWindow->SetParent(this->NavigationFrame->GetFrame());
  this->SelectionWindow->SetWidth(341);
  this->SelectionWindow->SetHeight(545);
  this->SelectionWindow->Create(app); 

  this->SelectionWindowButton->SetParent(
    this->NavigationFrame->GetLabelFrame());
  this->SelectionWindowButton->Create(app);
  this->SelectionWindowButton->SetHighlightThickness(0);
  this->SelectionWindowButton->IndicatorVisibilityOff();
  this->SelectionWindowButton->SetConfigurationOption(
    "-image", "PVSelectionWindowButton");
  this->SelectionWindowButton->SetConfigurationOption(
    "-selectimage", "PVSelectionWindowButton");

  this->SelectionWindowButton->SetBalloonHelpString(
    "Switch to selection window mode.");
  this->SelectionWindowButton->SetCommand(
    this, "ShowSelectionWindowCallback 1");
  
  this->NavigationWindowButton->SetParent(
    this->NavigationFrame->GetLabelFrame());
  this->NavigationWindowButton->Create(app);
  this->NavigationWindowButton->SetHighlightThickness(0);
  this->NavigationWindowButton->IndicatorVisibilityOff();
  this->NavigationWindowButton->SetConfigurationOption(
    "-image", "PVNavigationWindowButton");
  this->NavigationWindowButton->SetConfigurationOption(
    "-selectimage", "PVNavigationWindowButton");

  this->NavigationWindowButton->SetBalloonHelpString(
    "Switch to navigation window mode.");
  this->NavigationWindowButton->SetCommand(
    this, "ShowNavigationWindowCallback 1");

  this->Script("pack %s %s -side left -anchor w -before %s -padx 1",
               this->SelectionWindowButton->GetWidgetName(),
               this->NavigationWindowButton->GetWidgetName(),
               this->NavigationFrame->GetLabel()->GetWidgetName());

  if (app->HasRegistryValue(2, "RunTime", "SourcesBrowser"))
    {
    if (app->GetBooleanRegistryValue(2, "RunTime", 
                                                 "SourcesBrowser",
                                                 "SelectionWindow"))
      {
      this->ShowSelectionWindowCallback(0);
      }
    else
      {
      this->ShowNavigationWindowCallback(0);
      }
    }
  else
    {
    this->ShowSelectionWindowCallback(0);
    }

  this->SetSourcesBrowserAlwaysShowName(
    this->GetPVApplication()->GetSourcesBrowserAlwaysShowName());

  this->GetRenderWindow()->AddObserver(
                 vtkCommand::CursorChangedEvent, this->Observer);


  // This is created in this object only because the GetSourceParent method.
  // These should be create in application or window.
  this->SourceNotebook = vtkPVSourceNotebook::New();
  this->SourceNotebook->SetParent(this->GetSourceParent());
  this->SourceNotebook->Create(app);
  this->Script("pack %s -pady 2 -padx 2 -fill both -expand yes -anchor n",
               this->SourceNotebook->GetWidgetName());

  // For initializing the trace of the notebook.
  // Do we really need this?
  //this->GetSourceParent()->GetTraceHelper()->SetReferenceObject(this);
  //this->GetSourceParent()->GetTraceHelper()->SetReferenceCommand("GetParametersParent");

  this->EventuallyRender();
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SwitchBackAndForthToViewProperties()
{
  vtkKWWindow *win = this->GetPVWindow();
  if (!win)
    {
    return;
    }

  vtkKWMenu *viewmenu = win->GetViewMenu();
  if (!viewmenu)
    {
    return;
    }

  if (!viewmenu->HasItem(VTK_PV_VIEW_MENU_LABEL))
    {
    return;
    }
  int prop_position = viewmenu->GetIndexOfItem(VTK_PV_VIEW_MENU_LABEL);

  // First check where we are in the view menu

  int position = viewmenu->GetCheckedRadioButtonItem(viewmenu, "Radio");
  if (position < 0)
    {
    return;
    }

  // Now if we are not in the view prop, save the old pos and go to it
  // otherwise restore the old one

  if (position != prop_position)
    {
    this->SetMenuLabelSwitchBackAndForthToViewProperties(this->Script(
      "%s entrycget %d -label", viewmenu->GetWidgetName(), position));
    viewmenu->Invoke(prop_position);
    }
  else
    {
    if (this->MenuLabelSwitchBackAndForthToViewProperties &&
        viewmenu->HasItem(this->MenuLabelSwitchBackAndForthToViewProperties))
      {
      // This entry of the view menu must be in "normal" state to switch
      // between source and 3D views.
      int state = viewmenu->GetItemState(this->MenuLabelSwitchBackAndForthToViewProperties);
      viewmenu->SetItemState(this->MenuLabelSwitchBackAndForthToViewProperties,
                         vtkKWTkOptions::StateNormal);
      viewmenu->Invoke(
        viewmenu->GetIndexOfItem(this->MenuLabelSwitchBackAndForthToViewProperties));
      viewmenu->SetItemState(this->MenuLabelSwitchBackAndForthToViewProperties,
                         state);
      }
    }
}

//----------------------------------------------------------------------------
vtkKWWidget *vtkPVRenderView::GetSourceParent()
{
  return this->SplitFrame->GetFrame1();
}

//----------------------------------------------------------------------------
void vtkPVRenderView::Display3DWidgetsCallback()
{
  int val = this->Display3DWidgets->GetSelectedState();
  this->SetDisplay3DWidgets(val);
  this->GetApplication()->SetRegistryValue(2, "RunTime","Display3DWidgets",
                                      (val?"1":"0"));
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetDisplay3DWidgets(int s)
{
  this->Display3DWidgets->SetSelectedState(s);
  this->GetPVApplication()->SetDisplay3DWidgets(s);
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetSourcesBrowserAlwaysShowName(int s)
{
  if (this->NavigationWindow)
    {
    this->NavigationWindow->SetAlwaysShowName(s);
    }
  if (this->SelectionWindow)
    {
    this->SelectionWindow->SetAlwaysShowName(s);
    }
}

void InitializeScale(vtkKWScaleWithEntry *scale, vtkSMProperty *prop);
//----------------------------------------------------------------------------
void vtkPVRenderView::CreateViewProperties()
{
  this->vtkKWView::CreateViewProperties();

  double rgb[3];
  vtkPVWindow* pvwindow = this->GetPVWindow();
  vtkPVApplication* pvapp = this->GetPVApplication();

  this->RendererBackgroundColor->SetBalloonHelpString(
    "Change the background color of the 3D View window");
  // This used to be in vtkPVWindow.
  // I moved it here because I had to move Save color to this class.
  // I also think it belongs here.
  // Don't you think that save and retrieve color should really be in
  // the class vtkPVApplication?
  pvapp->RetrieveColorRegistryValue(2, "RenderViewBG", rgb); 
  if (rgb[0] == -1)
    {
    rgb[0] = 0.33;
    rgb[1] = 0.35;
    rgb[2] = 0.43;
    }
  this->SetRendererBackgroundColor(rgb[0], rgb[1], rgb[2]);

  // Render parameters

  this->RenderParametersFrame->SetParent(
    this->GeneralPropertiesFrame->GetFrame());
  this->RenderParametersFrame->Create(this->GetApplication());
  this->RenderParametersFrame->SetLabelText("Advanced Render Parameters");
  this->Script("pack %s -padx 2 -pady 2 -fill x -expand yes -anchor w",
               this->RenderParametersFrame->GetWidgetName());

  // Render parameters: parallel projection

  this->ParallelProjectionCheck->SetParent(
    this->RenderParametersFrame->GetFrame());
  this->ParallelProjectionCheck->Create(this->GetApplication());
  this->ParallelProjectionCheck->SetText("Use parallel projection");
  if (pvapp && pvwindow && 
      pvapp->GetRegistryValue(2, "RunTime", "UseParallelProjection", 0))
    {
    this->ParallelProjectionCheck->SetSelectedState(
      pvwindow->GetApplication()->GetIntRegistryValue(
        2, "RunTime", "UseParallelProjection"));
    this->ParallelProjectionCallback();
    }
  else
    {
    this->ParallelProjectionCheck->SetSelectedState(0);
    }
  this->ParallelProjectionCheck->SetCommand(this, 
                                            "ParallelProjectionCallback");
  this->ParallelProjectionCheck->SetBalloonHelpString(
    "Toggle the use of parallel projection "
    "(if parallel project is off, perspective projection is used).");
  
  // Render parameters: triangle strips

  this->TriangleStripsCheck->SetParent(
    this->RenderParametersFrame->GetFrame());
  this->TriangleStripsCheck->Create(this->GetApplication());
  this->TriangleStripsCheck->SetText("Use triangle strips");
  if (pvapp && pvwindow && 
      pvapp->GetRegistryValue(2, "RunTime", "UseStrips", 0))
    {
    this->TriangleStripsCheck->SetSelectedState(
      pvwindow->GetApplication()->GetIntRegistryValue(
        2, "RunTime", "UseStrips"));
    }
  else
    {
    this->TriangleStripsCheck->SetSelectedState(0);
    }
  this->TriangleStripsCheck->SetCommand(this, "TriangleStripsCallback");
  this->TriangleStripsCheck->SetBalloonHelpString(
    "If this option is chosen, all triangles are converted into triangle "
    "strips before rendering. This may improve the rendering perfermance.");
  
  // Render parameters: immediate mode

  this->ImmediateModeCheck->SetParent(this->RenderParametersFrame->GetFrame());
  this->ImmediateModeCheck->Create(this->GetApplication());
  this->ImmediateModeCheck->SetText("Use immediate mode rendering");
  this->ImmediateModeCheck->SetCommand(this, "ImmediateModeCallback");
  if (pvapp && pvwindow && 
      pvapp->GetRegistryValue(2, "RunTime", "UseImmediateMode", 0))
    {
    this->ImmediateModeCheck->SetSelectedState(
      pvwindow->GetApplication()->GetIntRegistryValue(
        2, "RunTime", "UseImmediateMode"));
    }
  else
    {
    this->ImmediateModeCheck->SetSelectedState(1);
    }
  this->ImmediateModeCheck->SetBalloonHelpString(
    "When this option is off, OpenGL display lists are used when rendering."
    "Using display lists improves performance for small datasets "
    "but is not recommended for large datasets due to excessive memory "
    "usage and long display list creating times.");

  // Render parameters: pack

  this->Script("pack %s %s %s -side top -anchor w",
               this->ParallelProjectionCheck->GetWidgetName(),
               this->TriangleStripsCheck->GetWidgetName(),
               this->ImmediateModeCheck->GetWidgetName());

  // Create the render module user interface.
  this->RenderModuleUI = 0;
  char* rmuiClassName;
  const char* rmname = this->RenderModuleProxy->GetXMLName();
  rmuiClassName = new char[strlen(rmname) + 20];
  sprintf(rmuiClassName, "vtkPV%sUI", rmname);
  vtkObject* rmui = vtkInstantiator::CreateInstance(rmuiClassName);
  vtkPVRenderModuleUI* rmuio = vtkPVRenderModuleUI::SafeDownCast(rmui);
  if ( rmuio )
    {
    this->RenderModuleUI = rmuio;
    this->RenderModuleUI->SetRenderModuleProxy(this->RenderModuleProxy);
    this->RenderModuleUI->SetParent(this->GeneralPropertiesFrame->GetFrame());
    this->RenderModuleUI->Create(this->GetApplication());
    this->RenderModuleUI->GetTraceHelper()->SetReferenceHelper(
      this->GetTraceHelper());
    this->RenderModuleUI->GetTraceHelper()->SetReferenceCommand(
      "GetRenderModuleUI");
    this->Script("pack %s -padx 2 -pady 2 -fill x -expand yes -anchor w",
      this->RenderModuleUI->GetWidgetName());
    // Disable compositing if the server does not support remote rendering.
    rmuio->Initialize();
    }
  else
    {
    this->RenderModuleUI = 0;
    }
  delete [] rmuiClassName;
  rmuiClassName = NULL;

  // Interface settings

  this->InterfaceSettingsFrame->SetParent(this->GeneralPropertiesFrame->GetFrame());
  this->InterfaceSettingsFrame->Create(this->GetApplication());
  this->InterfaceSettingsFrame->SetLabelText("3D Interface Settings");
  this->Script("pack %s -padx 2 -pady 2 -fill x -expand yes -anchor w",
               this->InterfaceSettingsFrame->GetWidgetName());


  // Interface settings: 3D widgets

  this->Display3DWidgets->SetParent(
    this->InterfaceSettingsFrame->GetFrame());
  this->Display3DWidgets->Create(this->GetApplication());
  this->Display3DWidgets->SetText("Display 3D widgets automatically");
  this->Display3DWidgets->SetBalloonHelpString(
    "When this advanced option is on, all 3D widgets (manipulators) are "
    "visible when created. Turn this off to avoid unnecessary "
    "renders when working with large data and not using 3D widgets "
    "to adjust parameters.");
  this->Display3DWidgets->SetCommand(this, "Display3DWidgetsCallback");

  if (!this->GetApplication()->GetRegistryValue(2,"RunTime","Display3DWidgets",0)||
    this->GetPVWindow()->GetApplication()->GetIntRegistryValue(
      2,"RunTime","Display3DWidgets"))
    {
    this->SetDisplay3DWidgets(1);
    }
  else
    {
    this->SetDisplay3DWidgets(0);
    }
  
  // Interface settings: pack

  this->Script("pack %s -side top -padx 2 -pady 2 -anchor w",
               this->Display3DWidgets->GetWidgetName());



  // Default light control
  this->DefaultLightFrame->SetParent(this->GeneralPropertiesFrame->GetFrame());
  this->DefaultLightFrame->Create(this->GetApplication());
  this->DefaultLightFrame->SetLabelText("Default Light Control");
  this->Script("pack %s -padx 2 -pady 2 -fill x -expand yes -anchor w",
               this->DefaultLightFrame->GetWidgetName());
  /*
  this->DefaultLightSwitch        = vtkKWCheckButton::New();
  */
  float intensity = 1.0;
  if (this->GetApplication()->GetRegistryValue(2, "RunTime", 
      VTK_PV_DEFAULT_LIGHT_INTENSITY_REG_KEY, 0))
    {
    intensity = this->GetApplication()->GetFloatRegistryValue(2, "RunTime", 
      VTK_PV_DEFAULT_LIGHT_INTENSITY_REG_KEY);
    }

  this->DefaultLightIntensity->SetParent(this->DefaultLightFrame->GetFrame());
  this->DefaultLightIntensity->Create(this->GetApplication());
  this->DefaultLightIntensity->ExpandEntryOn();
  this->DefaultLightIntensity->SetEntryWidth(4);
  this->DefaultLightIntensity->SetLabelText("Intensity");
  this->DefaultLightIntensity->SetCommand(this, "DefaultLightIntensityCallback");
  this->DefaultLightIntensity->SetEndCommand(this, "DefaultLightIntensityEndCallback");
  this->DefaultLightIntensity->SetEntryCommand(this, "DefaultLightIntensityEndCallback");
  this->DefaultLightIntensity->SetBalloonHelpString( "Set the intensity of the default light" );
  this->Script("pack %s -side top -padx 2 -pady 2 -anchor w -fill x -expand true",
               this->DefaultLightIntensity->GetWidgetName());
  InitializeScale(this->DefaultLightIntensity, this->RenderModuleProxy->GetProperty("LightIntensity"));
  this->SetDefaultLightIntensity(intensity);
 
  this->DefaultLightAmbientColor->SetParent( this->DefaultLightFrame->GetFrame());
  this->DefaultLightAmbientColor->GetLabel()->SetText("Set Ambient Light Color");
  this->DefaultLightAmbientColor->Create(this->GetApplication());
  this->DefaultLightAmbientColor->SetCommand(this, "SetDefaultLightAmbientColor");
  this->DefaultLightAmbientColor->SetBalloonHelpString(
    "Choose the ambient color of the default light.");
  /*
  this->Script("pack %s -side top -padx 2 -pady 2 -anchor w -fill x -expand true",
               this->DefaultLightAmbientColor->GetWidgetName());
  */
  this->DefaultLightDiffuseColor->SetParent( this->DefaultLightFrame->GetFrame());
  this->DefaultLightDiffuseColor->GetLabel()->SetText("Set Light Color");
  this->DefaultLightDiffuseColor->Create(this->GetApplication());
  this->DefaultLightDiffuseColor->SetCommand(this, "SetDefaultLightDiffuseColor");
  this->DefaultLightDiffuseColor->SetBalloonHelpString(
    "Choose the diffuse color of the default light.");
  this->Script("pack %s -side top -padx 2 -pady 2 -anchor w -fill x -expand true",
               this->DefaultLightDiffuseColor->GetWidgetName());
  this->DefaultLightSpecularColor->SetParent( this->DefaultLightFrame->GetFrame());
  this->DefaultLightSpecularColor->GetLabel()->SetText("Set Specular Light Color");
  this->DefaultLightSpecularColor->Create(this->GetApplication());
  this->DefaultLightSpecularColor->SetCommand(this, "SetDefaultLightSpecularColor");
  this->DefaultLightSpecularColor->SetBalloonHelpString(
    "Choose the specular color of the default light.");
  /*
  this->Script("pack %s -side top -padx 2 -pady 2 -anchor w -fill x -expand true",
               this->DefaultLightSpecularColor->GetWidgetName());
  */
  this->DefaultLightSwitch->SetParent(this->DefaultLightFrame->GetFrame());
  this->DefaultLightSwitch->Create(this->GetApplication());
  this->DefaultLightSwitch->SetText("Enable Default Light");
  this->DefaultLightSwitch->SetCommand(this, "DefaultLightSwitchCallback");
  this->DefaultLightSwitch->SetBalloonHelpString(
    "Chose wther the default light is on or off.");
  this->Script("pack %s -side top -padx 2 -pady 2 -anchor w -fill x -expand true",
               this->DefaultLightSwitch->GetWidgetName());
  if (!pvapp->GetRegistryValue(2, "RunTime", VTK_PV_ENABLE_DEFAULT_LIGHT_REG_KEY, 0) ||
    pvapp->GetIntRegistryValue(2, "RunTime", VTK_PV_ENABLE_DEFAULT_LIGHT_REG_KEY) == 1)
    {
    this->SetDefaultLightSwitch(1);
    }
  else
    {
    this->SetDefaultLightSwitch(0);
    }
  
  // Light Parameter frame
  // 
  // Setup the frame
  this->LightParameterFrame->SetParent(this->GeneralPropertiesFrame->GetFrame());
  this->LightParameterFrame->Create(this->GetApplication());
  this->LightParameterFrame->SetLabelText("Light Kit Parameters");
  this->Script("pack %s -padx 2 -pady 2 -fill x -expand yes -anchor w",
               this->LightParameterFrame->GetWidgetName());

  // First thing to do is a check button, so that we can remove it (make all paraview tests pass)
  this->UseLightButton->SetParent(this->LightParameterFrame->GetFrame()); 
  this->UseLightButton->Create(this->GetApplication());
  this->UseLightButton->SetText("Use Light Kit");
  this->UseLightButton->SetCommand(this, "UseLightCallback");
  this->UseLightButton->SetBalloonHelpString( 
    "Allow control over LightKit, designed to make general purpose" 
    "lighting of scenes simple, flexible, and attractive.  Use a LightKit when you want"
    "more control over your lighting than you can get with the default light.");
  if (!pvapp->GetRegistryValue(2, "RunTime", VTK_PV_USE_LIGHT_KIT_REG_KEY, 0) ||
    pvapp->GetIntRegistryValue(2, "RunTime", VTK_PV_USE_LIGHT_KIT_REG_KEY) == 0 )
    {
    this->SetUseLight(0);
    }
  else
    {
    this->SetUseLight(1);
    }

  // Set every different lights from the light kit
  this->KeyLightLabel->SetParent(this->LightParameterFrame->GetFrame());
  this->KeyLightLabel->Create(this->GetApplication());
  this->KeyLightLabel->SetText("Key :");
  this->KeyLightLabel->SetWidth(4);
  this->KeyLightLabel->SetBalloonHelpString(
     "The key light is the main light, it is usually "
     "positioned so that it appears like an overhead light. "
     "It is generally positioned to shine down on the "
     "scene from about a 45 degree angle vertically and at least a little "
     "offset side to side. The key light is usually at least about twice as "
     "bright as the total of all other lights in the scene to provide good "
     "modeling of object features.");

  this->FillLightLabel->SetParent(this->LightParameterFrame->GetFrame());
  this->FillLightLabel->Create(this->GetApplication());
  this->FillLightLabel->SetText("Fill:");
  this->FillLightLabel->SetWidth(4);
  this->FillLightLabel->SetBalloonHelpString(
     "The fill light is usually positioned across from or opposite from the "
     "key light (though still on the same side of the object as the "
     "camera) in order to simulate diffuse reflections from other objects "
     "in the scene." );

  this->BackLightLabel->SetParent(this->LightParameterFrame->GetFrame());
  this->BackLightLabel->Create(this->GetApplication());
  this->BackLightLabel->SetText("Back:");
  this->BackLightLabel->SetWidth(4);
  this->BackLightLabel->SetBalloonHelpString(
     "The two back lights, one on the left of the object as seen "
     "from the observer and one on the right, fill in the high-contrast "
     "areas behind the object." );

  this->HeadLightLabel->SetParent(this->LightParameterFrame->GetFrame());
  this->HeadLightLabel->Create(this->GetApplication());
  this->HeadLightLabel->SetText("Head:");
  this->HeadLightLabel->SetWidth(4);
  this->HeadLightLabel->SetBalloonHelpString(
     "The headlight, always located at the position of the camera, reduces "
     "the contrast between areas lit by the key and fill light.");

  // This structure has to be kept synchronize with LightKitSubType
  const char *LightTypeDocumentation[] = {
    "Set the warmth of each the lights.  Warmth is a parameter that "
    "varies from 0 to 1, where 0 is \"cold\", "
    "1 is \"warm\" , and 0.5 is a neutral white.  The warmth "
    "scale is non-linear. Warmth values close to 0.5 are subtly "
    "\"warmer\" or \"cooler,\" much like a warmer tungsten incandescent "
    "bulb, a cooler halogen, or daylight (cooler still). Moving "
    "further away from 0.5, colors become more quickly varying towards "
    "blues and reds.", //Warmth
    "Set the intensity of the key light. The key light is the "
    "brightest light in the scene. The intensities of the other two "
    "lights are ratios of the key light's intensity.", //Intensity
    "Set the position of the key, fill, and back lights "
    "using angular methods. Elevation corresponds to latitude." , //Elevation
    "Set the position of the key, fill, and back lights "
    "using angular methods.  Azimuth corresponds to longitude." , //Azimuth,
    "Set the key-to-fill ratio.  This ratio controls "
    "how bright the fill light is compared to the key light: larger "
    "values correspond to a dimmer fill light.  The purpose of the "
    "fill light is to light parts of the object not lit by the key "
    "light, while still maintaining constrast.", //KFRatio,
    "Set the key-to-back light ratio.  This ratio controls "
    "how bright the back lights are compared to the key light: larger "
    "values correspond to dimmer back lights.  The back lights fill "
    "in the remaining high-contrast regions behind the object.", //KBRatio,
    "Set the key-to-headlight ratio.  Similar to the key-to-fill "
    "ratio, this ratio controls how bright the headlight light is "
    "compared to the key light: larger values correspond to a dimmer "
    "headlight light.  The headlight is special kind of fill light,"
    "lighting only the parts of the object that the camera can see.", //KHRatio
    NULL
    };
  char command[100];
  char endcommand[100];
  vtkstd::string p;
  vtkLightKit::LightKitSubType subtype;
  int cc;
  float reg_value;
  int reg_value_valid;
  for ( cc = 0; cc < 4; cc ++ )
    {
    subtype = vtkLightKit::GetSubType(vtkLightKit::TKeyLight, cc);
    this->KeyLightScale[cc]->SetParent(this->LightParameterFrame->GetFrame());
    this->KeyLightScale[cc]->PopupModeOn();
    this->KeyLightScale[cc]->Create(this->GetApplication());
    this->KeyLightScale[cc]->ExpandEntryOn();
    this->KeyLightScale[cc]->SetEntryWidth(4);
    this->KeyLightScale[cc]->SetLabelText( 
      vtkLightKit::GetShortStringFromSubType( subtype ));
    sprintf(command,   "LightCallback %d %d", vtkLightKit::TKeyLight, subtype );
    sprintf(endcommand,"LightEndCallback %d %d", vtkLightKit::TKeyLight, subtype);
    this->KeyLightScale[cc]->SetCommand(this, command);
    this->KeyLightScale[cc]->SetEndCommand(this, endcommand);
    this->KeyLightScale[cc]->SetEntryCommand(this, endcommand);
    this->KeyLightScale[cc]->SetBalloonHelpString( LightTypeDocumentation[subtype] );

    p = vtkLightKit::GetStringFromType( vtkLightKit::TKeyLight );
    p += vtkLightKit::GetStringFromSubType( subtype );
    reg_value_valid = 0;
    if (pvapp->GetRegistryValue(2, "RunTime", p.c_str(),0))
      {
      reg_value_valid = 1;
      reg_value = pvapp->GetFloatRegistryValue(2, "RunTime", p.c_str());
      }
    
    InitializeScale(this->KeyLightScale[cc], 
      this->RenderModuleProxy->GetProperty(p.c_str()));
    if (reg_value_valid)
      {
      this->SetLight(vtkLightKit::TKeyLight, subtype, reg_value);
      }
    
    subtype = vtkLightKit::GetSubType(vtkLightKit::TFillLight, cc);
    this->FillLightScale[cc]->SetParent(this->LightParameterFrame->GetFrame());
    this->FillLightScale[cc]->PopupModeOn();
    this->FillLightScale[cc]->Create(this->GetApplication());
    this->FillLightScale[cc]->ExpandEntryOn();
    this->FillLightScale[cc]->SetEntryWidth(4);
    this->FillLightScale[cc]->SetLabelText( 
      vtkLightKit::GetShortStringFromSubType( subtype ));
    sprintf(command,   "LightCallback %d %d", vtkLightKit::TFillLight, subtype);
    sprintf(endcommand,"LightEndCallback %d %d", vtkLightKit::TFillLight, subtype);
    this->FillLightScale[cc]->SetCommand(this, command);
    this->FillLightScale[cc]->SetEndCommand(this, endcommand);
    this->FillLightScale[cc]->SetEntryCommand(this, endcommand);
    this->FillLightScale[cc]->SetBalloonHelpString( LightTypeDocumentation[subtype]);

    p = vtkLightKit::GetStringFromType( vtkLightKit::TFillLight );
    p += vtkLightKit::GetStringFromSubType( subtype );
    
    reg_value_valid = 0;
    if (pvapp->GetRegistryValue(2, "RunTime", p.c_str(),0))
      {
      reg_value_valid = 1;
      reg_value = pvapp->GetFloatRegistryValue(2, "RunTime", p.c_str());
      }
    InitializeScale(this->FillLightScale[cc], 
      this->RenderModuleProxy->GetProperty(p.c_str()));
    if (reg_value_valid)
      {
      this->SetLight(vtkLightKit::TFillLight, subtype, reg_value);
      }

    

    subtype = vtkLightKit::GetSubType(vtkLightKit::TBackLight, cc);
    this->BackLightScale[cc]->SetParent(this->LightParameterFrame->GetFrame());
    this->BackLightScale[cc]->PopupModeOn();
    this->BackLightScale[cc]->Create(this->GetApplication());
    this->BackLightScale[cc]->ExpandEntryOn();
    this->BackLightScale[cc]->SetEntryWidth(4);
    this->BackLightScale[cc]->SetLabelText(
      vtkLightKit::GetShortStringFromSubType( subtype ));
    sprintf(command,   "LightCallback %d %d", vtkLightKit::TBackLight, subtype);
    sprintf(endcommand,"LightEndCallback %d %d", vtkLightKit::TBackLight, subtype);
    this->BackLightScale[cc]->SetCommand(this, command);
    this->BackLightScale[cc]->SetEndCommand(this, endcommand);
    this->BackLightScale[cc]->SetEntryCommand(this, endcommand);
    this->BackLightScale[cc]->SetBalloonHelpString( LightTypeDocumentation[subtype]);

    p = vtkLightKit::GetStringFromType( vtkLightKit::TBackLight );
    p += vtkLightKit::GetStringFromSubType( subtype );

    reg_value_valid = 0;
    if (pvapp->GetRegistryValue(2, "RunTime", p.c_str(),0))
      {
      reg_value_valid = 1;
      reg_value = pvapp->GetFloatRegistryValue(2, "RunTime", p.c_str());
      }
    InitializeScale(this->BackLightScale[cc], 
      this->RenderModuleProxy->GetProperty(p.c_str()));
    if (reg_value_valid)
      {
      this->SetLight(vtkLightKit::TBackLight, subtype, reg_value);
      }
    
    if( cc < 2 )
      {
      subtype = vtkLightKit::GetSubType(vtkLightKit::THeadLight, cc);
      this->HeadLightScale[cc]->SetParent(this->LightParameterFrame->GetFrame());
      this->HeadLightScale[cc]->PopupModeOn();
      this->HeadLightScale[cc]->Create(this->GetApplication());
      this->HeadLightScale[cc]->ExpandEntryOn();
      this->HeadLightScale[cc]->SetEntryWidth(4);
      this->HeadLightScale[cc]->SetLabelText(
        vtkLightKit::GetShortStringFromSubType( subtype ));
      sprintf(command,   "LightCallback %d %d", vtkLightKit::THeadLight, subtype);
      sprintf(endcommand,"LightEndCallback %d %d", vtkLightKit::THeadLight, subtype);
      this->HeadLightScale[cc]->SetCommand(this, command);
      this->HeadLightScale[cc]->SetEndCommand(this, endcommand);
      this->HeadLightScale[cc]->SetEntryCommand(this, endcommand);
      this->HeadLightScale[cc]->SetBalloonHelpString( LightTypeDocumentation[subtype]);

      p = vtkLightKit::GetStringFromType( vtkLightKit::THeadLight );
      p += vtkLightKit::GetStringFromSubType( subtype );

      reg_value_valid = 0;
      if (pvapp->GetRegistryValue(2, "RunTime", p.c_str(),0))
        {
        reg_value_valid = 1;
        reg_value = pvapp->GetFloatRegistryValue(2, "RunTime", p.c_str());
        }
      InitializeScale(this->HeadLightScale[cc], 
        this->RenderModuleProxy->GetProperty(p.c_str()));
      if (reg_value_valid)
        {
        this->SetLight(vtkLightKit::THeadLight, subtype, reg_value);
        }

      }
    }

  // Maintain Luminance
  // This would be nice if there was an InitializeScale'function like for KWCheckButton too
  this->MaintainLuminanceButton->SetParent(this->LightParameterFrame->GetFrame()); 
  this->MaintainLuminanceButton->Create(this->GetApplication());
  this->MaintainLuminanceButton->SetText("Maintain Luminance");
  this->MaintainLuminanceButton->SetCommand(this, "MaintainLuminanceCallback");
  this->MaintainLuminanceButton->SetBalloonHelpString( 
    "If MaintainLuminance is set, the LightKit will attempt to maintain"
    "the apparent intensity of lights based on their perceptual brightnesses.");
  if (!pvapp->GetRegistryValue(2, "RunTime", 
      VTK_PV_MAINTAIN_LUMINANCE_REG_KEY, 0) || pvapp->GetIntRegistryValue(2,
      "RunTime", VTK_PV_MAINTAIN_LUMINANCE_REG_KEY) == 0)
    {
    this->SetMaintainLuminance(0);
    }
  else
    {
    this->SetMaintainLuminance(1);
    }
  
  this->Script("grid %s - -sticky nws",
               this->UseLightButton->GetWidgetName());

  int button_pady = 1;
  this->Script("grid %s %s %s %s %s -sticky news -pady %d",
               this->KeyLightLabel->GetWidgetName(),
               this->KeyLightScale[0]->GetWidgetName(),
               this->KeyLightScale[1]->GetWidgetName(),
               this->KeyLightScale[2]->GetWidgetName(),
               this->KeyLightScale[3]->GetWidgetName(),
               button_pady);

  this->Script("grid %s -sticky nws",
               this->KeyLightLabel->GetWidgetName());

  this->Script("grid %s %s %s %s %s -sticky news -pady %d",
               this->FillLightLabel->GetWidgetName(),
               this->FillLightScale[0]->GetWidgetName(),
               this->FillLightScale[1]->GetWidgetName(),
               this->FillLightScale[2]->GetWidgetName(),
               this->FillLightScale[3]->GetWidgetName(),
               button_pady);

  this->Script("grid %s -sticky nws",
               this->FillLightLabel->GetWidgetName());

  this->Script("grid %s %s %s %s %s -sticky news -pady %d",
               this->BackLightLabel->GetWidgetName(),
               this->BackLightScale[0]->GetWidgetName(),
               this->BackLightScale[1]->GetWidgetName(),
               this->BackLightScale[2]->GetWidgetName(),
               this->BackLightScale[3]->GetWidgetName(),
               button_pady);

  this->Script("grid %s -sticky nws",
               this->BackLightLabel->GetWidgetName());

  this->Script("grid %s %s %s %s - -sticky news -pady %d",
               this->HeadLightLabel->GetWidgetName(),
               this->HeadLightScale[0]->GetWidgetName(),
               this->HeadLightScale[1]->GetWidgetName(),
               this->MaintainLuminanceButton->GetWidgetName(),
               button_pady);

  this->Script("grid %s -sticky nws",
               this->HeadLightLabel->GetWidgetName());

 


  // Orientation axes settings
  
  this->OrientationAxesFrame->SetParent(this->AnnotationPropertiesFrame->GetFrame());
  this->OrientationAxesFrame->Create(this->GetApplication());
  this->OrientationAxesFrame->SetLabelText("Orientation Axes");
  this->Script("pack %s -padx 2 -pady 2 -fill x -expand yes -anchor w",
               this->OrientationAxesFrame->GetWidgetName());
  
  // Orientation axes settings: visibility check
  
  this->OrientationAxesCheck->SetParent(this->OrientationAxesFrame->GetFrame());
  this->OrientationAxesCheck->Create(this->GetApplication());
  this->OrientationAxesCheck->SetText("Display orientation axes");
  this->OrientationAxesCheck->SetCommand(this, "OrientationAxesCheckCallback");
  this->OrientationAxesCheck->SetBalloonHelpString(
    "Toggle the visibility of the orientation axes.");
  if (pvapp && pvwindow &&
      pvapp->GetRegistryValue(2, "RunTime", "OrientationAxesVisibility", 0))
    {
    this->OrientationAxesCheck->SetSelectedState(
      pvwindow->GetApplication()->GetIntRegistryValue(
        2, "RunTime", "OrientationAxesVisibility"));
    }
  else
    {
    this->OrientationAxesCheck->SetSelectedState(1);
    }
  this->OrientationAxesCheckCallback();
  
  // Orientation axes settings: interactive check
  
  this->OrientationAxesInteractiveCheck->SetParent(
    this->OrientationAxesFrame->GetFrame());
  this->OrientationAxesInteractiveCheck->Create(this->GetApplication());
  this->OrientationAxesInteractiveCheck->SetText("Interactive");
  this->OrientationAxesInteractiveCheck->SetCommand(this, "OrientationAxesInteractiveCallback");
  this->OrientationAxesInteractiveCheck->SetBalloonHelpString(
    "Toggle whether the position and size of the orientation axes can be "
    "controlled using mouse interaction in the 3D View window.");
  if (pvapp && pvwindow &&
      pvapp->GetRegistryValue(2, "RunTime", "OrientationAxesInteractivity", 0))
    {
    this->OrientationAxesInteractiveCheck->SetSelectedState(
      pvwindow->GetApplication()->GetIntRegistryValue(
        2, "RunTime", "OrientationAxesInteractivity"));
    }
  else
    {
    this->OrientationAxesInteractiveCheck->SetSelectedState(0);
    }
  
  this->OrientationAxesInteractiveCallback();
  
  // Orientation axes settings: outline color
  
  this->OrientationAxesOutlineColor->SetParent(
    this->OrientationAxesFrame->GetFrame());
  this->OrientationAxesOutlineColor->GetLabel()->SetText("Set Outline Color");
  this->OrientationAxesOutlineColor->Create(this->GetApplication());
  this->OrientationAxesOutlineColor->SetCommand(this, "SetOrientationAxesOutlineColor");
  this->OrientationAxesOutlineColor->SetBalloonHelpString(
    "Choose the color of the outline for resizing the orientation axes.");
  if (pvapp && pvwindow)
    {
    pvapp->RetrieveColorRegistryValue(2, "OrientationAxesOutline", rgb);
    if (rgb[0] == -1)
      {
      rgb[0] = 1.0;
      rgb[1] = 1.0;
      rgb[2] = 1.0;
      }
    }
  else
    {
    rgb[0] = 1.0;
    rgb[1] = 1.0;
    rgb[2] = 1.0;
    }
  this->SetOrientationAxesOutlineColor(rgb[0], rgb[1], rgb[2]);
    
  // Orientation axes settings: text color
  
  this->OrientationAxesTextColor->SetParent(
    this->OrientationAxesFrame->GetFrame());
  this->OrientationAxesTextColor->GetLabel()->SetText("Set Axis Label Color");
  this->OrientationAxesTextColor->Create(this->GetApplication());
  this->OrientationAxesTextColor->SetCommand(this, "SetOrientationAxesTextColor");
  this->OrientationAxesTextColor->SetBalloonHelpString(
    "Choose the color of the X, Y, Z labels of the orientation axes.");
  if (pvapp && pvwindow)
    {
    pvapp->RetrieveColorRegistryValue(2, "OrientationAxesText", rgb);
    if (rgb[0] == -1)
      {
      rgb[0] = 1.0;
      rgb[1] = 1.0;
      rgb[2] = 1.0;
      }
    }
  else
    {
    rgb[0] = 1.0;
    rgb[1] = 1.0;
    rgb[2] = 1.0;
    }
  this->SetOrientationAxesTextColor(rgb[0], rgb[1], rgb[2]);

  // Orientation axes settings: pack
  
  this->Script("pack %s %s -padx 2 -side top -anchor w",
               this->OrientationAxesCheck->GetWidgetName(),
               this->OrientationAxesInteractiveCheck->GetWidgetName());
  this->Script("pack %s %s -padx 2 -fill x -side top -anchor w",
               this->OrientationAxesOutlineColor->GetWidgetName(),
               this->OrientationAxesTextColor->GetWidgetName());

  // Orientation axes widget
  
  this->OrientationAxes->SetParentRenderer(this->GetRenderer());

  char buffer[1024];
  double vp[4];
  if (pvapp && pvwindow &&
      pvapp->GetRegistryValue(2, "RunTime", "OrientationAxesViewport", buffer))
    {
    if (*buffer)
      {
      sscanf(buffer, "%lf %lf %lf %lf", vp, vp+1, vp+2, vp+3);
      this->OrientationAxes->SetViewport(vp[0], vp[1], vp[2], vp[3]);
      }
    else
      {
      this->OrientationAxes->SetViewport(0, 0, 0.2, 0.2);
      }
    }
  else
    {
    this->OrientationAxes->SetViewport(0, 0, 0.2, 0.2);
    }
  
  // Camera settings
  this->Notebook->AddPage("Camera", 
                          "Camera and viewing navigation properties page");
  vtkKWWidget* page = this->Notebook->GetFrame("Camera");

  vtkKWFrameWithScrollbar* frame = vtkKWFrameWithScrollbar::New();
  frame->SetParent(page);
  frame->Create(this->GetApplication());
  this->Script("pack %s -fill both -expand yes", frame->GetWidgetName());

  // Camera: standard views

  this->StandardViewsFrame->SetParent( frame->GetFrame() );
  this->StandardViewsFrame->Create(this->GetApplication());
  this->StandardViewsFrame->SetLabelText("Standard Views");

  const char *views_grid_settings = " -padx 1 -pady 1 -ipadx 5 -sticky ew";

  this->XMaxViewButton->SetParent(this->StandardViewsFrame->GetFrame());
  this->XMaxViewButton->SetText("+X");
  this->XMaxViewButton->Create(this->GetApplication());
  this->XMaxViewButton->SetCommand(this, "StandardViewCallback 1 0 0");
  this->XMaxViewButton->SetBalloonHelpString(
    "Looking down X axis from (1,0,0)");
  this->Script("grid configure %s -column 0 -row 0 %s",
               this->XMaxViewButton->GetWidgetName(), views_grid_settings);

  this->XMinViewButton->SetParent(this->StandardViewsFrame->GetFrame());
  this->XMinViewButton->SetText("-X");
  this->XMinViewButton->Create(this->GetApplication());
  this->XMinViewButton->SetCommand(this, "StandardViewCallback -1 0 0");
  this->XMinViewButton->SetBalloonHelpString(
    "Looking down X axis from (-1,0,0)");
  this->Script("grid configure %s -column 0 -row 1 %s",
               this->XMinViewButton->GetWidgetName(), views_grid_settings);

  this->YMaxViewButton->SetParent(this->StandardViewsFrame->GetFrame());
  this->YMaxViewButton->SetText("+Y");
  this->YMaxViewButton->Create(this->GetApplication());
  this->YMaxViewButton->SetCommand(this, "StandardViewCallback 0 1 0");
  this->YMaxViewButton->SetBalloonHelpString(
    "Looking down Y axis from (0,1,0)");
  this->Script("grid configure %s -column 1 -row 0 %s",
               this->YMaxViewButton->GetWidgetName(), views_grid_settings);

  this->YMinViewButton->SetParent(this->StandardViewsFrame->GetFrame());
  this->YMinViewButton->SetText("-Y");
  this->YMinViewButton->Create(this->GetApplication());
  this->YMinViewButton->SetCommand(this, "StandardViewCallback 0 -1 0");
  this->YMinViewButton->SetBalloonHelpString(
    "Looking down Y axis from (0,-1,0)");
  this->Script("grid configure %s -column 1 -row 1 %s",
               this->YMinViewButton->GetWidgetName(), views_grid_settings);

  this->ZMaxViewButton->SetParent(this->StandardViewsFrame->GetFrame());
  this->ZMaxViewButton->SetText("+Z");
  this->ZMaxViewButton->Create(this->GetApplication());
  this->ZMaxViewButton->SetCommand(this, "StandardViewCallback 0 0 1");
  this->ZMaxViewButton->SetBalloonHelpString(
    "Looking down Z axis from (0,0,1)");
  this->Script("grid configure %s -column 2 -row 0 %s",
               this->ZMaxViewButton->GetWidgetName(), views_grid_settings);

  this->ZMinViewButton->SetParent(this->StandardViewsFrame->GetFrame());
  this->ZMinViewButton->SetText("-Z");
  this->ZMinViewButton->Create(this->GetApplication());
  this->ZMinViewButton->SetCommand(this, "StandardViewCallback 0 0 -1");
  this->ZMinViewButton->SetBalloonHelpString(
    "Looking down Z axis from (0,0,-1)");
  this->Script("grid configure %s -column 2 -row 1 %s",
               this->ZMinViewButton->GetWidgetName(), views_grid_settings);

  // Camera: stored camera position

  this->CameraIconsFrame->SetParent(frame->GetFrame());
  this->CameraIconsFrame->Create(this->GetApplication());
  this->CameraIconsFrame->SetLabelText("Stored Camera Positions");

  vtkKWWidget* cframe = this->CameraIconsFrame->GetFrame();
  for ( cc = 0; cc < 6; cc ++ )
    {
    int x, y;
    this->CameraIcons[cc]->SetRenderView(this);
    this->CameraIcons[cc]->SetParent(cframe);
    this->CameraIcons[cc]->Create(this->GetApplication());

    x = cc % 3;
    y = cc / 3;

    this->Script("grid configure %s -column %d -row %d "
                 "-padx 1 -pady 1 -ipadx 0 -ipady 0 -sticky news",
                 this->CameraIcons[cc]->GetWidgetName(),
                 x, y);
                 
    }

  // Camera: manipulators

  this->ManipulatorControl2D->SetParent(frame->GetFrame());
  this->ManipulatorControl2D->Create(pvapp);
  this->ManipulatorControl2D->SetLabel("2D Movements");
  this->ManipulatorControl2D->GetTraceHelper()->SetReferenceHelper(
    this->GetTraceHelper());
  this->ManipulatorControl2D->GetTraceHelper()->SetReferenceCommand(
    "GetManipulatorControl2D");
  
  this->ManipulatorControl3D->SetParent(frame->GetFrame());
  this->ManipulatorControl3D->Create(pvapp);
  this->ManipulatorControl3D->SetLabel("3D Movements");
  this->ManipulatorControl3D->GetTraceHelper()->SetReferenceHelper(
    this->GetTraceHelper());
  this->ManipulatorControl3D->GetTraceHelper()->SetReferenceCommand(
    "GetManipulatorControl3D");
  
  // Camera: camera control frame

  this->CameraControlFrame->SetParent(frame->GetFrame());
  this->CameraControlFrame->Create(this->GetApplication());
  this->CameraControlFrame->SetLabelText("Camera Orientation");
  
  // Camera: camera control
  
  this->CameraControl->SetParent(this->CameraControlFrame->GetFrame());
  this->CameraControl->Create(this->GetApplication());
  this->CameraControl->SetInteractorStyle(this->GetPVWindow()->GetCenterOfRotationStyle());
  this->CameraControl->SetRenderView(this);
  this->CameraControl->GetTraceHelper()->SetReferenceHelper(
    this->GetTraceHelper());
  this->CameraControl->GetTraceHelper()->SetReferenceCommand(
    "GetCameraControl");
  
  this->Script("pack %s -side top -fill x -expand y", this->CameraControl->GetWidgetName());
  
  // Camera: pack

  this->Script("pack %s %s %s %s %s -padx 2 -pady 2 -fill x -expand 1 -anchor w",
               this->StandardViewsFrame->GetWidgetName(),
               this->CameraIconsFrame->GetWidgetName(),
               this->ManipulatorControl2D->GetWidgetName(),
               this->ManipulatorControl3D->GetWidgetName(),
               this->CameraControlFrame->GetWidgetName());

  frame->Delete();

  this->Notebook->Raise("General");
}

//----------------------------------------------------------------------------
void vtkPVRenderView::StandardViewCallback(float x, float y, float z)
{
  this->GetTraceHelper()->AddEntry("$kw(%s) StandardViewCallback %f %f %f",
                      this->GetTclName(), x, y, z);
  
  vtkCamera *cam = this->GetRenderer()->GetActiveCamera();
  cam->SetFocalPoint(0.0, 0.0, 0.0);
  cam->SetPosition(x, y, z);
  if (y == 0.0)
    {
    cam->SetViewUp(0.0, 1.0, 0.0);
    }
  else
    {
    cam->SetViewUp(1.0, 0.0, 0.0);
    }

  this->ResetCamera();
  this->EventuallyRender();
}

//----------------------------------------------------------------------------
void vtkPVRenderView::UpdateNavigationWindow(vtkPVSource *currentSource, 
                                             int nobind)
{
  if (currentSource == 0)
    {
    return;
    }
  if (this->NavigationWindow)
    {
    this->NavigationWindow->SetCreateSelectionBindings(!nobind);
    this->NavigationWindow->Update(currentSource);
    }
  if (this->SelectionWindow)
    {
    this->SelectionWindow->SetCreateSelectionBindings(!nobind);
    this->SelectionWindow->Update(currentSource);
    }
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetRendererBackgroundColor(double r, double g, double b)
{
  // Save the color in registry here because there is no good place to do 
  // it upon exiting or destruction.  We have to delete the render window
  // before the TKRenderWidget, so we loose access to the background color.
  // The other option is to change vtkKWView to get the background color
  // locally from the color button.
  // This used to be in vtkPVWindow.  I had to move it here because
  // the renderer was destructing before the vtkPVWindow.
  double rgb[3];
  rgb[0] = r; rgb[1] = g; rgb[2] = b;
  this->GetApplication()->SaveColorRegistryValue(2, "RenderViewBG", rgb); 
 
  // Set the color of the interface button.
  this->RendererBackgroundColor->SetColor(r, g, b);
  // Since setting the color of the button from a script does
  // not invoke the callback, We also trace the view.
  this->GetTraceHelper()->AddEntry("$kw(%s) SetRendererBackgroundColor %f %f %f",
                      this->GetTclName(), r, g, b);
  this->RenderModuleProxy->SetBackgroundColorCM(rgb);
  this->EventuallyRender();
}

//----------------------------------------------------------------------------
// a litle more complex than just "bind $widget <Expose> {%W Render}"
// we have to handle all pending expose events otherwise they que up.
void vtkPVRenderView::Exposed()
{  
  if (this->InExpose)
    {
    return;
    }
  this->InExpose = 1;
  this->Script("update");
  this->EventuallyRender();
  this->InExpose = 0;
}

//----------------------------------------------------------------------------
// called on Configure event. Configure events might not generate an
// expose event if the size of the view gets smaller.
// At the moment, just call Exposed(), which does what we want to do,
// i.e. eventually render. If an Expose event was also generated after
// that Configure event, it will be discard because of the InExpose ivar
// logic (see above)
void vtkPVRenderView::Configured()
{
  vtkSMRenderModuleProxy* rm = this->RenderModuleProxy;
  if (this->BlockRender)
    {
    this->BlockRender = 2;
    return;
    }
  if (rm)
    {
    rm->InteractiveRender();
    }
}


//----------------------------------------------------------------------------
void vtkPVRenderView::ResetCamera()
{
  this->RenderModuleProxy->ResetCamera();
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetCameraState(float p0, float p1, float p2,
                                     float fp0, float fp1, float fp2,
                                     float up0, float up1, float up2)
{
  vtkCamera *cam; 
  
  // This is to trace effects of loaded scripts. 
  this->GetTraceHelper()->AddEntry(
    "$kw(%s) SetCameraState %.3f %.3f %.3f  %.3f %.3f %.3f  %.3f %.3f %.3f", 
    this->GetTclName(), p0, p1, p2, fp0, fp1, fp2, up0, up1, up2); 
  
  cam = this->GetRenderer()->GetActiveCamera(); 
  cam->SetPosition(p0, p1, p2); 
  cam->SetFocalPoint(fp0, fp1, fp2); 
  cam->SetViewUp(up0, up1, up2); 
  
  this->EventuallyRender(); 
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetCameraParallelScale(float scale)
{
  this->GetTraceHelper()->AddEntry("$kw(%s) SetCameraParallelScale %.3f",
                      this->GetTclName(), scale);
  
  this->GetRenderer()->GetActiveCamera()->SetParallelScale(scale);
  
  this->EventuallyRender();
}

//----------------------------------------------------------------------------
vtkPVApplication* vtkPVRenderView::GetPVApplication()
{
  if (this->GetApplication() == NULL)
    {
    return NULL;
    }
  
  if (this->GetApplication()->IsA("vtkPVApplication"))
    {  
    return (vtkPVApplication*)(this->GetApplication());
    }
  else
    {
    vtkErrorMacro("Bad typecast");
    return NULL;
    } 
}


//----------------------------------------------------------------------------
void vtkPVRenderView::ForceRender()
{
  vtkPVApplication *pvApp = this->GetPVApplication();
  if ( pvApp )
    {
    if (this->TimerToken)
      {
      Tcl_DeleteTimerHandler( this->TimerToken );
      this->TimerToken = NULL;
      }
    this->CornerAnnotation->UpdateCornerText();
    pvApp->GetProcessModule()->SetGlobalLODFlag(0);
    this->RenderModuleProxy->StillRender();
    }
}

//----------------------------------------------------------------------------
void vtkPVRenderView::Render()
{
  int abort;
  if (this->BlockRender)
    {
    this->BlockRender = 2;
    return;
    }

  // Some aborts require us to que another render.
  abort = this->ShouldIAbort();
  if (abort)
    {
    if (abort == 1)
      {
      this->EventuallyRender();
      }
    return;
    }
  vtkSMRenderModuleProxy* rm = this->RenderModuleProxy;
  if (rm)
    {
    rm->InteractiveRender();
    }
}





//----------------------------------------------------------------------------
// There are a couple of ways I could do this.
// I could allow eventually render callback to occur
// and abort the render using the disable rendering flag ...
void vtkPVRenderView::UpdateTclButAvoidRendering()
{
  int saveRender = 0;

  // Remove any pending renders.
  if (this->TimerToken)
    {
    saveRender = 1;
    Tcl_DeleteTimerHandler( this->TimerToken );
    this->TimerToken = NULL;
    }

  this->Script("update");

  // Add render pending back.
  if (saveRender)
    {
    this->EventuallyRender();
    }
}

//----------------------------------------------------------------------------
void vtkPVRenderView::StartBlockingRender()
{
  vtkDebugMacro("Start blocking render requests");
  if ( this->BlockRender > 0 )
    {
    return;
    }
  this->BlockRender = 1;
}

//----------------------------------------------------------------------------
void vtkPVRenderView::EndBlockingRender()
{
  vtkDebugMacro("Stop blocking render requests");
  if ( this->BlockRender > 1 )
    {
    vtkDebugMacro("There was a render request, so call render");
    this->EventuallyRender();
    }
  this->BlockRender = 0;
}


//----------------------------------------------------------------------------
extern "C" { void PVRenderView_IdleRender(ClientData arg); }

void PVRenderView_IdleRender(ClientData arg)
{
  vtkPVRenderView *me = (vtkPVRenderView *)arg;
  me->EventuallyRenderCallBack();
}

//----------------------------------------------------------------------------
void vtkPVRenderView::EventuallyRender()
{
  vtkDebugMacro("Enqueue EventuallyRender request");
  this->CornerAnnotation->UpdateCornerText();

  this->RenderTimer->StartTimer();
  if ( !this->TimerToken )
    {
    this->TimerToken = Tcl_CreateTimerHandler(110, 
                                              PVRenderView_IdleRender, 
                                              (ClientData)this);
    }
}

//----------------------------------------------------------------------------
void vtkPVRenderView::EventuallyRenderCallBack()
{
  int abortFlag;
  double elapsedTime;
  
  this->RenderTimer->StopTimer();
  
  elapsedTime = this->RenderTimer->GetElapsedTime();
  abortFlag = this->ShouldIAbort();
  
  this->TimerToken = NULL;
  
  if ( elapsedTime < 0.1 || abortFlag != 0 )
    {
    if ( abortFlag == 1 )
      {
      this->TimerToken = Tcl_CreateTimerHandler(200, 
                                                PVRenderView_IdleRender, 
                                                (ClientData)this);    
      }
    else if ( elapsedTime < 0.1 )
      {
      this->TimerToken = Tcl_CreateTimerHandler(100, 
                                                PVRenderView_IdleRender, 
                                                (ClientData)this);    
      }
    return;
    }
  
  if ( this->BlockRender )
    {
    this->BlockRender = 2;
    return;
    }

  vtkPVApplication *pvApp = this->GetPVApplication();
  if (pvApp)
    {
    vtkPVProcessModule *pm = pvApp->GetProcessModule();
    if (pm)
      {
      pm->SetGlobalLODFlag(0);
      vtkSMRenderModuleProxy* rm = this->RenderModuleProxy;
      if (rm)
        {
        rm->StillRender();
        }
      }
    }
}

//----------------------------------------------------------------------------
void vtkPVRenderView::TriangleStripsCallback()
{
  if (this->TriangleStripsCheck->GetSelectedState())
    {
    vtkTimerLog::MarkEvent("--- Enable triangle strips.");
    }
  else
    {
    vtkTimerLog::MarkEvent("--- Disable triangle strips.");
    }

  this->SetUseTriangleStrips(this->TriangleStripsCheck->GetSelectedState());
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetUseTriangleStrips(int state)
{

  this->GetTraceHelper()->AddEntry("$kw(%s) SetUseTriangleStrips %d", this->GetTclName(),
    state);

  if (this->TriangleStripsCheck->GetSelectedState() != state)
    {
    this->TriangleStripsCheck->SetSelectedState(state);
    }
  
  if ( ! this->ImmediateModeCheck->GetSelectedState() && ! state)
    { // Make sure immediate mode is on when strips are off.
    this->SetUseImmediateMode(1);
    }

  vtkSMRenderModuleProxy* rm = this->RenderModuleProxy;
  vtkSMIntVectorProperty* ivp = vtkSMIntVectorProperty::SafeDownCast(
    rm->GetProperty("UseTriangleStrips"));
  if (!ivp)
    {
    vtkErrorMacro("Failed to find property UseTriangleStrips on "
      "RenderModuleProxy.");
    return;
    }
  ivp->SetElement(0, state);
  rm->UpdateVTKObjects();

  // Save this selection on the server manager so new
  // part displays will have it a s a default.
  this->GetPVApplication()->GetProcessModule()->SetUseTriangleStrips(state);

  this->EventuallyRender();
}

//----------------------------------------------------------------------------
void vtkPVRenderView::ParallelProjectionOn()
{
  this->GetTraceHelper()->AddEntry("$kw(%s) ParallelProjectionOn", this->GetTclName());

  if (!this->ParallelProjectionCheck->GetSelectedState())
    {
    this->ParallelProjectionCheck->SetSelectedState(1);
    }
  vtkSMRenderModuleProxy* rm = this->RenderModuleProxy;
  vtkSMIntVectorProperty* ivp = vtkSMIntVectorProperty::SafeDownCast(
    rm->GetProperty("CameraParallelProjection"));
  if (!ivp)
    {
    vtkErrorMacro("Failed to find property CameraParallelProjection "
      "on RenderModuleProxy.");
    return;
    }
  ivp->SetElement(0, 1);
  rm->UpdateVTKObjects();
  this->EventuallyRender();
}

//----------------------------------------------------------------------------
void vtkPVRenderView::ParallelProjectionOff()
{
  this->GetTraceHelper()->AddEntry("$kw(%s) ParallelProjectionOff", this->GetTclName());
  if (this->ParallelProjectionCheck->GetSelectedState())
    {
    this->ParallelProjectionCheck->SetSelectedState(0);
    }

  vtkSMRenderModuleProxy* rm = this->RenderModuleProxy;
  vtkSMIntVectorProperty* ivp = vtkSMIntVectorProperty::SafeDownCast(
    rm->GetProperty("CameraParallelProjection"));
  if (!ivp)
    {
    vtkErrorMacro("Failed to find property CameraParallelProjection "
      "on RenderModuleProxy.");
    return;
    }
  ivp->SetElement(0, 0);
  rm->UpdateVTKObjects();
  this->EventuallyRender();
}

//----------------------------------------------------------------------------
void vtkPVRenderView::ParallelProjectionCallback()
{

  if (this->ParallelProjectionCheck->GetSelectedState())
    {
    vtkTimerLog::MarkEvent("--- Enable parallel projection.");
    this->ParallelProjectionOn();
    }
  else
    {
    vtkTimerLog::MarkEvent("--- Disable parallel projection.");
    this->ParallelProjectionOff();
    }
}

//----------------------------------------------------------------------------
void vtkPVRenderView::ImmediateModeCallback()
{
  if (this->ImmediateModeCheck->GetSelectedState())
    {
    vtkTimerLog::MarkEvent("--- Disable display lists.");
    }
  else
    {
    vtkTimerLog::MarkEvent("--- Enable display lists.");
    }
  
  this->SetUseImmediateMode(this->ImmediateModeCheck->GetSelectedState());
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetUseImmediateMode(int state)
{
  this->GetTraceHelper()->AddEntry("$kw(%s) SetUseImmediateMode %d", this->GetTclName(),
    state);

  if (this->ImmediateModeCheck->GetSelectedState() != state)
    {
    this->ImmediateModeCheck->SetSelectedState(state);
    }
  
  if ( ! state && ! this->TriangleStripsCheck->GetSelectedState())
    { // Make sure triangle strips are on.
    // When immediate mode is off, triangle strips must be on.
    this->SetUseTriangleStrips(1);
    }
 
  vtkSMRenderModuleProxy* rm = this->RenderModuleProxy;
  vtkSMIntVectorProperty* ivp = vtkSMIntVectorProperty::SafeDownCast(
    rm->GetProperty("UseImmediateMode"));
  if (!ivp)
    {
    vtkErrorMacro("Failed to find property UseImmediateMode on RenderModuleProxy.");
    return;
    }
  ivp->SetElement(0, state);
  rm->UpdateVTKObjects();
  
  // Save this selection on the server manager so new
  // part displays will have it a s a default.
  this->GetPVApplication()->GetProcessModule()->SetUseImmediateMode(state);

  this->EventuallyRender();
}

//----------------------------------------------------------------------------
double vtkPVRenderView::GetLight(int /*vtkLightKit::LightKitType*/ type, 
                                 int /*vtkLightKit::LightKitSubType*/ subtype)
{
  double value = 0;
  switch ( type )
    {
    case vtkLightKit::TKeyLight:
      switch ( subtype )
        {
        case vtkLightKit::Warmth:
          value = this->KeyLightScale[0]->GetValue();
          break;
        case vtkLightKit::Intensity:
          value = this->KeyLightScale[1]->GetValue();
          break;
        case vtkLightKit::Elevation:
          value = this->KeyLightScale[2]->GetValue();
          break;
        case vtkLightKit::Azimuth:
          value = this->KeyLightScale[3]->GetValue();
          break;
        default:
          vtkErrorMacro("Error");
          break;
        }
      break;
    case vtkLightKit::TFillLight:
      switch ( subtype )
        {
        case vtkLightKit::Warmth:
          value = this->FillLightScale[0]->GetValue();
          break;
        case vtkLightKit::KFRatio:
          value = this->FillLightScale[1]->GetValue();
          break;
        case vtkLightKit::Elevation:
          value = this->FillLightScale[2]->GetValue();
          break;
        case vtkLightKit::Azimuth:
          value = this->FillLightScale[3]->GetValue();
          break;
        default:
          vtkErrorMacro("Error");
          break;
        }
      break;
    case vtkLightKit::TBackLight:
      switch ( subtype )
        {
        case vtkLightKit::Warmth:
          value = this->BackLightScale[0]->GetValue();
          break;
        case vtkLightKit::KBRatio:
          value = this->BackLightScale[1]->GetValue();
          break;
        case vtkLightKit::Elevation:
          value = this->BackLightScale[2]->GetValue();
          break;
        case vtkLightKit::Azimuth:
          value = this->BackLightScale[3]->GetValue();
          break;
        default:
          vtkErrorMacro("Error");
          break;
        }
      break;
    case vtkLightKit::THeadLight:
      switch ( subtype )
        {
        case vtkLightKit::Warmth:
          value = this->HeadLightScale[0]->GetValue();
          break;
        case vtkLightKit::KHRatio:
          value = this->HeadLightScale[1]->GetValue();
          break;
        default:
          vtkErrorMacro("Error");
          break;
        }
      break;
    default:
      vtkErrorMacro("Error");
    }

  return value;
}

//----------------------------------------------------------------------------
// Helper function to down cast to double vector sm property and set value
inline int DoubleVectSetElement(vtkSMProperty *prop, double value)
{
  vtkSMDoubleVectorProperty *dp = vtkSMDoubleVectorProperty::SafeDownCast( prop );
  return dp->SetElements1(value);
}
inline int IntVectSetElement(vtkSMProperty* prop, int value)
{
  vtkSMIntVectorProperty* ip = vtkSMIntVectorProperty::SafeDownCast(prop);
  return ip->SetElement(0, value);
}

//----------------------------------------------------------------------------
void vtkPVRenderView::DefaultLightIntensityCallback()
{
  double value = this->DefaultLightIntensity->GetValue();
  this->SetDefaultLightIntensityNoTrace(value);
  this->Render();
}

//----------------------------------------------------------------------------
void vtkPVRenderView::DefaultLightIntensityEndCallback()
{
  double value = this->DefaultLightIntensity->GetValue();
  this->SetDefaultLightIntensity(value);
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetDefaultLightIntensity(double intensity)
{
  this->SetDefaultLightIntensityNoTrace(intensity);
  this->EventuallyRender();
  this->GetTraceHelper()->AddEntry("$kw(%s) SetDefaultLightIntensity %f", 
    this->GetTclName(), intensity);
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetDefaultLightIntensityNoTrace(double intensity)
{
  this->DefaultLightIntensity->SetValue(intensity);
  DoubleVectSetElement(this->RenderModuleProxy->GetProperty("LightIntensity"), 
    intensity);
  this->RenderModuleProxy->UpdateVTKObjects();

  // Save in registry.
  this->GetApplication()->SetRegistryValue(2, "RunTime",
    VTK_PV_DEFAULT_LIGHT_INTENSITY_REG_KEY, "%f", intensity);
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetDefaultLightAmbientColor(double r, double g, double b)
{
  vtkSMDoubleVectorProperty *dp = vtkSMDoubleVectorProperty::SafeDownCast(
    this->RenderModuleProxy->GetProperty("LightAmbientColor"));
  dp->SetElements3(r, g, b);
  this->RenderModuleProxy->UpdateVTKObjects();
  this->EventuallyRender();
  this->GetTraceHelper()->AddEntry("$kw(%s) SetDefaultLightAmbientColor %f %f %f", this->GetTclName(), r, g, b);
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetDefaultLightDiffuseColor(double r, double g, double b)
{
  vtkSMDoubleVectorProperty *dp = vtkSMDoubleVectorProperty::SafeDownCast(this->RenderModuleProxy->GetProperty("LightDiffuseColor"));
  dp->SetElements3(r, g, b);
  this->RenderModuleProxy->UpdateVTKObjects();
  this->EventuallyRender();
  this->GetTraceHelper()->AddEntry("$kw(%s) SetDefaultLightDiffuseColor %f %f %f", this->GetTclName(), r, g, b);
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetDefaultLightSpecularColor(double r, double g, double b)
{
  vtkSMDoubleVectorProperty *dp = vtkSMDoubleVectorProperty::SafeDownCast(this->RenderModuleProxy->GetProperty("LightSpecularColor"));
  dp->SetElements3(r, g, b);
  this->RenderModuleProxy->UpdateVTKObjects();
  this->EventuallyRender();
  this->GetTraceHelper()->AddEntry("$kw(%s) SetDefaultLightSpecularColor %f %f %f", this->GetTclName(), r, g, b);
}

//----------------------------------------------------------------------------
void vtkPVRenderView::DefaultLightSwitchCallback()
{
  int value = this->DefaultLightSwitch->GetSelectedState();
  this->SetDefaultLightSwitch(value);
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetDefaultLightSwitch(int val)
{
  this->DefaultLightSwitch->SetSelectedState(val);
  IntVectSetElement(this->RenderModuleProxy->GetProperty("LightSwitch"), val);
  this->RenderModuleProxy->UpdateVTKObjects();
  this->EventuallyRender();
  
  this->GetTraceHelper()->AddEntry("$kw(%s) SetDefaultLightSwitch %d", 
    this->GetTclName(), val);

  // Add to registry.
  this->GetApplication()->SetRegistryValue(2, "RunTime", 
    VTK_PV_ENABLE_DEFAULT_LIGHT_REG_KEY,  (val? "1" : "0"));
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetLightNoTrace(int type, int subtype, double value)
{
  // Both GUI settings and acu
  switch ( type )
    {
    case vtkLightKit::TKeyLight:
      switch ( subtype )
        {
        case vtkLightKit::Warmth:
          this->KeyLightScale[0]->SetValue(value);
          break;
        case vtkLightKit::Intensity:
          this->KeyLightScale[1]->SetValue(value);
          break;
        case vtkLightKit::Elevation:
          this->KeyLightScale[2]->SetValue(value);
          break;
        case vtkLightKit::Azimuth:
          this->KeyLightScale[3]->SetValue(value);
          break;
        default:
          vtkErrorMacro("Error");
          break;
        }
      break;
    case vtkLightKit::TFillLight:
      switch ( subtype )
        {
        case vtkLightKit::Warmth:
          this->FillLightScale[0]->SetValue(value);
          break;
        case vtkLightKit::KFRatio:
          this->FillLightScale[1]->SetValue(value);
          break;
        case vtkLightKit::Elevation:
          this->FillLightScale[2]->SetValue(value);
          break;
        case vtkLightKit::Azimuth:
          this->FillLightScale[3]->SetValue(value);
          break;
        default:
          vtkErrorMacro("Error");
          break;
        }
      break;
    case vtkLightKit::TBackLight:
      switch ( subtype )
        {
        case vtkLightKit::Warmth:
          this->BackLightScale[0]->SetValue(value);
          break;
        case vtkLightKit::KBRatio:
          this->BackLightScale[1]->SetValue(value);
          break;
        case vtkLightKit::Elevation:
          this->BackLightScale[2]->SetValue(value);
          break;
        case vtkLightKit::Azimuth:
          this->BackLightScale[3]->SetValue(value);
          break;
        default:
          vtkErrorMacro("Error");
          break;
        }
      break;
    case vtkLightKit::THeadLight:
      switch ( subtype )
        {
        case vtkLightKit::Warmth:
          this->HeadLightScale[0]->SetValue(value);
          break;
        case vtkLightKit::KHRatio:
          this->HeadLightScale[1]->SetValue(value);
          break;
        default:
          vtkErrorMacro("Error");
          break;
        }
      break;
    default:
      vtkErrorMacro("Error");
    }

  vtkstd::string s;
  s = vtkLightKit::GetStringFromType(type);
  s += vtkLightKit::GetStringFromSubType(subtype);
  DoubleVectSetElement(this->RenderModuleProxy->GetProperty(s.c_str()), value);
  this->RenderModuleProxy->UpdateVTKObjects();

  // Save in reg.
  this->GetApplication()->SetRegistryValue(2, "RunTime", s.c_str(), "%f", value);
  // Do not render here (do it in the callback, since it could be either
  // Render or EventuallyRender depending on the interaction)
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetLight(int type, int subtype, double value)
{
  this->SetLightNoTrace(type, subtype, value);
  this->EventuallyRender();

  this->GetTraceHelper()->AddEntry("$kw(%s) SetLight %d %d %f",
                      this->GetTclName(), type, subtype, value);
}

//----------------------------------------------------------------------------
void vtkPVRenderView::LightCallback(int /*LightKitType*/ type, int /*LightKitSubType*/ subtype)
{
  double value = this->GetLight(type, subtype);
  this->SetLightNoTrace(type, subtype, value);
  this->Render();
}

//----------------------------------------------------------------------------
void vtkPVRenderView::LightEndCallback(int type, int subtype)
{
  double value = this->GetLight(type, subtype);
  this->SetLight(type, subtype, value);
}

//----------------------------------------------------------------------------
void vtkPVRenderView::MaintainLuminanceCallback()
{
  int val = this->MaintainLuminanceButton->GetSelectedState();
  this->SetMaintainLuminance(val);
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetMaintainLuminance(int s)
{
  // Set the GUI
  this->MaintainLuminanceButton->SetSelectedState(s);
  vtkSMProperty *prop = this->RenderModuleProxy->GetProperty("MaintainLuminance");
  vtkSMIntVectorProperty *dp = vtkSMIntVectorProperty::SafeDownCast( prop );
  dp->SetElements1(s);
  this->RenderModuleProxy->UpdateVTKObjects();
  this->EventuallyRender();

  this->GetTraceHelper()->AddEntry("$kw(%s) SetMaintainLuminance %d",
                      this->GetTclName(), s);
  this->GetApplication()->SetRegistryValue(2, "RunTime", 
    VTK_PV_MAINTAIN_LUMINANCE_REG_KEY, (s? "1" : "0"));
}

//----------------------------------------------------------------------------
void vtkPVRenderView::UseLightCallback()
{
  int val = this->UseLightButton->GetSelectedState();
  this->SetUseLight(val);
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetUseLight(int s)
{
  // Set the GUI
  this->UseLightButton->SetSelectedState(s);
  vtkSMProperty* p = this->RenderModuleProxy->GetProperty("UseLight");
  IntVectSetElement(p, s);
  this->RenderModuleProxy->UpdateVTKObjects();

  this->EventuallyRender();

  this->GetTraceHelper()->AddEntry("$kw(%s) SetUseLight %d", this->GetTclName(), s);
  // Save to registry.
  this->GetApplication()->SetRegistryValue(2, "RunTime", VTK_PV_USE_LIGHT_KIT_REG_KEY, 
    (s? "1" : "0"));
}

//----------------------------------------------------------------------------
vtkPVWindow *vtkPVRenderView::GetPVWindow()
{
  vtkPVWindow *pvWin = vtkPVWindow::SafeDownCast(this->GetParentWindow());

  return pvWin;
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SaveInBatchScript(ofstream* file)
{
  *file << "# RenderModule Proxy ---------- " << endl;
  if (this->RenderModuleProxy)
    {
    this->RenderModuleProxy->SaveInBatchScript(file);
    }
  *file << "# End of RenderModuleProxy ---- " << endl;
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SaveState(ofstream* file)
{
  vtkCamera *camera;
  double position[3];
  double focalPoint[3];
  double viewUp[3];
  double *color;

  color = this->GetRenderer()->GetBackground();
  *file << "$kw(" << this->GetTclName() << ") SetRendererBackgroundColor " 
        << color[0] << " " << color[1] << " " << color[2] << endl;

  camera = this->GetRenderer()->GetActiveCamera();
  camera->GetPosition(position);
  camera->GetFocalPoint(focalPoint);
  camera->GetViewUp(viewUp);
  
  if (camera->GetParallelProjection())
    {
    *file << "$kw(" << this->GetTclName() << ") ParallelProjectionOn" << endl;
    *file << "$kw(" << this->GetTclName() << ") SetCameraParallelScale "
          << camera->GetParallelScale() << endl;
    }
  else
    {
    *file << "$kw(" << this->GetTclName() << ") ParallelProjectionOff" << endl;
    }
  
  *file << "$kw(" << this->GetTclName() << ") SetCameraState " 
        << position[0] << " " << position[1] << " " << position[2] << " "
        << focalPoint[0] << " " << focalPoint[1] << " " << focalPoint[2] << " "
        << viewUp[0] << " " << viewUp[1] << " " << viewUp[2] << endl; 

  *file << "$kw(" << this->GetTclName() << ") SetUseTriangleStrips "
        << this->TriangleStripsCheck->GetSelectedState() << endl;
  
  *file << "$kw(" << this->GetTclName() << ") SetUseImmediateMode "
        << this->ImmediateModeCheck->GetSelectedState() << endl;
  
  if (this->RenderModuleUI)
    {
    *file << "set kw(" << this->RenderModuleUI->GetTclName()
          << ") [$kw(" << this->GetTclName() << ") GetRenderModuleUI]" << endl;
    this->RenderModuleUI->SaveState(file);
    }
  
  *file << "set kw(" << this->CornerAnnotation->GetTclName()
        << ") [$kw(" << this->GetTclName() << ") GetCornerAnnotation]" << endl;
  this->CornerAnnotation->SaveState(file);
  
  *file << "$kw(" << this->GetTclName() << ") SetOrientationAxesVisibility "
        << this->OrientationAxesCheck->GetSelectedState() << endl;
  *file << "$kw(" << this->GetTclName() << ") SetOrientationAxesInteractivity "
        << this->OrientationAxesInteractiveCheck->GetSelectedState() << endl;
  color = this->OrientationAxesOutlineColor->GetColor();
  *file << "$kw(" << this->GetTclName() << ") SetOrientationAxesOutlineColor "
        << color[0] << " " << color[1] << " " << color[2] << endl;
  color = this->OrientationAxesTextColor->GetColor();
  *file << "$kw(" << this->GetTclName() << ") SetOrientationAxesTextColor "
        << color[0] << " " << color[1] << " " << color[2] << endl;
  
  *file << "set kw(" << this->ManipulatorControl2D->GetTclName()
        << ") [$kw(" << this->GetTclName() << ") GetManipulatorControl2D]"
        << endl;
  this->ManipulatorControl2D->SaveState(file);
  
  *file << "set kw(" << this->ManipulatorControl3D->GetTclName()
        << ") [$kw(" << this->GetTclName() << ") GetManipulatorControl3D]"
        << endl;
  this->ManipulatorControl3D->SaveState(file);

  // Saving light state:
  if(  this->UseLightButton->GetSelectedState() )
    {
    *file << "$kw(" << this->GetTclName() << ") SetUseLight "
      << this->UseLightButton->GetSelectedState() << endl;
    *file << "$kw(" << this->GetTclName() << ") SetMaintainLuminance "
      << this->MaintainLuminanceButton->GetSelectedState() << endl;

    for(int i = 0; i < 4; i++) // For each light type
      {
      for(int j=0; j<4; j++) // For each light subtype
        {
        // Convert j to the light's subtype
        if( !(i == 3 && j >= 2) )  // HeadLight has only two parameters
          {
          int subtype = vtkLightKit::GetSubType((vtkLightKit::LightKitType)i,j);
          double light = this->GetLight(i,subtype);
          *file << "$kw(" << this->GetTclName() << ") SetLight "
            << i << " " << subtype << " " << light << endl;
          }
        }
      }
    }
}

//----------------------------------------------------------------------------
int* vtkPVRenderView::GetRenderWindowSize()
{
  if ( this->GetRenderWindow() )
    {
    return this->GetRenderWindow()->GetSize();
    }
  return 0;
}

//----------------------------------------------------------------------------
void vtkPVRenderView::UpdateCameraManipulators()
{
  vtkPVInteractorStyleControl *iscontrol3D = this->GetManipulatorControl3D();
  vtkPVInteractorStyleControl *iscontrol2D = this->GetManipulatorControl2D();
  iscontrol3D->UpdateMenus();
  iscontrol2D->UpdateMenus();
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetupCameraManipulators()
{
  vtkPVInteractorStyleControl *iscontrol3D = this->GetManipulatorControl3D();
  vtkPVInteractorStyleControl *iscontrol2D = this->GetManipulatorControl2D();

  iscontrol3D->SetCurrentManipulator(0, 0, "Rotate");
  iscontrol3D->SetCurrentManipulator(1, 0, "Pan");
  iscontrol3D->SetCurrentManipulator(2, 0, "Zoom");
  iscontrol3D->SetCurrentManipulator(0, 1, "Roll");
  iscontrol3D->SetCurrentManipulator(1, 1, "Center");
  iscontrol3D->SetCurrentManipulator(2, 1, "Pan");
  iscontrol3D->SetCurrentManipulator(0, 2, "FlyIn");
  iscontrol3D->SetCurrentManipulator(2, 2, "FlyOut");
  iscontrol3D->SetDefaultManipulator("Rotate");
  iscontrol3D->UpdateMenus();

  iscontrol2D->SetCurrentManipulator(0, 1, "Roll");
  iscontrol2D->SetCurrentManipulator(1, 0, "Pan");
  iscontrol2D->SetCurrentManipulator(2, 1, "Pan");
  iscontrol2D->SetCurrentManipulator(2, 0, "Zoom");
  iscontrol2D->SetDefaultManipulator("Pan");
  iscontrol2D->UpdateMenus();
}

//----------------------------------------------------------------------------
void vtkPVRenderView::StoreCurrentCamera(int position)
{
  if ( this->CameraIcons[position] )
    {
    this->CameraIcons[position]->StoreCamera();
    }
}

//----------------------------------------------------------------------------
void vtkPVRenderView::RestoreCurrentCamera(int position)
{
  if ( this->CameraIcons[position] )
    {
    this->CameraIcons[position]->RestoreCamera();
    }
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SaveAsImage(const char* filename) 
{
  const char* writerName = 0;

  vtksys_stl::string ext_stl = 
    vtksys::SystemTools::GetFilenameLastExtension(filename);
  if (ext_stl == ".bmp")
    {
    writerName = "vtkBMPWriter";
    }
  else if (ext_stl == ".tif")
    {
    writerName = "vtkTIFFWriter";
    }
  else if (ext_stl == ".ppm")
    {
    writerName = "vtkPNMWriter";
    }
  else if (ext_stl == ".png")
    {
    writerName = "vtkPNGWriter";
    }
  else if (ext_stl == ".jpg" || ext_stl == ".jpeg")
    {
    writerName = "vtkJPEGWriter";
    }
  this->Script("update");
  if (this->RenderModuleProxy->WriteImage(filename, writerName) == 
      vtkErrorCode::OutOfDiskSpaceError)
    {
    vtkKWMessageDialog::PopupMessage(
      this->GetApplication(), this->ParentWindow, "Write Error",
      "There is insufficient disk space to save this image. The file will be "
      "deleted.");
    }
}


//----------------------------------------------------------------------------
void vtkPVRenderView::ExecuteEvent(vtkObject*, unsigned long event, void* par)
{
  if ( event == vtkCommand::CursorChangedEvent )
    {
    int val = *(static_cast<int*>(par));
    const char* image = "left_ptr";
    switch ( val ) 
      {
      case VTK_CURSOR_ARROW:
        image = "arrow";
        break;
      case VTK_CURSOR_SIZENE:
        image = "top_right_corner";
        break;
      case VTK_CURSOR_SIZENW:        
        image = "top_left_corner";
        break;
      case VTK_CURSOR_SIZESW:
        image = "bottom_left_corner";
        break;
      case VTK_CURSOR_SIZESE:
        image = "bottom_right_corner";
        break;
      case VTK_CURSOR_SIZENS:
        image = "sb_v_double_arrow";
        break;
      case VTK_CURSOR_SIZEWE:
        image = "sb_h_double_arrow";
        break;
      case VTK_CURSOR_SIZEALL:
        image = "hand2";
        break;
      case VTK_CURSOR_HAND:
        image = "hand2";
        break;
      }
    this->Script("%s config -cursor %s", 
                 this->GetPVWindow()->GetWidgetName(), image);
    } 
}

//----------------------------------------------------------------------------
void vtkPVRenderView::Enable3DWidget(vtkInteractorObserver *o)
{
  vtkRenderer *ren = this->GetRenderer2D();
  if (!ren)
    {
    return;
    }
  
  vtkRendererCollection *savedRens = vtkRendererCollection::New();
  vtkRenderWindow *renWin = this->GetRenderWindow();
  vtkRendererCollection *rens = renWin->GetRenderers();
  
  vtkRenderer *current;
  
  int i, numRens = rens->GetNumberOfItems();
  int renId = rens->IsItemPresent(ren) - 1;
  rens->InitTraversal();
  for (i = 0; i < numRens; i++)
    {
    current = rens->GetNextItem();
    if (current != ren)
      {
      savedRens->AddItem(current);
      renWin->RemoveRenderer(current);
      }
    }
  
  o->SetEnabled(1);  

  // put the renderers back in the correct order
  renWin->RemoveRenderer(ren);
  savedRens->InitTraversal();
  for (i = 0 ; i < numRens; i++)
    {
    if (i == renId)
      {
      renWin->AddRenderer(ren);
      }
    else
      {
      renWin->AddRenderer(savedRens->GetNextItem());
      }
    }      
  savedRens->Delete();
}

//----------------------------------------------------------------------------
int vtkPVRenderView::GetOrientationAxesVisibility()
{
  if (!this->OrientationAxesCheck)
    {
    return 0;
    }
  return this->OrientationAxesCheck->GetSelectedState();
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetOrientationAxesVisibility(int val)
{
  if (this->OrientationAxesCheck->GetSelectedState() != val)
    {
    this->GetTraceHelper()->AddEntry("$kw(%s) SetOrientationAxesVisibility %d",
                        this->GetTclName(), val);
    this->OrientationAxesCheck->SetSelectedState(val);
    }
  
  if (!this->OrientationAxes->GetInteractor())
    {
    this->OrientationAxes->SetInteractor(this->GetPVWindow()->GetInteractor());
    }
  if (!this->OrientationAxes->GetParentRenderer())
    {
    this->OrientationAxes->SetParentRenderer(this->GetRenderer());
    }

  this->OrientationAxes->SetEnabled(val);
  this->EventuallyRender();
}

//----------------------------------------------------------------------------
void vtkPVRenderView::OrientationAxesCheckCallback()
{
  int val = this->OrientationAxesCheck->GetSelectedState();
  this->GetTraceHelper()->AddEntry("$kw(%s) SetOrientationAxesVisibility %d",
                      this->GetTclName(), val);
  this->SetOrientationAxesVisibility(val);
  
  this->GetApplication()->SetRegistryValue(2, "RunTime",
                                       "OrientationAxesVisibility",
                                       (val ? "1" : "0"));
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetOrientationAxesInteractivity(int val)
{
  if (this->OrientationAxesInteractiveCheck->GetSelectedState() != val)
    {
    this->GetTraceHelper()->AddEntry("$kw(%s) SetOrientationAxesInteractivity %d",
                        this->GetTclName(), val);
    this->OrientationAxesInteractiveCheck->SetSelectedState(val);
    }
  
  this->OrientationAxes->SetInteractive(val);
}

//----------------------------------------------------------------------------
void vtkPVRenderView::OrientationAxesInteractiveCallback()
{
  int val = this->OrientationAxesInteractiveCheck->GetSelectedState();
  this->GetTraceHelper()->AddEntry("$kw(%s) SetOrientationAxesInteractivity %d",
                      this->GetTclName(), val);
  this->SetOrientationAxesInteractivity(val);
  this->GetApplication()->SetRegistryValue(2, "RunTime",
                                       "OrientationAxesInteractivity",
                                       (val ? "1" : "0"));
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetOrientationAxesOutlineColor(double r, double g, double b)
{
  double *color = this->OrientationAxesOutlineColor->GetColor();
  if (r != color[0] || g != color[1] || b != color[2])
    {
    this->OrientationAxesOutlineColor->SetColor(r, g, b);
    }
  this->GetTraceHelper()->AddEntry("$kw(%s) SetOrientationAxesOutlineColor %lf %lf %lf",
                      this->GetTclName(), r, g, b);
  this->OrientationAxes->SetOutlineColor(r, g, b);
  this->GetApplication()->SaveColorRegistryValue(
    2, "OrientationAxesOutline", this->OrientationAxes->GetOutlineColor());
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetOrientationAxesTextColor(double r, double g, double b)
{
  double *color = this->OrientationAxesTextColor->GetColor();
  if (r != color[0] || g != color[1] || b != color[2])
    {
    this->OrientationAxesTextColor->SetColor(r, g, b);
    }
  this->GetTraceHelper()->AddEntry("$kw(%s) SetOrientationAxesTextColor %lf %lf %lf",
                      this->GetTclName(), r, g, b);
  this->OrientationAxes->SetAxisLabelColor(r, g, b);
  this->GetApplication()->SaveColorRegistryValue(
    2, "OrientationAxesText", this->OrientationAxes->GetAxisLabelColor());
  this->EventuallyRender();
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetRenderWindowSize(int x, int y)
{
  this->GetRenderWindow()->SetSize(x,y);
}

//----------------------------------------------------------------------------
void vtkPVRenderView::EditCopy()
{
  vtkWindowToImageFilter *w2i = vtkWindowToImageFilter::New();
  w2i->SetInput(this->GetRenderWindow());
  w2i->ShouldRerenderOff();
  w2i->Update();

#ifdef _WIN32
  // get the pointer to the data
  unsigned char *ptr = 
    (unsigned char *)(w2i->GetOutput()->GetScalarPointer());
  
  LPBITMAPINFOHEADER  lpbi;       // pointer to BITMAPINFOHEADER
  DWORD               dwLen;      // size of memory block
  HANDLE              hDIB = NULL;  // handle to DIB, temp handle
  int *size = this->GetVTKWindow()->GetSize();
  int dataWidth = ((size[0]*3+3)/4)*4;
  int srcWidth = size[0]*3;
  
  if (::OpenClipboard((HWND)this->GetVTKWindow()->GetGenericWindowId()))
    {
    EmptyClipboard();
    
    dwLen = sizeof(BITMAPINFOHEADER) + dataWidth*size[1];
    hDIB = ::GlobalAlloc(GHND, dwLen);
    lpbi = (LPBITMAPINFOHEADER) ::GlobalLock(hDIB);
    
    lpbi->biSize = sizeof(BITMAPINFOHEADER);
    lpbi->biWidth = size[0];
    lpbi->biHeight = size[1];
    lpbi->biPlanes = 1;
    lpbi->biBitCount = 24;
    lpbi->biCompression = BI_RGB;
    lpbi->biClrUsed = 0;
    lpbi->biClrImportant = 0;
    lpbi->biSizeImage = dataWidth*size[1];
    
    // copy the data to the clipboard
    unsigned char *dest = (unsigned char *)lpbi + lpbi->biSize;
    int i,j;
    for (i = 0; i < size[1]; i++)
      {
      for (j = 0; j < size[0]; j++)
        {
        *dest++ = ptr[2];
        *dest++ = ptr[1];
        *dest++ = *ptr;
        ptr += 3;
        }
      dest = dest + (dataWidth - srcWidth);
      }
    
    SetClipboardData (CF_DIB, hDIB);
    ::GlobalUnlock(hDIB);
    CloseClipboard();
    }           
#endif
  w2i->Delete();
}

//----------------------------------------------------------------------------
void vtkPVRenderView::PrintView()
{
#ifdef _WIN32
  this->Superclass::PrintView();
#else
  
  vtkWindowToImageFilter *w2i = vtkWindowToImageFilter::New();
  double DPI=0;
  if (this->GetParentWindow())
    {
    // Is this right? Should DPI be int or float?
    DPI = this->GetApplication()->GetPrintTargetDPI();
    }

  if (DPI >= 150.0)
    {
    w2i->SetMagnification(2);
    }
  if (DPI >= 300.0)
    {
    w2i->SetMagnification(3);
    }

  w2i->SetInput(this->GetRenderWindow());
  w2i->Update();
  
  this->Script("tk_getSaveFile -title \"Save Postscript\" -filetypes {{{Postscript} {.ps}}}");
  char* path = 
    strcpy(new char[strlen(this->GetApplication()->GetMainInterp()->result)+1], 
           this->GetApplication()->GetMainInterp()->result);
  if (strlen(path) != 0)
    {
    vtkPostScriptWriter *psw = vtkPostScriptWriter::New();
    psw->SetInput(w2i->GetOutput());
    psw->SetFileName(path);
    psw->Write();
    psw->Delete();

    vtkKWMessageDialog *dlg = vtkKWMessageDialog::New();
    dlg->SetMasterWindow(this->ParentWindow);
    dlg->Create(this->GetApplication());
    dlg->SetText(
      "A postscript file has been generated. You will need to\n"
      "print this file using a print command appropriate for\n"
      "your system. Typically this command is lp or lpr. For\n"
      "additional information on printing a postscript file\n"
      "please contact your system administrator.");
    dlg->Invoke();
    }
  w2i->Delete();
#endif
  this->Printing = 0;
}

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

  this->PropagateEnableState(this->StandardViewsFrame);
  this->PropagateEnableState(this->XMaxViewButton);
  this->PropagateEnableState(this->XMinViewButton);
  this->PropagateEnableState(this->YMaxViewButton);
  this->PropagateEnableState(this->YMinViewButton);
  this->PropagateEnableState(this->ZMaxViewButton);
  this->PropagateEnableState(this->ZMinViewButton);
  this->PropagateEnableState(this->RenderParametersFrame);
  this->PropagateEnableState(this->TriangleStripsCheck);
  this->PropagateEnableState(this->ParallelProjectionCheck);
  this->PropagateEnableState(this->ImmediateModeCheck);
  this->PropagateEnableState(this->RenderModuleUI);
  this->PropagateEnableState(this->InterfaceSettingsFrame);
  this->PropagateEnableState(this->Display3DWidgets);
  //Light
  this->PropagateEnableState(this->LightParameterFrame);
  this->PropagateEnableState(this->UseLightButton);
  this->PropagateEnableState(this->KeyLightLabel);
  this->PropagateEnableState(this->FillLightLabel);
  this->PropagateEnableState(this->BackLightLabel);
  this->PropagateEnableState(this->HeadLightLabel);
  int cc;
  for ( cc = 0; cc < 4; cc ++ )
    {
    this->PropagateEnableState(this->KeyLightScale[cc]);
    this->PropagateEnableState(this->FillLightScale[cc]);
    this->PropagateEnableState(this->BackLightScale[cc]);
    this->PropagateEnableState(this->HeadLightScale[cc]);
    }
  this->PropagateEnableState(this->MaintainLuminanceButton);


  this->PropagateEnableState(this->OrientationAxesFrame);
  this->PropagateEnableState(this->OrientationAxesCheck);
  this->PropagateEnableState(this->OrientationAxesInteractiveCheck);
  this->PropagateEnableState(this->OrientationAxesOutlineColor);
  this->PropagateEnableState(this->OrientationAxesTextColor);
  this->PropagateEnableState(this->SplitFrame);
  this->PropagateEnableState(this->NavigationFrame);
  this->PropagateEnableState(this->NavigationWindow);
  this->PropagateEnableState(this->SelectionWindow);
  this->PropagateEnableState(this->NavigationWindowButton);
  this->PropagateEnableState(this->SelectionWindowButton);
  this->PropagateEnableState(this->TopLevelRenderWindow);
  this->PropagateEnableState(this->ManipulatorControl2D);
  this->PropagateEnableState(this->ManipulatorControl3D);
  this->PropagateEnableState(this->CameraControlFrame);
  this->PropagateEnableState(this->CameraIconsFrame);
  for ( cc = 0; cc < 6; cc ++ )
    {
    this->PropagateEnableState(this->CameraIcons[cc]);
    }
  this->PropagateEnableState(this->CameraControlFrame);
  this->PropagateEnableState(this->CameraControl);
  this->PropagateEnableState(this->PropertiesButton);
}

//----------------------------------------------------------------------------
void vtkPVRenderView::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  os << indent << "ImmediateModeCheck: " 
     << this->GetImmediateModeCheck() << endl;
  os << indent << "SplitFrame: " 
     << this->GetSplitFrame() << endl;
  os << indent << "NavigationFrame: " 
     << this->GetNavigationFrame() << endl;
  os << indent << "TriangleStripsCheck: " 
     << this->GetTriangleStripsCheck() << endl;
  os << indent << "ParallelProjectionCheck: "
     << this->GetParallelProjectionCheck();
  os << indent << "ManipulatorControl2D: " 
     << this->ManipulatorControl2D << endl;
  os << indent << "ManipulatorControl3D: " 
     << this->ManipulatorControl3D << endl;
  os << indent << "RenderModuleUI: " << this->RenderModuleUI << endl;
  os << indent << "CameraControl: " << this->CameraControl << endl;
  os << indent << "CameraControlFrame: " << this->CameraControlFrame << endl;
  os << indent << "StandardViewsFrame: " << this->StandardViewsFrame << endl;
  os << indent << "CameraIconsFrame: " << this->CameraIconsFrame << endl;
  os << indent << "OrientationAxes: " << this->OrientationAxes << endl;
  os << indent << "OrientationAxesFrame: " << this->OrientationAxesFrame
     << endl;
  os << indent << "SourceNotebook: ";
  if( this->SourceNotebook )
    {
    this->SourceNotebook->PrintSelf(os << endl, indent.GetNextIndent() );
    }
  else
    {
    os << "(none)" << endl;
    }
  os << indent << "RenderModuleProxy: " << this->RenderModuleProxy << endl;
}

//----------------------------------------------------------------------------
// Special method to enforce the relationship between a GUI element / vtkSMproxy
// in our case only do the relationship vtkKWScale / vtkSMProperty
void InitializeScale(vtkKWScaleWithEntry *scale, vtkSMProperty *prop)
{
  // First set the domain(=range) of the KWScale
  vtkSMDoubleRangeDomain *domain = 
    vtkSMDoubleRangeDomain::SafeDownCast( prop->GetDomain("range") );
  int index, exist;
  index = 0; // In our case this is always true

  double min = domain->GetMinimum(index, exist);
  double max = domain->GetMaximum(index, exist);
  scale->SetRange(min, max);

  // Then set the resolution of the KWScale
  double res = domain->GetResolution(index, exist);
  scale->SetResolution(res);

  // Now try to access the default values, this is tricky since they are not saved anywhere
  vtkSMDoubleVectorProperty *dprop = vtkSMDoubleVectorProperty::SafeDownCast(prop);
  double value = dprop->GetElement(0);
  scale->SetValue(value);
}

