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

  Program:   ParaView
  Module:    vtkPVRenderView.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2000-2001 Kitware Inc. 469 Clifton Corporate Parkway,
Clifton Park, NY, 12065, USA.
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * Neither the name of Kitware nor the names of any contributors may be used
   to endorse or promote products derived from this software without specific 
   prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

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

#include "vtkInstantiator.h"
#include "vtkCamera.h"
#include "vtkCollectionIterator.h"
#include "vtkCallbackCommand.h"
#include "vtkCommand.h"
#include "vtkKWApplicationSettingsInterface.h"
#include "vtkKWChangeColorButton.h"
#include "vtkKWCheckButton.h"
#include "vtkKWFrame.h"
#include "vtkKWLabel.h"
#include "vtkKWLabeledFrame.h"
#include "vtkKWMenu.h"
#include "vtkKWNotebook.h"
#include "vtkKWPushButton.h"
#include "vtkKWRadioButton.h"
#include "vtkKWScale.h"
#include "vtkKWSplitFrame.h"
#include "vtkKWWindowCollection.h"
#include "vtkMultiProcessController.h"
#include "vtkObjectFactory.h"
#include "vtkPVApplication.h"
#include "vtkPVApplicationSettingsInterface.h"
#include "vtkPVCameraIcon.h"
#include "vtkPVConfig.h"
#include "vtkPVData.h"
#include "vtkPVDataInformation.h"
#include "vtkPVGenericRenderWindowInteractor.h"
#include "vtkPVPart.h"
#include "vtkPVPartDisplay.h"
#include "vtkPVInteractorStyleControl.h"
#include "vtkPVNavigationWindow.h"
#include "vtkPVProcessModule.h"
#include "vtkPVRenderView.h"
#include "vtkPVSourceCollection.h"
#include "vtkPVSourceList.h"
#include "vtkPVWindow.h"
#include "vtkPVSource.h"
#include "vtkPVRenderModuleUI.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkRenderer.h"
#include "vtkString.h"
#include "vtkTimerLog.h"
#include "vtkToolkits.h"

#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==";

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

int vtkPVRenderViewCommand(ClientData cd, Tcl_Interp *interp,
                             int argc, char *argv[]);

//===========================================================================
//***************************************************************************
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;
};

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

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

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

  this->EventuallyRenderFlag = 0;
  this->RenderPending = NULL;

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

  this->StandardViewsFrame = vtkKWLabeledFrame::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 = vtkKWLabeledFrame::New();

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

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

  this->NavigationFrame = vtkKWLabeledFrame::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 = vtkKWLabeledFrame::New();
  this->Display3DWidgets = vtkKWCheckButton::New();

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

  this->Observer = vtkPVRenderViewObserver::New();
  this->Observer->PVRenderView = this;

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

//----------------------------------------------------------------------------
void vtkPVRenderView::ShowNavigationWindowCallback(int registery)
{
  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->SetLabel("Navigation Window");
  this->ShowSelectionWindow = 0;
  this->ShowNavigationWindow = 1;

  this->NavigationWindowButton->StateOn();
  this->SelectionWindowButton->StateOff();
  if ( registery )
    {
    this->Application->SetRegisteryValue(2, "RunTime","SourcesBrowser",
                                         "NavigationWindow");
    }
}

//----------------------------------------------------------------------------
void vtkPVRenderView::ShowSelectionWindowCallback(int registery)
{
  if ( !this->Application )
    {
    return;
    }
  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->SetLabel("Selection Window");
  this->ShowNavigationWindow = 0;
  this->ShowSelectionWindow = 1;

  this->NavigationWindowButton->StateOff();
  this->SelectionWindowButton->StateOn();
  if ( registery )
    {
    this->Application->SetRegisteryValue(2, "RunTime","SourcesBrowser",
                                         "SelectionWindow");
    }
}

