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

  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 "vtkKWApplicationSettingsInterface.h"
#include "vtkKWChangeColorButton.h"
#include "vtkKWCheckButton.h"
#include "vtkPVCornerAnnotationEditor.h"
#include "vtkKWFrame.h"
#include "vtkKWFrameWithScrollbar.h"
#include "vtkKWLabel.h"
#include "vtkKWFrameLabeled.h"
#include "vtkKWMenu.h"
#include "vtkKWMessageDialog.h"
#include "vtkKWNotebook.h"
#include "vtkPVSourceNotebook.h"
#include "vtkKWPushButton.h"
#include "vtkKWRadioButton.h"
#include "vtkKWScale.h"
#include "vtkKWSplitFrame.h"
#include "vtkObjectFactory.h"
#include "vtkPNGWriter.h"
#include "vtkPNMWriter.h"
#include "vtkPVApplication.h"
#include "vtkPVApplicationSettingsInterface.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"

/* 
 * 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_buffer_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.389");

//----------------------------------------------------------------------------
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 = vtkKWFrameLabeled::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 = vtkKWFrameLabeled::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 = vtkKWFrameLabeled::New();
  this->CameraControl = vtkPVCameraControl::New();
  
  this->NavigationFrame = vtkKWFrameLabeled::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 = vtkKWFrameLabeled::New();
  this->Display3DWidgets = vtkKWCheckButton::New();

  // Light
  this->LightParameterFrame = vtkKWFrameLabeled::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]  = vtkKWScale::New();
    this->FillLightScale[cc] = vtkKWScale::New();
    this->BackLightScale[cc] = vtkKWScale::New();
    this->HeadLightScale[cc] = vtkKWScale::New();
    }
  this->MaintainLuminanceButton = vtkKWCheckButton::New(); 

  this->OrientationAxesFrame = vtkKWFrameLabeled::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 = vtkKWFrameLabeled::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->StateOn();
  this->SelectionWindowButton->StateOff();
  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->StateOff();
  this->SelectionWindowButton->StateOn();
  if ( registry )
    {
    this->GetApplication()->SetRegistryValue(2, "RunTime","SourcesBrowser",
                                         "SelectionWindow");
    }
}

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

  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->GetState());
    pvapp->SetRegistryValue(2, "RunTime", "UseStrips", "%d",
                             this->TriangleStripsCheck->GetState());
    pvapp->SetRegistryValue(2, "RunTime", "UseImmediateMode", "%d",
                             this->ImmediateModeCheck->GetState());
    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;
      }
    }
}


//----------------------------------------------------------------------------
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->SetImageOption(image_properties, 
                                         image_properties_width, 
                                         image_properties_height, 
                                         image_properties_pixel_size,
                                         image_properties_buffer_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->SetExpandFrameToFrame1();
  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->ShowHideFrameOff();
  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->SetIndicator(0);
  this->SelectionWindowButton->SetImageOption(
    "PVSelectionWindowButton");
  this->SelectionWindowButton->SetImageOption(
    "PVSelectionWindowButton", "-selectimage");

  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->SetIndicator(0);
  this->NavigationWindowButton->SetImageOption(
    "PVNavigationWindowButton");
  this->NavigationWindowButton->SetImageOption(
    "PVNavigationWindowButton", "-selectimage");

  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->GetIndex(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->GetState(this->MenuLabelSwitchBackAndForthToViewProperties);
      viewmenu->SetState(this->MenuLabelSwitchBackAndForthToViewProperties,
                         vtkKWMenu::StateNormal);
      viewmenu->Invoke(
        viewmenu->GetIndex(this->MenuLabelSwitchBackAndForthToViewProperties));
      viewmenu->SetState(this->MenuLabelSwitchBackAndForthToViewProperties,
                         state);
      }
    }
}

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

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

//----------------------------------------------------------------------------
void vtkPVRenderView::SetDisplay3DWidgets(int s)
{
  this->Display3DWidgets->SetState(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(vtkKWScale *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->ShowHideFrameOn();
  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->SetState(
      pvwindow->GetApplication()->GetIntRegistryValue(
        2, "RunTime", "UseParallelProjection"));
    this->ParallelProjectionCallback();
    }
  else
    {
    this->ParallelProjectionCheck->SetState(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->SetState(
      pvwindow->GetApplication()->GetIntRegistryValue(
        2, "RunTime", "UseStrips"));
    }
  else
    {
    this->TriangleStripsCheck->SetState(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->SetState(
      pvwindow->GetApplication()->GetIntRegistryValue(
        2, "RunTime", "UseImmediateMode"));
    }
  else
    {
    this->ImmediateModeCheck->SetState(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->ShowHideFrameOn();
  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());




  // Light Parameter frame
  // 
  // Setup the frame
  this->LightParameterFrame->SetParent(this->GeneralPropertiesFrame->GetFrame());
  this->LightParameterFrame->ShowHideFrameOn();
  this->LightParameterFrame->Create(this->GetApplication());
  this->LightParameterFrame->SetLabelText("Light Kit Parameter");
  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.");
 

  // 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 on 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;
  for ( cc = 0; cc < 4; cc ++ )
    {
    subtype = vtkLightKit::GetSubType(vtkLightKit::TKeyLight, cc);
    this->KeyLightScale[cc]->SetParent(this->LightParameterFrame->GetFrame());
    this->KeyLightScale[cc]->PopupScaleOn();
    this->KeyLightScale[cc]->Create(this->GetApplication());
    this->KeyLightScale[cc]->DisplayEntry();
    this->KeyLightScale[cc]->DisplayEntryAndLabelOnTopOff();
    this->KeyLightScale[cc]->ExpandEntryOn();
    this->KeyLightScale[cc]->SetEntryWidth(4);
    this->KeyLightScale[cc]->DisplayLabel ( 
      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 );
    InitializeScale(this->KeyLightScale[cc], 
      this->RenderModuleProxy->GetProperty(p.c_str()));

    subtype = vtkLightKit::GetSubType(vtkLightKit::TFillLight, cc);
    this->FillLightScale[cc]->SetParent(this->LightParameterFrame->GetFrame());
    this->FillLightScale[cc]->PopupScaleOn();
    this->FillLightScale[cc]->Create(this->GetApplication());
    this->FillLightScale[cc]->DisplayEntry();
    this->FillLightScale[cc]->DisplayEntryAndLabelOnTopOff();
    this->FillLightScale[cc]->ExpandEntryOn();
    this->FillLightScale[cc]->SetEntryWidth(4);
    this->FillLightScale[cc]->DisplayLabel ( 
      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 );
    InitializeScale(this->FillLightScale[cc], 
      this->RenderModuleProxy->GetProperty(p.c_str()));

    subtype = vtkLightKit::GetSubType(vtkLightKit::TBackLight, cc);
    this->BackLightScale[cc]->SetParent(this->LightParameterFrame->GetFrame());
    this->BackLightScale[cc]->PopupScaleOn();
    this->BackLightScale[cc]->Create(this->GetApplication());
    this->BackLightScale[cc]->DisplayEntry();
    this->BackLightScale[cc]->DisplayEntryAndLabelOnTopOff();
    this->BackLightScale[cc]->ExpandEntryOn();
    this->BackLightScale[cc]->SetEntryWidth(4);
    this->BackLightScale[cc]->DisplayLabel (
      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 );
    InitializeScale(this->BackLightScale[cc], 
      this->RenderModuleProxy->GetProperty(p.c_str()));

    if( cc < 2 )
      {
      subtype = vtkLightKit::GetSubType(vtkLightKit::THeadLight, cc);
      this->HeadLightScale[cc]->SetParent(this->LightParameterFrame->GetFrame());
      this->HeadLightScale[cc]->PopupScaleOn();
      this->HeadLightScale[cc]->Create(this->GetApplication());
      this->HeadLightScale[cc]->DisplayEntry();
      this->HeadLightScale[cc]->DisplayEntryAndLabelOnTopOff();
      this->HeadLightScale[cc]->ExpandEntryOn();
      this->HeadLightScale[cc]->SetEntryWidth(4);
      this->HeadLightScale[cc]->DisplayLabel (
        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 );
      InitializeScale(this->HeadLightScale[cc], 
        this->RenderModuleProxy->GetProperty(p.c_str()));
      }
    }

  // 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.");
 
  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->ShowHideFrameOn();
  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->SetState(
      pvwindow->GetApplication()->GetIntRegistryValue(
        2, "RunTime", "OrientationAxesVisibility"));
    }
  else
    {
    this->OrientationAxesCheck->SetState(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->SetState(
      pvwindow->GetApplication()->GetIntRegistryValue(
        2, "RunTime", "OrientationAxesInteractivity"));
    }
  else
    {
    this->OrientationAxesInteractiveCheck->SetState(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->ShowHideFrameOn();
  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->ShowHideFrameOn();
  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->ShowHideFrameOn();
  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->GetState())
    {
    vtkTimerLog::MarkEvent("--- Enable triangle strips.");
    }
  else
    {
    vtkTimerLog::MarkEvent("--- Disable triangle strips.");
    }

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

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

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

  if (this->TriangleStripsCheck->GetState() != state)
    {
    this->TriangleStripsCheck->SetState(state);
    }
  
  if ( ! this->ImmediateModeCheck->GetState() && ! 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->GetState())
    {
    this->ParallelProjectionCheck->SetState(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->GetState())
    {
    this->ParallelProjectionCheck->SetState(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->GetState())
    {
    vtkTimerLog::MarkEvent("--- Enable parallel projection.");
    this->ParallelProjectionOn();
    }
  else
    {
    vtkTimerLog::MarkEvent("--- Disable parallel projection.");
    this->ParallelProjectionOff();
    }
}

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

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

  if (this->ImmediateModeCheck->GetState() != state)
    {
    this->ImmediateModeCheck->SetState(state);
    }
  
  if ( ! state && ! this->TriangleStripsCheck->GetState())
    { // 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::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();

  // 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->GetState();
  this->SetMaintainLuminance(val);
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetMaintainLuminance(int s)
{
  // Set the GUI
  this->MaintainLuminanceButton->SetState(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);
}

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

//----------------------------------------------------------------------------
void vtkPVRenderView::SetUseLight(int s)
{
  // Set the GUI
  this->UseLightButton->SetState(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);
}

//----------------------------------------------------------------------------
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->GetState() << endl;
  
  *file << "$kw(" << this->GetTclName() << ") SetUseImmediateMode "
        << this->ImmediateModeCheck->GetState() << 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->GetState() << endl;
  *file << "$kw(" << this->GetTclName() << ") SetOrientationAxesInteractivity "
        << this->OrientationAxesInteractiveCheck->GetState() << 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->GetState() )
    {
    *file << "$kw(" << this->GetTclName() << ") SetUseLight "
      << this->UseLightButton->GetState() << endl;
    *file << "$kw(" << this->GetTclName() << ") SetMaintainLuminance "
      << this->MaintainLuminanceButton->GetState() << 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();
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SetOrientationAxesVisibility(int val)
{
  if (this->OrientationAxesCheck->GetState() != val)
    {
    this->GetTraceHelper()->AddEntry("$kw(%s) SetOrientationAxesVisibility %d",
                        this->GetTclName(), val);
    this->OrientationAxesCheck->SetState(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->GetState();
  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->GetState() != val)
    {
    this->GetTraceHelper()->AddEntry("$kw(%s) SetOrientationAxesInteractivity %d",
                        this->GetTclName(), val);
    this->OrientationAxesInteractiveCheck->SetState(val);
    }
  
  this->OrientationAxes->SetInteractive(val);
}

//----------------------------------------------------------------------------
void vtkPVRenderView::OrientationAxesInteractiveCallback()
{
  int val = this->OrientationAxesInteractiveCheck->GetState();
  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(vtkKWScale *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);
}