//----------------------------------------------------------------------------
vtkPVRenderView::~vtkPVRenderView()
{
  vtkPVApplication *pvApp = 0;
  if ( this->Application )
    {
    pvApp = this->GetPVApplication();
    }

  this->InterfaceSettingsFrame->Delete();
  this->Display3DWidgets->Delete();
  this->Display3DWidgets = NULL;

  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;

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

  if (this->Renderer)
    {
    this->Renderer->UnRegister(this);
    this->Renderer = NULL;
    }
  
  if (this->RenderWindow)
    {
    this->RenderWindow->UnRegister(this);
    this->RenderWindow = NULL;
    }
  
  // undo the binding we set up
  if ( this->Application )
    {
    this->Script("bind %s <Motion> {}", this->VTKWidget->GetWidgetName());
    }
  if (this->RenderPending && this->Application )
    {
    this->Script("after cancel %s", this->RenderPending);
    }
  this->SetRenderPending(NULL);

  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->CameraIconsFrame->Delete();
  this->CameraIconsFrame = 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;
      }
    }
  this->Observer->Delete();

  this->PropertiesButton->Delete();
  this->PropertiesButton = NULL;
  this->SetMenuLabelSwitchBackAndForthToViewProperties(NULL);
}

//----------------------------------------------------------------------------
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)
    {
    //("Abort 2");
    me->GetRenderWindow()->SetAbortRender(2);
    }
}

//----------------------------------------------------------------------------
void vtkPVRenderView::CreateRenderObjects(vtkPVApplication *pvApp)
{
  // Get rid of renderer created by the superclass
  this->Renderer->Delete();
  this->Renderer = pvApp->GetRenderModule()->GetRenderer();
  this->Renderer->Register(this);

  // Create the call back that looks for events to abort rendering.
  pvApp->GetRenderModule()->RemoveObservers(vtkCommand::AbortCheckEvent);
  vtkCallbackCommand* abc = vtkCallbackCommand::New();
  abc->SetCallback(PVRenderViewAbortCheck);
  abc->SetClientData(this);
  pvApp->GetRenderModule()->AddObserver(vtkCommand::AbortCheckEvent, abc);
  abc->Delete();

  // Get rid of render window created by the superclass
  this->RenderWindow->Delete();
  this->RenderWindow = pvApp->GetRenderModule()->GetRenderWindow();
  this->RenderWindow->Register(this);

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


//----------------------------------------------------------------------------
// Here we are going to change only the satellite procs.
void vtkPVRenderView::PrepareForDelete()
{
  vtkPVApplication* pvapp = this->GetPVApplication();
  if (pvapp)
    {
    pvapp->SetRegisteryValue(2, "RunTime", "UseParallelProjection", "%d",
                             this->ParallelProjectionCheck->GetState());
    pvapp->SetRegisteryValue(2, "RunTime", "UseStrips", "%d",
                             this->TriangleStripsCheck->GetState());
    pvapp->SetRegisteryValue(2, "RunTime", "UseImmediateMode", "%d",
                             this->ImmediateModeCheck->GetState());

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

    if (pvapp->GetWindows()->GetNumberOfItems() <= 1 &&
        pvapp->HasRegisteryValue(
          2, "Geometry", VTK_KW_SAVE_WINDOW_GEOMETRY_REG_KEY) &&
        pvapp->GetIntRegisteryValue(
          2, "Geometry", VTK_KW_SAVE_WINDOW_GEOMETRY_REG_KEY))
      {
      pvapp->SetRegisteryValue(
        2, "Geometry", VTK_PV_NAV_FRAME_SIZE_REG_KEY, "%d", 
        this->SplitFrame->GetFrame1Size());
      }
    }

  // We must call prepare for delete on the RenderModule !!!!!!!


  // 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->PrepareForDelete();
  vtkKWView::Close();
}  


//----------------------------------------------------------------------------
vtkRenderer *vtkPVRenderView::GetRenderer()
{
  return this->Renderer;
}

//----------------------------------------------------------------------------
vtkRenderWindow *vtkPVRenderView::GetRenderWindow()
{
  return this->RenderWindow;
}

//----------------------------------------------------------------------------
void vtkPVRenderView::Create(vtkKWApplication *app, const char *args)
{
  char *local;
  const char *wname;
  
  local = new char [strlen(args)+100];

  if (this->Application)
    {
    vtkErrorMacro("RenderView already created");
    return;
    }
  
  // Must set the application

  if (this->Application)
    {
    vtkErrorMacro("RenderView already created");
    return;
    }
  this->SetApplication(app);



  // Create the frames

  wname = this->GetWidgetName();
  this->Script("frame %s -bd 0 %s",wname,args);

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

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

  this->Label->Create(app,"label","-fg #fff -text {3D View} -bd 0");

  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, "-bd 0 -bg #008 -padx 0 -pady 0 -highlightthickness 0 -relief flat");
  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,"frame","-bd 0");
  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, "toplevel", "");
    this->Script("wm title %s %s", 
                 this->TopLevelRenderWindow->GetWidgetName(),
                 this->Application->GetApplicationName());
    }

  // Add the -rw argument

  sprintf(local,"%s -rw Addr=%p",args,this->RenderWindow);
  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->SetSeparatorSize(5);
  this->SplitFrame->SetFrame1MinimumSize(80);

  if (this->Application->HasRegisteryValue(
    2, "Geometry", VTK_KW_SAVE_WINDOW_GEOMETRY_REG_KEY) &&
      this->Application->GetIntRegisteryValue(
        2, "Geometry", VTK_KW_SAVE_WINDOW_GEOMETRY_REG_KEY) &&
      this->Application->HasRegisteryValue(
        2, "Geometry", VTK_PV_NAV_FRAME_SIZE_REG_KEY))
    {
    this->SplitFrame->SetFrame1Size(this->Application->GetIntRegisteryValue(
      2, "Geometry", VTK_PV_NAV_FRAME_SIZE_REG_KEY));
    }
  else
    {
    this->SplitFrame->SetFrame1Size(80);
    }

  this->SplitFrame->Create(this->Application);

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

  // Configure the navigation frame

  this->NavigationFrame->SetParent(this->SplitFrame->GetFrame1());
  this->NavigationFrame->ShowHideFrameOff();
  this->NavigationFrame->Create(this->Application, 0);
  this->NavigationFrame->SetLabel("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(this->Application, 0); 

  // Configure the selection window

  this->SelectionWindow->SetParent(this->NavigationFrame->GetFrame());
  this->SelectionWindow->SetWidth(341);
  this->SelectionWindow->SetHeight(545);
  this->SelectionWindow->Create(this->Application, 0); 

  this->SelectionWindowButton->SetParent(
    this->NavigationFrame->GetLabelFrame());
  this->SelectionWindowButton->Create(
    this->Application, 
    "-indicatoron 0 -highlightthickness 0 -image PVSelectionWindowButton "
    "-selectimage PVSelectionWindowButton");
  this->SelectionWindowButton->SetBalloonHelpString(
    "Switch to selection window mode.");
  this->SelectionWindowButton->SetCommand(
    this, "ShowSelectionWindowCallback 1");
  
  this->NavigationWindowButton->SetParent(
    this->NavigationFrame->GetLabelFrame());
  this->NavigationWindowButton->Create(
    this->Application, 
    "-indicatoron 0 -highlightthickness 0 -image PVNavigationWindowButton "
    "-selectimage PVNavigationWindowButton");
  this->NavigationWindowButton->SetBalloonHelpString(
    "Switch to navigation window mode.");
  this->NavigationWindowButton->SetCommand(
    this, "ShowNavigationWindowCallback 1");

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

  if (this->Application->HasRegisteryValue(2, "RunTime", "SourcesBrowser"))
    {
    if (this->Application->BooleanRegisteryCheck(2, "RunTime", 
                                                 "SourcesBrowser",
                                                 "SelectionWindow"))
      {
      this->ShowSelectionWindowCallback(0);
      }
    else
      {
      this->ShowNavigationWindowCallback(0);
      }
    }
  else
    {
    this->ShowSelectionWindowCallback(0);
    }

  this->EventuallyRender();
  delete [] local;
}

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

  vtkKWMenu *viewmenu = win->GetMenuView();
  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))
      {
      viewmenu->Invoke(
        viewmenu->GetIndex(this->MenuLabelSwitchBackAndForthToViewProperties));
      }
    }
}

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

//----------------------------------------------------------------------------
void vtkPVRenderView::Display3DWidgetsCallback()
{
  int val = this->Display3DWidgets->GetState();
  this->SetDisplay3DWidgets(val);
  this->Application->SetRegisteryValue(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->GetPVWindow())
    {
    vtkPVApplicationSettingsInterface *asi = 
      vtkPVApplicationSettingsInterface::SafeDownCast(
        this->GetPVWindow()->GetApplicationSettingsInterface());
    if (asi)
      {
      asi->Update();
      }
    }

  if (this->NavigationWindow && this->NavigationWindow->IsCreated())
    {
    this->NavigationWindow->SetAlwaysShowName(s);
    }
  if (this->SelectionWindow && this->SelectionWindow->IsCreated())
    {
    this->SelectionWindow->SetAlwaysShowName(s);
    }
}

//----------------------------------------------------------------------------
void vtkPVRenderView::CreateViewProperties()
{
  this->vtkKWView::CreateViewProperties();

  this->BackgroundColor->SetBalloonHelpString("Change the background color of the 3D View window");

  vtkPVWindow* pvwindow = this->GetPVWindow();
  vtkPVApplication* pvapp = this->GetPVApplication();

  // Render parameters

  this->RenderParametersFrame->SetParent(this->GeneralProperties->GetFrame());
  this->RenderParametersFrame->ShowHideFrameOn();
  this->RenderParametersFrame->Create(this->Application,0);
  this->RenderParametersFrame->SetLabel("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->Application, "");
  this->ParallelProjectionCheck->SetText("Use parallel projection");
  if (pvapp && pvwindow && 
      pvapp->GetRegisteryValue(2, "RunTime", "UseParallelProjection", 0))
    {
    this->ParallelProjectionCheck->SetState(
      pvwindow->GetIntRegisteryValue(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->Application, "");
  this->TriangleStripsCheck->SetText("Use triangle strips");
  if (pvapp && pvwindow && 
      pvapp->GetRegisteryValue(2, "RunTime", "UseStrips", 0))
    {
    this->TriangleStripsCheck->SetState(
      pvwindow->GetIntRegisteryValue(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->Application, 
                                   "-text \"Use immediate mode rendering\"");
  this->ImmediateModeCheck->SetCommand(this, "ImmediateModeCallback");
  if (pvapp && pvwindow && 
      pvapp->GetRegisteryValue(2, "RunTime", "UseImmediateMode", 0))
    {
    this->ImmediateModeCheck->SetState(
      pvwindow->GetIntRegisteryValue(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.
  char* rmuiClassName;
  rmuiClassName = new char[strlen(pvapp->GetRenderModuleName()) + 20];
  sprintf(rmuiClassName, "vtkPV%sUI", pvapp->GetRenderModuleName());
  vtkObject* rmui = vtkInstantiator::CreateInstance(rmuiClassName);
  this->RenderModuleUI = vtkPVRenderModuleUI::SafeDownCast(rmui);
  this->RenderModuleUI->SetRenderModule(pvapp->GetRenderModule());
  this->RenderModuleUI->SetParent(this->GeneralProperties->GetFrame());
  this->RenderModuleUI->Create(this->Application,0);
  this->Script("pack %s -padx 2 -pady 2 -fill x -expand yes -anchor w",
               this->RenderModuleUI->GetWidgetName());
  delete [] rmuiClassName;
  rmuiClassName = NULL;

  // Interface settings

  this->InterfaceSettingsFrame->SetParent(this->GeneralProperties->GetFrame());
  this->InterfaceSettingsFrame->ShowHideFrameOn();
  this->InterfaceSettingsFrame->Create(this->Application,0);
  this->InterfaceSettingsFrame->SetLabel("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->Application, 0);
  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->Application->GetRegisteryValue(2,"RunTime","Display3DWidgets",0)||
    this->GetPVWindow()->GetIntRegisteryValue(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());

  // Camera settings

  this->Notebook->AddPage("Camera", 
                          "Camera and viewing navigation properties page");
  vtkKWWidget* page = this->Notebook->GetFrame("Camera");

  vtkKWFrame* frame = vtkKWFrame::New();
  frame->SetParent(page);
  frame->ScrollableOn();
  frame->Create(this->Application,0);
  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->Application, 0);
  this->StandardViewsFrame->SetLabel("Standard Views");

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

  this->XMaxViewButton->SetParent(this->StandardViewsFrame->GetFrame());
  this->XMaxViewButton->SetLabel("+X");
  this->XMaxViewButton->Create(this->Application, "");
  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->SetLabel("-X");
  this->XMinViewButton->Create(this->Application, "");
  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->SetLabel("+Y");
  this->YMaxViewButton->Create(this->Application, "");
  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->SetLabel("-Y");
  this->YMinViewButton->Create(this->Application, "");
  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->SetLabel("+Z");
  this->ZMaxViewButton->Create(this->Application, "");
  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->SetLabel("-Z");
  this->ZMinViewButton->Create(this->Application, "");
  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

  int cc;
  this->CameraIconsFrame->SetParent(frame->GetFrame());
  this->CameraIconsFrame->ShowHideFrameOn();
  this->CameraIconsFrame->Create(this->Application, 0);
  this->CameraIconsFrame->SetLabel("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->Application, "");

    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, 0);
  this->ManipulatorControl2D->SetLabel("2D Movements");

  this->ManipulatorControl3D->SetParent(frame->GetFrame());
  this->ManipulatorControl3D->Create(pvapp, 0);
  this->ManipulatorControl3D->SetLabel("3D Movements");

  // Camera: pack

  this->Script("pack %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());

  frame->Delete();

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

//----------------------------------------------------------------------------
void vtkPVRenderView::StandardViewCallback(float x, float y, float z)
{
  vtkCamera *cam = this->Renderer->GetActiveCamera();
  cam->SetFocalPoint(0.0, 0.0, 0.0);
  cam->SetPosition(x, y, z);
  if (x == 0.0)
    {
    cam->SetViewUp(1.0, 0.0, 0.0);
    }
  else
    {
    cam->SetViewUp(0.0, 1.0, 0.0);
    }

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

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

//----------------------------------------------------------------------------
void vtkPVRenderView::SetBackgroundColor(float r, float g, float b)
{
  vtkPVApplication *pvApp = this->GetPVApplication();
  
  // Set the color of the interface button.
  this->BackgroundColor->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->AddTraceEntry("$kw(%s) SetBackgroundColor %f %f %f",
                      this->GetTclName(), r, g, b);
  pvApp->GetRenderModule()->SetBackgroundColor(r, g, b);
  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()
{
  vtkPVRenderModule* rm = this->GetPVApplication()->GetRenderModule();
  if (rm)
    {
    rm->InteractiveRender();
    }
}


//----------------------------------------------------------------------------
void vtkPVRenderView::ResetCamera()
{
  float bds[6];


  this->GetPVApplication()->GetRenderModule()->ComputeVisiblePropBounds(bds);
  if (bds[0] <= bds[1] && bds[2] <= bds[3] && bds[4] <= bds[5])
    {
    this->GetRenderer()->ResetCamera(bds);
    }
}

//----------------------------------------------------------------------------
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->AddTraceEntry(
    "$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::AddBindings()
{
  this->Script("bind %s <Motion> {%s MotionCallback %%x %%y}",
               this->VTKWidget->GetWidgetName(), this->GetTclName());
}
    
//----------------------------------------------------------------------------
vtkPVApplication* vtkPVRenderView::GetPVApplication()
{
  if (this->Application == NULL)
    {
    return NULL;
    }
  
  if (this->Application->IsA("vtkPVApplication"))
    {  
    return (vtkPVApplication*)(this->Application);
    }
  else
    {
    vtkErrorMacro("Bad typecast");
    return NULL;
    } 
}



//----------------------------------------------------------------------------
void vtkPVRenderView::Render()
{
  int abort;

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

  vtkPVRenderModule* rm = this->GetPVApplication()->GetRenderModule();
  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->RenderPending && this->Application )
    {
    saveRender = 1;
    this->Script("after cancel %s", this->RenderPending);
    this->SetRenderPending(NULL);
    // This flag is not necessary.  We should just use render pending ivar.
    this->EventuallyRenderFlag = 0;
    }

  this->Script("update");

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




//----------------------------------------------------------------------------
void vtkPVRenderView::EventuallyRender()
{
  if (this->EventuallyRenderFlag)
    {
    return;
    }
  this->EventuallyRenderFlag = 1;
  //cout << "EventuallyRender()" << endl;

  // Keep track of whether there is a render pending so that if a render is
  // pending when this object is deleted, we can cancel the "after" command.
  // We don't want to have this object register itself because this can
  // cause leaks if we exit before EventuallyRenderCallBack is called.
  this->Script("update idletasks");
  this->Script("after idle {%s EventuallyRenderCallBack}",this->GetTclName());
  this->SetRenderPending(this->Application->GetMainInterp()->result);

}
                      
//----------------------------------------------------------------------------
void vtkPVRenderView::EventuallyRenderCallBack()
{
  int abort;

  vtkPVApplication *pvApp = this->GetPVApplication();

  // sanity check
  if (this->EventuallyRenderFlag == 0 || !this->RenderPending)
    {
    vtkErrorMacro("Inconsistent EventuallyRenderFlag");
    return;
    }
  // We could get rid of the flag and use the pending ivar.
  this->EventuallyRenderFlag = 0;
  this->SetRenderPending(NULL);

  // I do not know if these are necessary here.
  abort = this->ShouldIAbort();
  if (abort)
    {
    if (abort == 1)
      {
      this->EventuallyRender();
      }
    return;
    }

  pvApp->SetGlobalLODFlag(0);
  pvApp->GetRenderModule()->StillRender();
}

//----------------------------------------------------------------------------
void vtkPVRenderView::TriangleStripsCallback()
{
  vtkPVWindow *pvWin;
  vtkPVSourceCollection *sources;
  vtkPVSource *pvs;
  vtkPVApplication *pvApp;
  int numParts, partIdx;

  if ( ! this->ImmediateModeCheck->GetState() && 
       ! this->TriangleStripsCheck->GetState())
    { // Make sure immediate mode is on when strips are off.
    this->ImmediateModeCheck->SetState(1);
    this->ImmediateModeCallback();
    }


  pvApp = this->GetPVApplication();
  pvWin = this->GetPVWindow();
  if (pvWin == NULL)
    {
    vtkErrorMacro("Missing window.");
    return;
    }
  sources = pvWin->GetSourceList("Sources");
  
  sources->InitTraversal();
  while ( (pvs = sources->GetNextPVSource()) )
    {
    numParts = pvs->GetNumberOfParts();
    for (partIdx = 0; partIdx < numParts; ++partIdx)
      {
      pvApp->BroadcastScript("%s SetUseStrips %d",
                             pvs->GetPart(partIdx)->GetGeometryTclName(),
                             this->TriangleStripsCheck->GetState());
      pvs->GetPart(partIdx)->GetPartDisplay()->InvalidateGeometry();
      }
    }

  if (this->TriangleStripsCheck->GetState())
    {
    vtkTimerLog::MarkEvent("--- Enable triangle strips.");
    }
  else
    {
    vtkTimerLog::MarkEvent("--- Disable triangle strips.");
    }

  this->EventuallyRender();
}


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

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

//----------------------------------------------------------------------------
void vtkPVRenderView::ImmediateModeCallback()
{
  vtkPVWindow *pvWin;
  vtkPVSourceCollection *sources;
  vtkPVSource *pvs;
  vtkPVApplication *pvApp;
  int partIdx, numParts;

  if ( ! this->ImmediateModeCheck->GetState() && 
       ! this->TriangleStripsCheck->GetState())
    { // Make sure triangle strips are on.
    // When immediate mode is off, triangle strips must be on.
    this->TriangleStripsCheck->SetState(1);
    this->TriangleStripsCallback();
    }

  pvApp = this->GetPVApplication();
  pvWin = this->GetPVWindow();
  if (pvWin == NULL)
    {
    vtkErrorMacro("Missing window.");
    return;
    }
  sources = pvWin->GetSourceList("Sources");
  
  sources->InitTraversal();
  while ( (pvs = sources->GetNextPVSource()) )
    {
    numParts = pvs->GetNumberOfParts();
    for (partIdx = 0; partIdx < numParts; ++partIdx)
      {
      pvs->GetPart(partIdx)->GetPartDisplay()->SetUseImmediateMode(
                             this->ImmediateModeCheck->GetState());
      }
    }

  if (this->ImmediateModeCheck->GetState())
    {
    vtkTimerLog::MarkEvent("--- Disable display lists.");
    }
  else
    {
    vtkTimerLog::MarkEvent("--- Enable display lists.");
    }
  this->EventuallyRender();
}

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

  return pvWin;
}

//----------------------------------------------------------------------------
void vtkPVRenderView::SaveInBatchScript(ofstream* file)
{
  vtkCamera *camera;
  float position[3];
  float focalPoint[3];
  float viewUp[3];
  float viewAngle;
  float clippingRange[2];
  float *color;
  int *size;

  size = this->RenderWindow->GetSize();
  *file << "vtkRenderer " << "Ren1" << "\n\t";
  color = this->Renderer->GetBackground();
  *file << "Ren1" << " SetBackground "
        << color[0] << " " << color[1] << " " << color[2] << endl;
  *file << "vtkRenderWindow " << "RenWin1" << "\n\t"
        << "RenWin1" << " AddRenderer "
        << "Ren1" << "\n\t";
  *file << "RenWin1" << " SetSize " << size[0] << " " << size[1] << endl;

  camera = this->GetRenderer()->GetActiveCamera();
  camera->GetPosition(position);
  camera->GetFocalPoint(focalPoint);
  camera->GetViewUp(viewUp);
  viewAngle = camera->GetViewAngle();
  camera->GetClippingRange(clippingRange);
  
  *file << "# camera parameters\n"
        << "set camera [" << "Ren1" << " GetActiveCamera]\n\t"
        << "$camera SetPosition " << position[0] << " " << position[1] << " "
        << position[2] << "\n\t"
        << "$camera SetFocalPoint " << focalPoint[0] << " " << focalPoint[1]
        << " " << focalPoint[2] << "\n\t"
        << "$camera SetViewUp " << viewUp[0] << " " << viewUp[1] << " "
        << viewUp[2] << "\n\t"
        << "$camera SetViewAngle " << viewAngle << "\n\t"
        << "$camera SetClippingRange " << clippingRange[0] << " "
        << clippingRange[1] << "\n";
}


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

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

  camera = this->GetRenderer()->GetActiveCamera();
  camera->GetPosition(position);
  camera->GetFocalPoint(focalPoint);
  camera->GetViewUp(viewUp);
  
  *file << "$kw(" << this->GetTclName() << ") SetCameraState " 
        << position[0] << " " << position[1] << " " << position[2] << " "
        << focalPoint[0] << " " << focalPoint[1] << " " << focalPoint[2] << " "
        << viewUp[0] << " " << viewUp[1] << " " << viewUp[2] << 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) 
{
  this->EventuallyRender();
  this->Script("update");
  this->Superclass::SaveAsImage(filename);
}


//----------------------------------------------------------------------------
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 = "arror";
        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::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 << "ManipulatorControl2D: " 
     << this->ManipulatorControl2D << endl;
  os << indent << "ManipulatorControl3D: " 
     << this->ManipulatorControl3D << endl;
}

