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

  Program:   ParaView
  Module:    vtkPVColorMap.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 "vtkPVColorMap.h"

#include "vtkCommand.h"
#include "vtkKWChangeColorButton.h"
#include "vtkKWCheckButton.h"
#include "vtkKWEntry.h"
#include "vtkKWFrame.h"
#include "vtkKWLabel.h"
#include "vtkKWLabeledEntry.h"
#include "vtkKWLabeledFrame.h"
#include "vtkKWMenuButton.h"
#include "vtkKWOptionMenu.h"
#include "vtkKWPushButton.h"
#include "vtkKWScale.h"
#include "vtkKWTextProperty.h"
#include "vtkKWTkUtilities.h"
#include "vtkKWWidget.h"
#include "vtkLookupTable.h"
#include "vtkObjectFactory.h"
#include "vtkPVApplication.h"
#include "vtkPVArrayInformation.h"
#include "vtkPVData.h"
#include "vtkPVDataInformation.h"
#include "vtkPVDataSetAttributesInformation.h"
#include "vtkPVGenericRenderWindowInteractor.h"
#include "vtkPVRenderView.h"
#include "vtkPVSource.h"
#include "vtkPVSourceCollection.h"
#include "vtkPVWindow.h"
#include "vtkRenderer.h"
#include "vtkRendererCollection.h"
#include "vtkRenderWindow.h"
#include "vtkScalarBarActor.h"
#include "vtkScalarBarWidget.h"
#include "vtkPVProcessModule.h"
#include "vtkPVRenderModule.h"
//----------------------------------------------------------------------------
vtkStandardNewMacro(vtkPVColorMap);
vtkCxxRevisionMacro(vtkPVColorMap, "1.75");

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

/* 
 * This part was generated by ImageConvert from image:
 *    presets.png (zlib, base64)
 */
#define image_presets_width         16
#define image_presets_height        16
#define image_presets_pixel_size    4
#define image_presets_buffer_length 264

static unsigned char image_presets[] = 
  "eNrdkusNhSAMhZkHhtAlXAKHgCFkCZeAIXAIXeJcikiqQaN/L8kJr349LQGAQJG1FleB3T"
  "+JYkMIecvnNznuWJ7jqbay/jSIEULgzIvHOvjc4t+yR0//4P9VV3+SUgp932MYBoxaw6S7"
  "yTnM84zgA5ZlwbZtObblr6RMfJd5PSbeGDg3Zd4TH2Pl+f858d3ur/XB7/4+eETGt6SUrP"
  "WTP+WuvPfJn+pf63tz0Zm89G9N4qfSf/Kn/tfi3+K/vf+Z/wENH5fO";

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

  vtkScalarBarWidgetObserver()
    {
      this->PVColorMap = 0;
    }

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

  vtkPVColorMap* PVColorMap;
};

#define VTK_PV_COLOR_MAP_RED_HUE 0.0
#define VTK_PV_COLOR_MAP_RED_SATURATION 1.0
#define VTK_PV_COLOR_MAP_RED_VALUE 1.0
#define VTK_PV_COLOR_MAP_BLUE_HUE 0.6667
#define VTK_PV_COLOR_MAP_BLUE_SATURATION 1.0
#define VTK_PV_COLOR_MAP_BLUE_VALUE 1.0
#define VTK_PV_COLOR_MAP_BLACK_HUE 0.0
#define VTK_PV_COLOR_MAP_BLACK_SATURATION 0.0
#define VTK_PV_COLOR_MAP_BLACK_VALUE 0.0
#define VTK_PV_COLOR_MAP_WHITE_HUE 0.0
#define VTK_PV_COLOR_MAP_WHITE_SATURATION 0.0
#define VTK_PV_COLOR_MAP_WHITE_VALUE 1.0

//***************************************************************************
//===========================================================================
//vtkCxxSetObjectMacro(vtkPVColorMap,PVRenderView,vtkPVRenderView);
//----------------------------------------------------------------------------
// No register count because of reference loop.
void vtkPVColorMap::SetPVRenderView(vtkPVRenderView *rv)
{
  this->PVRenderView = rv;
}

//----------------------------------------------------------------------------
vtkPVColorMap::vtkPVColorMap()
{
  this->CommandFunction = vtkPVColorMapCommand;

  // Used to be in vtkPVActorComposite
  static int instanceCount = 0;

  this->UseCount = 0;

  this->ScalarBarTitle = NULL;
  this->ScalarBarLabelFormat = NULL;
  this->ArrayName = NULL;
  this->NumberOfVectorComponents = 0;
  this->ScalarBarVisibility = 0;
  this->InternalScalarBarVisibility = 0;
  this->ScalarRange[0] = 0.0;
  this->ScalarRange[1] = 1.0;
  this->Initialized = 0;

  this->StartHSV[0] = VTK_PV_COLOR_MAP_RED_HUE;
  this->StartHSV[1] = VTK_PV_COLOR_MAP_RED_SATURATION;
  this->StartHSV[2] = VTK_PV_COLOR_MAP_RED_VALUE;
  this->EndHSV[0] = VTK_PV_COLOR_MAP_BLUE_HUE;
  this->EndHSV[1] = VTK_PV_COLOR_MAP_BLUE_SATURATION;
  this->EndHSV[2] = VTK_PV_COLOR_MAP_BLUE_VALUE;

  this->NumberOfColors = 256;

  this->PVRenderView = NULL;
  this->LookupTableID.ID = 0;
  this->LookupTable = NULL;
  this->ScalarBarID.ID = 0;
  this->ScalarBar = NULL;
  this->ScalarBarObserver = NULL;

  // Create a unique id for creating tcl names.
  ++instanceCount;
  this->InstanceCount = instanceCount;    
  this->VectorMode = vtkPVColorMap::COMPONENT;
  this->VectorComponent = 0;

  // User interaface.
  this->ColorMapFrame = vtkKWLabeledFrame::New();
  this->ArrayNameLabel = vtkKWLabel::New();
  this->NumberOfColorsScale = vtkKWScale::New();  
  this->ColorEditorFrame = vtkKWWidget::New();
  this->StartColorButton = vtkKWChangeColorButton::New();
  this->Map = vtkKWLabel::New();
  this->EndColorButton = vtkKWChangeColorButton::New();
  // Stuff for setting the range of the color map.
  this->ColorRangeFrame = vtkKWWidget::New();
  this->ColorRangeResetButton = vtkKWPushButton::New();
  this->ColorRangeMinEntry = vtkKWLabeledEntry::New();
  this->ColorRangeMaxEntry = vtkKWLabeledEntry::New();

  this->VectorFrame = vtkKWLabeledFrame::New();
  this->VectorModeMenu = vtkKWOptionMenu::New() ;
  this->VectorComponentMenu = vtkKWOptionMenu::New();

  // Stuff for manipulating the scalar bar.
  this->ScalarBarFrame = vtkKWLabeledFrame::New();
  this->ScalarBarCheck = vtkKWCheckButton::New();
  this->ScalarBarTitleFrame = vtkKWWidget::New();
  this->ScalarBarTitleLabel = vtkKWLabel::New();
  this->ScalarBarTitleEntry = vtkKWEntry::New();
  this->ScalarBarVectorTitleEntry = vtkKWEntry::New();
  this->ScalarBarLabelFormatFrame = vtkKWWidget::New();
  this->ScalarBarLabelFormatLabel = vtkKWLabel::New();
  this->ScalarBarLabelFormatEntry = vtkKWEntry::New();

  this->VectorMagnitudeTitle = new char[12];
  strcpy(this->VectorMagnitudeTitle, "Magnitude");
  this->VectorComponentTitles = NULL;

  this->BackButton = vtkKWPushButton::New();

  this->MapData = NULL;
  this->MapDataSize = 0;
  this->MapHeight = 25;
  this->MapWidth = 20;

  this->PresetsMenuButton = vtkKWMenuButton::New();

  this->VisitedFlag = 0;

  this->TitleTextPropertyWidget = vtkKWTextProperty::New();
  this->LabelTextPropertyWidget = vtkKWTextProperty::New();
}

//----------------------------------------------------------------------------
vtkPVColorMap::~vtkPVColorMap()
{
  // Used to be in vtkPVActorComposite........
  vtkPVApplication *pvApp = this->GetPVApplication();

  if (this->ArrayName)
    {
    delete [] this->ArrayName;
    this->ArrayName = NULL;
    }
  
  if (this->ScalarBarTitle)
    {
    delete [] this->ScalarBarTitle;
    this->ScalarBarTitle = NULL;
    }
  if (this->ScalarBarLabelFormat)
    {
    delete [] this->ScalarBarLabelFormat;
    this->ScalarBarLabelFormat = NULL;
    }

  this->SetPVRenderView(NULL);

  if (this->LookupTableID.ID)
    {
    if ( pvApp )
      {
      vtkPVProcessModule* pm = pvApp->GetProcessModule();
      pm->DeleteStreamObject(this->LookupTableID);
      pm->SendStreamToClientAndServer();
      }
    this->LookupTableID.ID = 0;
    this->LookupTable = NULL;
    }

  if (this->ScalarBar)
    {
    if ( pvApp )
      {
      vtkPVProcessModule* pm = pvApp->GetProcessModule();
      pm->DeleteStreamObject(this->ScalarBarID);
      pm->SendStreamToClientAndServer();
      }
    this->ScalarBarID.ID = 0;
    this->ScalarBar = NULL;
    }

  if (this->ScalarBarObserver)
    {
    this->ScalarBarObserver->Delete();
    this->ScalarBarObserver = NULL;
    }
    
  this->VectorFrame->Delete();
  this->VectorFrame = NULL;
  this->VectorModeMenu->Delete();
  this->VectorModeMenu = NULL;
  this->VectorComponentMenu->Delete();
  this->VectorComponentMenu = NULL;
  this->ScalarBarVectorTitleEntry->Delete();
  this->ScalarBarVectorTitleEntry = NULL;

  // User interaface.
  this->ColorMapFrame->Delete();
  this->ColorMapFrame = NULL;
  this->ArrayNameLabel->Delete();
  this->ArrayNameLabel = NULL;
  this->NumberOfColorsScale->Delete();
  this->NumberOfColorsScale = NULL;

  this->ColorEditorFrame->Delete();
  this->ColorEditorFrame = NULL;
  this->StartColorButton->Delete();
  this->StartColorButton = NULL;
  this->Map->Delete();
  this->Map = NULL;
  this->EndColorButton->Delete();
  this->EndColorButton = NULL;
  
  // Stuff for setting the range of the color map.
  this->ColorRangeFrame->Delete();
  this->ColorRangeFrame = NULL;
  this->ColorRangeResetButton->Delete();
  this->ColorRangeResetButton = NULL;
  this->ColorRangeMinEntry->Delete();
  this->ColorRangeMinEntry = NULL;
  this->ColorRangeMaxEntry->Delete();      
  this->ColorRangeMaxEntry = NULL;     


  this->ScalarBarFrame->Delete();
  this->ScalarBarFrame = NULL;
  this->ScalarBarCheck->Delete();
  this->ScalarBarCheck = NULL;
  this->ScalarBarTitleFrame->Delete();
  this->ScalarBarTitleFrame = NULL;
  this->ScalarBarTitleLabel->Delete();
  this->ScalarBarTitleLabel = NULL;
  this->ScalarBarTitleEntry->Delete();
  this->ScalarBarTitleEntry = NULL;
  this->ScalarBarLabelFormatFrame->Delete();
  this->ScalarBarLabelFormatFrame = NULL;
  this->ScalarBarLabelFormatLabel->Delete();
  this->ScalarBarLabelFormatLabel = NULL;
  this->ScalarBarLabelFormatEntry->Delete();
  this->ScalarBarLabelFormatEntry = NULL;

  if (this->VectorMagnitudeTitle)
    {
    delete [] this->VectorMagnitudeTitle;
    this->VectorMagnitudeTitle = NULL;
    }
  // This will delete the vector component titles.
  this->SetNumberOfVectorComponents(0);

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

  if (this->MapData)
    {
    delete [] this->MapData;
    this->MapDataSize = 0;
    this->MapWidth = 0;
    this->MapHeight = 0;
    }

  if ( this->PresetsMenuButton )
    {
    this->PresetsMenuButton->Delete();
    }

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

  this->LabelTextPropertyWidget->Delete();
  this->LabelTextPropertyWidget = NULL;
}


//----------------------------------------------------------------------------
void vtkPVColorMap::Create(vtkKWApplication *app)
{
  vtkPVApplication *pvApp = vtkPVApplication::SafeDownCast(app);
  const char* wname;
  const char *grid_settings = "-padx 1 -pady 2";
  const char *label_settings = "-anchor w";
  
  if (this->Application)
    {
    vtkErrorMacro("PVColorMap already created");
    return;
    }
  // Superclass create takes a KWApplication, but we need a PVApplication.
  if (pvApp == NULL)
    {
    vtkErrorMacro("Need a PV application");
    return;
    }
  this->SetApplication(app);
  this->CreateParallelTclObjects(pvApp);
  
  // create the top level
  wname = this->GetWidgetName();
  this->Script("frame %s -borderwidth 0 -relief flat", wname);
  
  // Now for the UI.

  // Color map

  this->ColorMapFrame->SetParent(this);
  this->ColorMapFrame->ShowHideFrameOn();
  this->ColorMapFrame->Create(this->Application, 0);
  this->ColorMapFrame->SetLabel("Color Map");

  // Color map: parameter name

  this->ArrayNameLabel->SetParent(this->ColorMapFrame->GetFrame());
  this->ArrayNameLabel->Create(this->Application, "-anchor w");
  this->ArrayNameLabel->SetLabel("Parameter: ");

  // Color map: range

  this->ColorRangeFrame->SetParent(this->ColorMapFrame->GetFrame());
  this->ColorRangeFrame->Create(this->Application, "frame", "");

  this->ColorRangeResetButton->SetParent(this->ColorRangeFrame);
  this->ColorRangeResetButton->Create(this->Application, 
                                      "-text {Reset Range}");
  this->ColorRangeResetButton->SetCommand(this, "ResetScalarRange");

  this->ColorRangeMinEntry->SetParent(this->ColorRangeFrame);
  this->ColorRangeMinEntry->Create(this->Application);
  this->ColorRangeMinEntry->SetLabel("Min:");
  this->ColorRangeMinEntry->GetEntry()->SetWidth(10);
  this->Script("bind %s <KeyPress-Return> {%s ColorRangeEntryCallback}",
               this->ColorRangeMinEntry->GetEntry()->GetWidgetName(),
               this->GetTclName());
  this->Script("bind %s <FocusOut> {%s ColorRangeEntryCallback}",
               this->ColorRangeMinEntry->GetEntry()->GetWidgetName(),
               this->GetTclName()); 

  this->ColorRangeMaxEntry->SetParent(this->ColorRangeFrame);
  this->ColorRangeMaxEntry->Create(this->Application);
  this->ColorRangeMaxEntry->SetLabel("Max:");
  this->ColorRangeMaxEntry->GetEntry()->SetWidth(
    this->ColorRangeMinEntry->GetEntry()->GetWidth());
  this->Script("bind %s <KeyPress-Return> {%s ColorRangeEntryCallback}",
               this->ColorRangeMaxEntry->GetEntry()->GetWidgetName(),
               this->GetTclName());
  this->Script("bind %s <FocusOut> {%s ColorRangeEntryCallback}",
               this->ColorRangeMaxEntry->GetEntry()->GetWidgetName(),
               this->GetTclName());

  this->Script("pack %s -side left -expand f",
               this->ColorRangeResetButton->GetWidgetName());

  this->Script("pack %s %s -side left -expand t -fill x",
               this->ColorRangeMinEntry->GetWidgetName(),
               this->ColorRangeMaxEntry->GetWidgetName());

  // Color map: gradient editor

  this->ColorEditorFrame->SetParent(this->ColorMapFrame->GetFrame());
  this->ColorEditorFrame->Create(this->Application, "frame", "");

  this->StartColorButton->SetParent(this->ColorEditorFrame);
  this->StartColorButton->ShowLabelOff();
  this->StartColorButton->Create(this->Application, "");
  this->StartColorButton->SetColor(1.0, 0.0, 0.0);
  this->StartColorButton->SetCommand(this, "StartColorButtonCallback");
  this->StartColorButton->SetBalloonHelpString("Select the minimum color.");

  this->Map->SetParent(this->ColorEditorFrame);
  this->Map->Create(this->Application, 
                    "-relief flat -bd 0 -highlightthickness 0 -padx 0 -pady 0");
  this->Script("bind %s <Configure> {%s MapConfigureCallback %s}", 
               this->Map->GetWidgetName(), 
               this->GetTclName(), "%w %h");

  this->EndColorButton->SetParent(this->ColorEditorFrame);
  this->EndColorButton->ShowLabelOff();
  this->EndColorButton->Create(this->Application, "");
  this->EndColorButton->SetColor(0.0, 0.0, 1.0);
  this->EndColorButton->SetCommand(this, "EndColorButtonCallback");
  this->EndColorButton->SetBalloonHelpString("Select the maximum color.");

  this->PresetsMenuButton->SetParent(this->ColorEditorFrame);
  this->PresetsMenuButton->Create(this->Application, "-indicator 0");
  this->PresetsMenuButton->SetBalloonHelpString("Select a preset color map.");
  this->PresetsMenuButton->AddCommand(
    "Blue to Red", 
    this, "SetColorSchemeToBlueRed", "Set Color Scheme to Blue-Red");
  this->PresetsMenuButton->AddCommand(
    "Red to Blue", 
    this, "SetColorSchemeToRedBlue", "Set Color Scheme to Red-Blue");
  this->PresetsMenuButton->AddCommand(
    "Grayscale", 
    this, "SetColorSchemeToGrayscale", "Set Color Scheme to Grayscale");
  
  // This was a molecular color map that we do not need.
  // We may want to allow editing of individual color entries ...
  //this->PresetsMenuButton->AddCommand(
  //  "RGBW", 
  //  this, "SetColorSchemeToRGBW", "Set Color Scheme to RGBW (Red Blue Green White)");

  this->PresetsMenuButton->SetImageOption(image_presets, 
                                          image_presets_width, 
                                          image_presets_height, 
                                          image_presets_pixel_size,
                                          image_presets_buffer_length);

  this->Script("grid %s %s %s %s -sticky news -padx 1 -pady 2",
               this->PresetsMenuButton->GetWidgetName(),
               this->StartColorButton->GetWidgetName(),
               this->Map->GetWidgetName(),
               this->EndColorButton->GetWidgetName());

  this->Script("grid columnconfigure %s 2 -weight 1",
               this->Map->GetParent()->GetWidgetName());
  this->Script("grid %s -ipadx 1",
               this->PresetsMenuButton->GetWidgetName());

  // Color map: resolution

  this->NumberOfColorsScale->SetParent(this->ColorMapFrame->GetFrame());
  this->NumberOfColorsScale->Create(this->Application, "");
  this->NumberOfColorsScale->SetRange(2, 256);
  this->NumberOfColorsScale->SetValue(256);
  this->NumberOfColorsScale->DisplayLabel("Resolution:");
  this->NumberOfColorsScale->DisplayEntry();
  this->NumberOfColorsScale->DisplayEntryAndLabelOnTopOff();
  this->NumberOfColorsScale->SetEndCommand(this, 
                                           "NumberOfColorsScaleCallback");
  this->NumberOfColorsScale->SetEntryCommand(this, 
                                             "NumberOfColorsScaleCallback");
  this->NumberOfColorsScale->SetBalloonHelpString(
    "Select the discrete number of colors in the color map.");

  // Color map: pack

  this->Script("pack %s %s %s %s -side top -expand t -fill x -anchor nw",
               this->ArrayNameLabel->GetWidgetName(),
               this->ColorRangeFrame->GetWidgetName(),
               this->ColorEditorFrame->GetWidgetName(),
               this->NumberOfColorsScale->GetWidgetName());


  if (this->NumberOfVectorComponents > 1)
    {
    this->VectorFrame->SetParent(this);
    this->VectorFrame->ShowHideFrameOn();
    this->VectorFrame->Create(this->Application, 0);
    this->VectorFrame->SetLabel("Vector");

    this->VectorModeMenu->SetParent(this->VectorFrame->GetFrame());
    this->VectorModeMenu->Create(this->Application, "");
    this->VectorModeMenu->AddEntryWithCommand("Magnitude", this, 
                                          "VectorModeMagnitudeCallback");
    this->VectorModeMenu->AddEntryWithCommand("Component", this, 
                                          "VectorModeComponentCallback");
    this->VectorModeMenu->SetValue("Component");

    this->VectorComponentMenu->SetParent(this->VectorFrame->GetFrame());
    this->VectorComponentMenu->Create(this->Application, "");
    this->UpdateVectorComponentMenu();
    this->Script("pack %s -side left -expand f -fill both -padx 2",
                 this->VectorModeMenu->GetWidgetName());
    this->Script("pack %s -side left -expand f -fill both -padx 2",
                 this->VectorComponentMenu->GetWidgetName());
    }

  // Scalar bar frame

  this->ScalarBarFrame->SetParent(this);
  this->ScalarBarFrame->ShowHideFrameOn();
  this->ScalarBarFrame->Create(this->Application, 0);
  this->ScalarBarFrame->SetLabel("Scalar Bar");

  // Scalar bar : Visibility

  this->ScalarBarCheck->SetParent(this->ScalarBarFrame->GetFrame());
  this->ScalarBarCheck->Create(this->Application, "-text Visibility");
  this->Application->Script(
    "%s configure -command {%s ScalarBarCheckCallback}",
    this->ScalarBarCheck->GetWidgetName(),
    this->GetTclName());

  // Scalar bar : Title control

  this->ScalarBarTitleFrame->SetParent(this->ScalarBarFrame->GetFrame());
  this->ScalarBarTitleFrame->Create(this->Application, "frame", "-bd 0");

  this->ScalarBarTitleLabel->SetParent(this->ScalarBarTitleFrame);
  this->ScalarBarTitleLabel->SetLabel("Title:");
  this->ScalarBarTitleLabel->Create(this->Application, label_settings);
  
  this->ScalarBarTitleEntry->SetParent(this->ScalarBarTitleFrame);
  this->ScalarBarTitleEntry->SetWidth(10);
  this->ScalarBarTitleEntry->Create(this->Application, "");
  this->Script("bind %s <KeyPress-Return> {%s ScalarBarTitleEntryCallback}",
               this->ScalarBarTitleEntry->GetWidgetName(),
               this->GetTclName());
  this->Script("bind %s <FocusOut> {%s ScalarBarTitleEntryCallback}",
               this->ScalarBarTitleEntry->GetWidgetName(),
               this->GetTclName()); 

  this->ScalarBarVectorTitleEntry->SetParent(this->ScalarBarTitleFrame);
  this->ScalarBarVectorTitleEntry->SetWidth(
    this->ScalarBarTitleEntry->GetWidth() / 2);
  this->ScalarBarVectorTitleEntry->Create(this->Application, "");
  this->Script(
    "bind %s <KeyPress-Return> {%s ScalarBarVectorTitleEntryCallback}",
               this->ScalarBarVectorTitleEntry->GetWidgetName(),
               this->GetTclName());
  this->Script("bind %s <FocusOut> {%s ScalarBarVectorTitleEntryCallback}",
               this->ScalarBarVectorTitleEntry->GetWidgetName(),
               this->GetTclName()); 

  this->TitleTextPropertyWidget->SetParent(this->ScalarBarTitleFrame);
  this->TitleTextPropertyWidget->SetTextProperty(
    this->ScalarBar->GetScalarBarActor()->GetTitleTextProperty());
  this->TitleTextPropertyWidget->SetActor2D(
    this->ScalarBar->GetScalarBarActor());
  this->TitleTextPropertyWidget->Create(this->Application);
  this->TitleTextPropertyWidget->SetChangedCommand(this, "RenderView");
  this->TitleTextPropertyWidget->SetTraceReferenceObject(this);
  this->TitleTextPropertyWidget->SetTraceReferenceCommand(
    "GetTitleTextPropertyWidget");

  this->Script("grid %s -row 0 -column 0 -sticky nws %s",
               this->ScalarBarTitleLabel->GetWidgetName(),
               grid_settings);

  this->Script("grid %s -row 0 -column 1 -sticky news %s",
               this->ScalarBarTitleEntry->GetWidgetName(),
               grid_settings);

  this->Script("grid %s -row 1 -column 1 -columnspan 2 -sticky nws %s",
               this->TitleTextPropertyWidget->GetWidgetName(),
               grid_settings);

  if (this->NumberOfVectorComponents > 1)
    {
    this->Script("grid %s -row 0 -column 2 -sticky news %s",
                 this->ScalarBarVectorTitleEntry->GetWidgetName(),
                 grid_settings);
    this->Script("grid columnconfigure %s 2 -weight 3",
                 this->ScalarBarVectorTitleEntry->GetParent()->GetWidgetName());
    }

  // Scalar bar : Label control

  this->ScalarBarLabelFormatFrame->SetParent(this->ScalarBarFrame->GetFrame());
  this->ScalarBarLabelFormatFrame->Create(this->Application, "frame", "-bd 0");

  this->ScalarBarLabelFormatLabel->SetParent(this->ScalarBarLabelFormatFrame);
  this->ScalarBarLabelFormatLabel->SetLabel("Labels:");
  this->ScalarBarLabelFormatLabel->Create(this->Application, label_settings);
  
  this->ScalarBarLabelFormatEntry->SetParent(this->ScalarBarLabelFormatFrame);
  this->ScalarBarLabelFormatEntry->SetWidth(
    this->ScalarBarTitleEntry->GetWidth());
  this->ScalarBarLabelFormatEntry->Create(this->Application, "");
  this->Script("bind %s <KeyPress-Return> {%s ScalarBarLabelFormatEntryCallback}",
               this->ScalarBarLabelFormatEntry->GetWidgetName(),
               this->GetTclName());
  this->Script("bind %s <FocusOut> {%s ScalarBarLabelFormatEntryCallback}",
               this->ScalarBarLabelFormatEntry->GetWidgetName(),
               this->GetTclName()); 
  this->ScalarBarLabelFormatEntry->SetBalloonHelpString(
    "Set the labels format (printf() style).");

  this->SetScalarBarLabelFormat(
    this->ScalarBar->GetScalarBarActor()->GetLabelFormat());

  this->LabelTextPropertyWidget->SetParent(this->ScalarBarLabelFormatFrame);
  this->LabelTextPropertyWidget->SetTextProperty(
    this->ScalarBar->GetScalarBarActor()->GetLabelTextProperty());
  this->LabelTextPropertyWidget->SetActor2D(
    this->ScalarBar->GetScalarBarActor());
  this->LabelTextPropertyWidget->Create(this->Application);
  this->LabelTextPropertyWidget->SetChangedCommand(this, "RenderView");
  this->LabelTextPropertyWidget->SetTraceReferenceObject(this);
  this->LabelTextPropertyWidget->SetTraceReferenceCommand(
    "GetLabelTextPropertyWidget");

  this->Script("grid %s -row 0 -column 0 -sticky nws %s",
               this->ScalarBarLabelFormatLabel->GetWidgetName(),
               grid_settings);

  this->Script("grid %s -row 0 -column 1 -sticky news %s",
               this->ScalarBarLabelFormatEntry->GetWidgetName(),
               grid_settings);

  this->Script("grid %s -row 1 -column 1 -sticky nws %s",
               this->LabelTextPropertyWidget->GetWidgetName(),
               grid_settings);

  // Scalar bar : enable copy between text property widgets

  this->TitleTextPropertyWidget->ShowCopyOn();
  this->TitleTextPropertyWidget->GetCopyButton()->SetBalloonHelpString(
    "Copy the labels text properties to the title text properties.");
  ostrstream copy1;
  copy1 << "CopyValuesFrom " << this->LabelTextPropertyWidget->GetTclName() << ends;
  this->TitleTextPropertyWidget->GetCopyButton()->SetCommand(
    this->TitleTextPropertyWidget, copy1.str());
  copy1.rdbuf()->freeze(0);

  this->LabelTextPropertyWidget->ShowCopyOn();
  this->LabelTextPropertyWidget->GetCopyButton()->SetBalloonHelpString(
    "Copy the title text properties to the labels text properties.");
  ostrstream copy2;
  copy2 << "CopyValuesFrom " << this->TitleTextPropertyWidget->GetTclName() << ends;
  this->LabelTextPropertyWidget->GetCopyButton()->SetCommand(
    this->LabelTextPropertyWidget, copy2.str());
  copy2.rdbuf()->freeze(0);

  // Scalar bar: synchronize all those grids to have them aligned

  const char *widgets[2];
  widgets[0] = this->ScalarBarTitleFrame->GetWidgetName();
  widgets[1] = this->ScalarBarLabelFormatFrame->GetWidgetName();

  int weights[2];
  weights[0] = 0;
  weights[1] = 4;

  float factors[2];
  factors[0] = 1.15;
  factors[1] = 0.0;

  vtkKWTkUtilities::SynchroniseGridsColumnMinimumSize(
    this->Application->GetMainInterp(), 2, widgets, factors, weights);

  // Scalar bar : pack/grid

  this->Script("pack %s -side top -fill y -anchor w",
               this->ScalarBarCheck->GetWidgetName());
  
  this->Script("pack %s %s -side top -expand t -fill both -anchor w",
               this->ScalarBarTitleFrame->GetWidgetName(),
               this->ScalarBarLabelFormatFrame->GetWidgetName());

  // Back button

  this->BackButton->SetParent(this);
  this->BackButton->Create(this->Application, "-text {Back}");
  this->BackButton->SetCommand(this, "BackButtonCallback");

  // Pack

  this->Script("pack %s -side top -anchor n -fill x -padx 2 -pady 2", 
               this->ColorMapFrame->GetWidgetName());
  if (this->NumberOfVectorComponents > 1)
    {
    this->Script("pack %s -side top -anchor n -fill x -padx 2 -pady 2", 
                 this->VectorFrame->GetWidgetName());
    }
  this->Script("pack %s %s -side top -anchor n -fill x -padx 2 -pady 2", 
               this->ScalarBarFrame->GetWidgetName(),
               this->BackButton->GetWidgetName());

  this->SetColorSchemeToBlueRed();
}

//----------------------------------------------------------------------------
void vtkPVColorMap::UpdateVectorComponentMenu()
{
  int idx;
  char numStr[5];

  if (this->NumberOfVectorComponents  == 1)
    {
    return;
    }

  this->VectorComponentMenu->ClearEntries();
  if ( *(this->VectorComponentTitles[this->VectorComponent]) != '\0')
    {
    this->VectorComponentMenu->SetValue(
                         this->VectorComponentTitles[this->VectorComponent]);
    }
  else
    {
    sprintf(numStr, "%d", this->VectorComponent + 1);
    this->VectorComponentMenu->SetValue(numStr);
    } 

  for (idx = 0; idx < this->NumberOfVectorComponents; ++idx)
    {
    char command[64];
    sprintf(command, "VectorComponentCallback %d", idx);
    if (*(this->VectorComponentTitles[idx]) != '\0')
      {                                       
      this->VectorComponentMenu->AddEntryWithCommand(
                                           this->VectorComponentTitles[idx], 
                                           this, command);
      }
    else
      {
      sprintf(numStr, "%d", idx+1);
      this->VectorComponentMenu->AddEntryWithCommand(numStr, this, command);
      }
    }
} 


//----------------------------------------------------------------------------
void vtkPVColorMap::SetNumberOfVectorComponents(int  num)
{
  int idx;

  if (this->Application && num != 0)
    {
    vtkErrorMacro("You must set the number of vector components before "
                  "you create this color map.");
    return;
    }

  if (num == this->NumberOfVectorComponents)
    {
    return;
    }

  // Get rid of old arrays.
  // Use for delete.  This number shold not be changed after creation.
  if (this->VectorComponentTitles)
    {
    for (idx = 0; idx < this->NumberOfVectorComponents; ++idx)
      {
      delete [] this->VectorComponentTitles[idx];
      this->VectorComponentTitles[idx] = NULL;
      }
    }

  delete[] this->VectorComponentTitles;
  this->VectorComponentTitles = NULL;
  
  this->NumberOfVectorComponents = num;

  // Set defaults for component titles.
  if (num > 0)
    {
    this->VectorComponentTitles = new char* [num];
    }
  for (idx = 0; idx < num; ++idx)
    {
    this->VectorComponentTitles[idx] = new char[4];  
    }
  if (num == 3)
    { // Use XYZ for default of three component vectors.
    strcpy(this->VectorComponentTitles[0], "X");
    strcpy(this->VectorComponentTitles[1], "Y");
    strcpy(this->VectorComponentTitles[2], "Z");
    }
  else
    {
    for (idx = 0; idx < num; ++idx)
      {
      sprintf(this->VectorComponentTitles[idx], "%d", idx+1);
      }
    }

  if (this->ArrayName != NULL)
    {
    char *str2;
    str2 = new char [strlen(this->ArrayName) + 128];
    sprintf(str2, "GetPVColorMap {%s} %d", this->ArrayName, 
            this->NumberOfVectorComponents);
    this->SetTraceReferenceCommand(str2);
    delete [] str2;
    }
}

//----------------------------------------------------------------------------
void vtkPVColorMap::CreateParallelTclObjects(vtkPVApplication *pvApp)
{
  this->vtkKWWidget::SetApplication(pvApp);
  vtkPVProcessModule* pm = pvApp->GetProcessModule();
  
  this->LookupTableID = pm->NewStreamObject("vtkLookupTable");
  pm->SendStreamToClientAndServer();
  this->LookupTable =
    vtkLookupTable::SafeDownCast(pm->GetObjectFromID(this->LookupTableID));
  pm->GetStream() << vtkClientServerStream::Invoke 
                  << this->LookupTableID << "SetVectorModeToComponent"
                  << vtkClientServerStream::End;

  this->ScalarBarID = pm->NewStreamObject("vtkScalarBarWidget");
  pm->SendStreamToClientAndServer();
  this->ScalarBar =
    vtkScalarBarWidget::SafeDownCast(pm->GetObjectFromID(this->ScalarBarID));
  this->ScalarBar->SetInteractor(
    this->PVRenderView->GetPVWindow()->GetInteractor());
  pm->GetStream() << vtkClientServerStream::Invoke 
                  << this->ScalarBarID << "GetScalarBarActor"
                  << vtkClientServerStream::End;
  pm->GetStream() << vtkClientServerStream::Invoke 
                  << vtkClientServerStream::LastResult 
                  << "GetPositionCoordinate" 
                  << vtkClientServerStream::End;
  pm->GetStream() << vtkClientServerStream::Invoke 
                  << vtkClientServerStream::LastResult 
                  << "SetValue" << 0.87 << 0.25
                  << vtkClientServerStream::End;
  pm->GetStream() << vtkClientServerStream::Invoke 
                  << this->ScalarBarID << "GetScalarBarActor"
                  << vtkClientServerStream::End;
  pm->GetStream() << vtkClientServerStream::Invoke 
                  << vtkClientServerStream::LastResult 
                  << "SetWidth" << 0.13 
                  << vtkClientServerStream::End;
  pm->GetStream() << vtkClientServerStream::Invoke 
                  << this->ScalarBarID << "GetScalarBarActor"
                  << vtkClientServerStream::End;
  pm->GetStream() << vtkClientServerStream::Invoke 
                  << vtkClientServerStream::LastResult 
                  << "SetHeight" << 0.5 
                  << vtkClientServerStream::End;
  pm->SendStreamToClientAndServer();

  this->ScalarBarObserver = vtkScalarBarWidgetObserver::New();
  this->ScalarBarObserver->PVColorMap = this;
  this->ScalarBar->AddObserver(vtkCommand::InteractionEvent, 
                               this->ScalarBarObserver);
  this->ScalarBar->AddObserver(vtkCommand::StartInteractionEvent, 
                               this->ScalarBarObserver);
  this->ScalarBar->AddObserver(vtkCommand::EndInteractionEvent, 
                               this->ScalarBarObserver);

  this->UpdateScalarBarTitle();

  pm->GetStream() << vtkClientServerStream::Invoke 
                  << this->ScalarBarID << "GetScalarBarActor"
                  << vtkClientServerStream::End;
  pm->GetStream() << vtkClientServerStream::Invoke 
                  << vtkClientServerStream::LastResult 
                  << "SetLookupTable" << this->LookupTableID
                  << vtkClientServerStream::End;
  pm->SendStreamToClientAndServer();
}

//----------------------------------------------------------------------------
void vtkPVColorMap::RenderView()
{
  if (this->PVRenderView)
    {
    this->PVRenderView->EventuallyRender();
    }
}

//----------------------------------------------------------------------------
void vtkPVColorMap::BackButtonCallback()
{
  if (this->PVRenderView == NULL)
    {
    return;
    }

  // This has a side effect of gathering and display information.
  this->PVRenderView->GetPVWindow()->GetCurrentPVSource()->GetPVOutput()->UpdateProperties();
  this->PVRenderView->GetPVWindow()->ShowCurrentSourceProperties();
}


//----------------------------------------------------------------------------
void vtkPVColorMap::SetArrayName(const char* str)
{
  if ( this->ArrayName == NULL && str == NULL) 
    { 
    return;
    }
  if ( this->ArrayName && str && (!strcmp(this->ArrayName,str))) 
    { 
    return;
    }
  if (this->ArrayName)
    {
    delete [] this->ArrayName;
    this->ArrayName = NULL;
    }
  if (str)
    {
    this->ArrayName = new char[strlen(str)+1];
    strcpy(this->ArrayName,str);
    }
  if (str)
    {
    char *tmp;
    tmp = new char[strlen(str)+128];
    sprintf(tmp, "Parameter: %s", str);
    this->ArrayNameLabel->SetLabel(tmp);
    delete [] tmp;
    }

  if (str != NULL)
    {
    char *str2;
    str2 = new char [strlen(str) + 128];
    sprintf(str2, "GetPVColorMap {%s} %d", str, this->NumberOfVectorComponents);
    this->SetTraceReferenceCommand(str2);
    delete [] str2;
    }
  this->Modified();
}

//----------------------------------------------------------------------------
int vtkPVColorMap::MatchArrayName(const char* str, int numberOfComponents)
{
  if (str == NULL || this->ArrayName == NULL)
    {
    return 0;
    }
  if (strcmp(str, this->ArrayName) == 0 && 
      numberOfComponents == this->NumberOfVectorComponents)
    {
    return 1;
    }
  return 0;
}

//----------------------------------------------------------------------------
void vtkPVColorMap::ScalarBarTitleEntryCallback()
{
  this->SetScalarBarTitle(this->ScalarBarTitleEntry->GetValue());
}

//----------------------------------------------------------------------------
void vtkPVColorMap::SetScalarBarTitle(const char* name)
{
  this->SetScalarBarTitleInternal(name);
  this->AddTraceEntry("$kw(%s) SetScalarBarTitle {%s}", 
                      this->GetTclName(), name);
}

//----------------------------------------------------------------------------
void vtkPVColorMap::SetScalarBarTitleInternal(const char* name)
{
  if (this->ScalarBarTitle == NULL && name == NULL) 
    { 
    return;
    }

  if (this->ScalarBarTitle && name && (!strcmp(this->ScalarBarTitle, name))) 
    { 
    return;
    }

  if (this->ScalarBarTitle) 
    { 
    delete [] this->ScalarBarTitle; 
    this->ScalarBarTitle = NULL;
    }

  if (name)
    {
    this->ScalarBarTitle = new char[strlen(name) + 1];
    strcpy(this->ScalarBarTitle, name);
    } 

  this->ScalarBarTitleEntry->SetValue(name);

  this->UpdateScalarBarTitle();

  this->Modified();
}


//----------------------------------------------------------------------------
void vtkPVColorMap::ScalarBarVectorTitleEntryCallback()
{
  this->SetScalarBarVectorTitle(this->ScalarBarVectorTitleEntry->GetValue());
}

//----------------------------------------------------------------------------
void vtkPVColorMap::SetScalarBarVectorTitle(const char* name)
{
  if (this->VectorMode == vtkPVColorMap::MAGNITUDE)
    {
    if (this->VectorMagnitudeTitle == NULL && name == NULL) 
      { 
      return;
      }

    if (this->VectorMagnitudeTitle && name && 
        (!strcmp(this->VectorMagnitudeTitle, name)))
      {
      return;
      }

    if (this->VectorMagnitudeTitle)
      {
      delete [] this->VectorMagnitudeTitle;
      this->VectorMagnitudeTitle = NULL;
      }

    if (name)
      {
      this->VectorMagnitudeTitle = new char[strlen(name) + 1];
      strcpy(this->VectorMagnitudeTitle, name);
      }

    this->ScalarBarVectorTitleEntry->SetValue(name);

    this->AddTraceEntry("$kw(%s) SetScalarBarVectorTitle {%s}", 
                        this->GetTclName(), name);

    this->UpdateScalarBarTitle();

    this->Modified();
    }
  else
    {
    if (this->VectorComponentTitles == NULL)
      {
      return;
      }

    if (this->VectorComponentTitles[this->VectorComponent] == NULL && 
        name == NULL) 
      { 
      return;
      }

    if (this->VectorComponentTitles[this->VectorComponent] && 
        name && 
        (!strcmp(this->VectorComponentTitles[this->VectorComponent], name)))
      {
      return;
      }

    if (this->VectorComponentTitles[this->VectorComponent])
      {
      delete [] this->VectorComponentTitles[this->VectorComponent];
      this->VectorComponentTitles[this->VectorComponent] = NULL;
      }

    if (name)
      {
      this->VectorComponentTitles[this->VectorComponent] = 
        new char[strlen(name) + 1];
      strcpy(this->VectorComponentTitles[this->VectorComponent], name);
      }
    
    this->ScalarBarVectorTitleEntry->SetValue(name);

    this->AddTraceEntry("$kw(%s) SetScalarBarVectorTitle {%s}", 
                        this->GetTclName(), name);

    this->UpdateVectorComponentMenu();

    this->UpdateScalarBarTitle();

    this->Modified();
    }
}

//----------------------------------------------------------------------------
void vtkPVColorMap::ScalarBarLabelFormatEntryCallback()
{
  this->SetScalarBarLabelFormat(this->ScalarBarLabelFormatEntry->GetValue());
}

//----------------------------------------------------------------------------
void vtkPVColorMap::SetScalarBarLabelFormat(const char* name)
{
  if (this->ScalarBarLabelFormat == NULL && name == NULL) 
    { 
    return;
    }

  if (this->ScalarBarLabelFormat && 
      name && 
      (!strcmp(this->ScalarBarLabelFormat,name))) 
    { 
    return;
    }

  if (this->ScalarBarLabelFormat) 
    { 
    delete [] this->ScalarBarLabelFormat; 
    this->ScalarBarLabelFormat = NULL;
    }

  if (name)
    {
    this->ScalarBarLabelFormat = new char[strlen(name) + 1];
    strcpy(this->ScalarBarLabelFormat,name);
    } 

  this->ScalarBarLabelFormatEntry->SetValue(name);

  this->AddTraceEntry("$kw(%s) SetScalarBarLabelFormat {%s}", 
                      this->GetTclName(), name);

  if (this->ScalarBar != NULL && this->ScalarBarLabelFormat != NULL)
    {
    this->ScalarBar->GetScalarBarActor()->SetLabelFormat(
      this->ScalarBarLabelFormat);
    this->RenderView();
    }

  this->Modified();
}

//----------------------------------------------------------------------------
void vtkPVColorMap::UpdateLookupTable()
{
  vtkPVApplication *pvApp = this->GetPVApplication();
  vtkPVProcessModule* pm = pvApp->GetProcessModule();

  // The a hue is arbitrary, make is consistent
  // so we do not get unexpected interpolated hues.
  if (this->StartHSV[1] == 0.0)
    {
    this->StartHSV[0] = this->EndHSV[0];
    }
  if (this->EndHSV[1] == 0.0)
    {
    this->EndHSV[0] = this->StartHSV[0];
    }
  pm->GetStream() << vtkClientServerStream::Invoke
                  << this->LookupTableID << "SetNumberOfTableValues"
                  << this->NumberOfColors
                  << vtkClientServerStream::End;
  pm->GetStream() << vtkClientServerStream::Invoke
                  << this->LookupTableID << "SetHueRange"
                  << this->StartHSV[0] << this->EndHSV[0]
                  << vtkClientServerStream::End;
  pm->GetStream() << vtkClientServerStream::Invoke
                  << this->LookupTableID << "SetSaturationRange"
                  << this->StartHSV[1] << this->EndHSV[1]
                  << vtkClientServerStream::End;
  pm->GetStream() << vtkClientServerStream::Invoke
                  << this->LookupTableID << "SetValueRange"
                  << this->StartHSV[2] << this->EndHSV[2]
                  << vtkClientServerStream::End;
  pm->GetStream() << vtkClientServerStream::Invoke
                  << this->LookupTableID << "ForceBuild"
                  << vtkClientServerStream::End;
  pm->SendStreamToClientAndServer();
  
  if (this->MapWidth > 0 && this->MapHeight > 0)
    {
    this->UpdateMap(this->MapWidth, this->MapHeight);
    }

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


//----------------------------------------------------------------------------
void vtkPVColorMap::NumberOfColorsScaleCallback()
{
  int num = (int)(this->NumberOfColorsScale->GetValue());

  if (num == this->NumberOfColors)
    {
    return;
    }

  this->AddTraceEntry("$kw(%s) SetNumberOfColors %d", this->GetTclName(),
                      num);

  this->NumberOfColors = num;
  this->UpdateLookupTable();
}

//----------------------------------------------------------------------------
// Access for trace files.
void vtkPVColorMap::SetNumberOfColors(int num)
{
  if (num == this->NumberOfColors)
    {
    return;
    }
  this->NumberOfColorsScale->SetValue(num);
  this->NumberOfColorsScaleCallback();
}

//----------------------------------------------------------------------------
void vtkPVColorMap::SetColorSchemeToRedBlue()
{
  this->StartHSV[0] = VTK_PV_COLOR_MAP_RED_HUE;
  this->StartHSV[1] = VTK_PV_COLOR_MAP_RED_SATURATION;
  this->StartHSV[2] = VTK_PV_COLOR_MAP_RED_VALUE;
  this->EndHSV[0] = VTK_PV_COLOR_MAP_BLUE_HUE;
  this->EndHSV[1] = VTK_PV_COLOR_MAP_BLUE_SATURATION;
  this->EndHSV[2] = VTK_PV_COLOR_MAP_BLUE_VALUE;

  this->StartColorButton->SetColor(1.0, 0.0, 0.0);
  this->EndColorButton->SetColor(0.0, 0.0, 1.0);

  this->UpdateLookupTable();
  this->AddTraceEntry("$kw(%s) SetColorSchemeToRedBlue", this->GetTclName());
}

//----------------------------------------------------------------------------
void vtkPVColorMap::SetColorSchemeToBlueRed()
{
  this->StartHSV[0] = VTK_PV_COLOR_MAP_BLUE_HUE;
  this->StartHSV[1] = VTK_PV_COLOR_MAP_BLUE_SATURATION;
  this->StartHSV[2] = VTK_PV_COLOR_MAP_BLUE_VALUE;
  this->EndHSV[0] = VTK_PV_COLOR_MAP_RED_HUE;
  this->EndHSV[1] = VTK_PV_COLOR_MAP_RED_SATURATION;
  this->EndHSV[2] = VTK_PV_COLOR_MAP_RED_VALUE;

  this->StartColorButton->SetColor(0.0, 0.0, 1.0);
  this->EndColorButton->SetColor(1.0, 0.0, 0.0);

  this->UpdateLookupTable();
  this->AddTraceEntry("$kw(%s) SetColorSchemeToBlueRed", this->GetTclName());
}



//----------------------------------------------------------------------------
void vtkPVColorMap::SetColorSchemeToGrayscale()
{
  this->StartHSV[0] = VTK_PV_COLOR_MAP_BLACK_HUE;
  this->StartHSV[1] = VTK_PV_COLOR_MAP_BLACK_SATURATION;
  this->StartHSV[2] = VTK_PV_COLOR_MAP_BLACK_VALUE;
  this->EndHSV[0] = VTK_PV_COLOR_MAP_WHITE_HUE;
  this->EndHSV[1] = VTK_PV_COLOR_MAP_WHITE_SATURATION;
  this->EndHSV[2] = VTK_PV_COLOR_MAP_WHITE_VALUE;

  this->StartColorButton->SetColor(0.0, 0.0, 0.0);
  this->EndColorButton->SetColor(1.0, 1.0, 1.0);

  this->UpdateLookupTable();
  this->AddTraceEntry("$kw(%s) SetColorSchemeToGrayscale", this->GetTclName());
}

//----------------------------------------------------------------------------
void vtkPVColorMap::SetColorSchemeToRGBW()
{
  this->StartHSV[0] = 0.0;
  this->StartHSV[1] = 0.0;
  this->StartHSV[2] = 0.0;
  this->EndHSV[0] = 0.0;
  this->EndHSV[1] = 0.0;
  this->EndHSV[2] = 1.0;

  this->StartColorButton->SetColor(1.0, 0.0, 0.0);
  this->EndColorButton->SetColor(1.0, 1.0, 1.0);
  this->NumberOfColorsScale->SetValue(4);
  this->NumberOfColors = 4;

  // Try to keep interpolated colors consitent with this
  // Special color map.
  this->StartHSV[0] = 0.0;
  this->StartHSV[1] = 1.0;
  this->StartHSV[2] = 1.0;
  this->EndHSV[0] = 0.6666;
  this->EndHSV[1] = 0.0;
  this->EndHSV[2] = 1.0;

  vtkPVApplication* pvApp = this->GetPVApplication();
  vtkPVProcessModule* pm = pvApp->GetProcessModule();
  pm->GetStream() << vtkClientServerStream::Invoke 
                  << this->LookupTableID << "SetNumberOfTableValues"
                  << 4
                  << vtkClientServerStream::End;
  pm->GetStream() << vtkClientServerStream::Invoke 
                  << this->LookupTableID << "SetTableValue"
                  << 0 << 1 << 0 << 0 << 1
                  << vtkClientServerStream::End;
  pm->GetStream() << vtkClientServerStream::Invoke 
                  << this->LookupTableID << "SetTableValue"
                  << 1 << 0 << 1 << 0 << 1
                  << vtkClientServerStream::End;
  pm->GetStream() << vtkClientServerStream::Invoke 
                  << this->LookupTableID << "SetTableValue"
                  << 2 << 0 << 0 << 1 << 1
                  << vtkClientServerStream::End;
  pm->GetStream() << vtkClientServerStream::Invoke 
                  << this->LookupTableID << "SetTableValue"
                  << 3 << 1 << 1 << 1 << 1
                  << vtkClientServerStream::End;
  pm->SendStreamToClientAndServer();
  if (this->MapWidth > 0 && this->MapHeight > 0)
    {
    this->UpdateMap(this->MapWidth, this->MapHeight);
    }

  this->GetPVRenderView()->EventuallyRender();
  this->AddTraceEntry("$kw(%s) SetColorSchemeToRGBW", this->GetTclName());
}

//----------------------------------------------------------------------------
void vtkPVColorMap::StartColorButtonCallback(double r, double g, double b)
{
  double rgb[3];
  double hsv[3];

  // Convert RGB to HSV.
  rgb[0] = r;
  rgb[1] = g;
  rgb[2] = b;
  this->RGBToHSV(rgb, hsv);

  this->SetStartHSV(hsv[0], hsv[1], hsv[2]);
}


//----------------------------------------------------------------------------
// Access for trace files.
void vtkPVColorMap::SetStartHSV(double h, double s, double v)
{
  double hsv[3];
  double rgb[3];

  if ( this->StartHSV[0] == h && 
       this->StartHSV[1] == s && this->StartHSV[2] == v)
    {
    return;
    }

  // Change color button (should have no callback effect...)
  hsv[0] = h;  hsv[1] = s;  hsv[2] = v;
  this->HSVToRGB(hsv, rgb);
  this->StartColorButton->SetColor(rgb);

  this->AddTraceEntry("$kw(%s) SetStartHSV %g %g %g", 
                      this->GetTclName(), h, s, v);

  this->StartHSV[0] = h;
  this->StartHSV[1] = s;
  this->StartHSV[2] = v;

  this->UpdateLookupTable();
}

//----------------------------------------------------------------------------
void vtkPVColorMap::EndColorButtonCallback(double r, double g, double b)
{
  double rgb[3];
  double hsv[3];

  // Convert RGB to HSV.
  rgb[0] = r;
  rgb[1] = g;
  rgb[2] = b;
  this->RGBToHSV(rgb, hsv);

  this->SetEndHSV(hsv[0], hsv[1], hsv[2]);
}


//----------------------------------------------------------------------------
// Access for trace files.
void vtkPVColorMap::SetEndHSV(double h, double s, double v)
{
  double hsv[3];
  double rgb[3];

  if ( this->EndHSV[0] == h && 
       this->EndHSV[1] == s && this->EndHSV[2] == v)
    {
    return;
    }

  // Change color button (should have no callback effect...)
  hsv[0] = h;  hsv[1] = s;  hsv[2] = v;
  this->HSVToRGB(hsv, rgb);
  this->EndColorButton->SetColor(rgb);

  this->AddTraceEntry("$kw(%s) SetEndHSV %g %g %g", 
                      this->GetTclName(), h, s, v);

  this->EndHSV[0] = h;
  this->EndHSV[1] = s;
  this->EndHSV[2] = v;

  this->UpdateLookupTable();
}

//----------------------------------------------------------------------------
void vtkPVColorMap::ScalarBarCheckCallback()
{
  this->SetScalarBarVisibility(this->ScalarBarCheck->GetState());
  if ( this->GetPVRenderView() )
    {
    this->GetPVRenderView()->EventuallyRender();
    }
}

//----------------------------------------------------------------------------
void vtkPVColorMap::SetScalarRange(double min, double max)
{
  this->SetScalarRangeInternal(min, max);
  this->AddTraceEntry("$kw(%s) SetScalarRange %g %g", this->GetTclName(),
                      min, max);
}


//----------------------------------------------------------------------------
void vtkPVColorMap::SetScalarRangeInternal(double min, double max)
{
  vtkPVApplication *pvApp = this->GetPVApplication();
  vtkPVProcessModule* pm = pvApp->GetProcessModule();
  char str[256];

  sprintf(str, "%g", min);
  this->ColorRangeMinEntry->GetEntry()->SetValue(str);
  sprintf(str, "%g", max);
  this->ColorRangeMaxEntry->GetEntry()->SetValue(str);

  if (this->ScalarRange[0] == min && this->ScalarRange[1] == max)
    {
    return;
    }

  this->ScalarRange[0] = min;
  this->ScalarRange[1] = max;
  pm->GetStream() << vtkClientServerStream::Invoke 
                  << this->LookupTableID << "SetTableRange"
                  << min << max
                  << vtkClientServerStream::End;

  pm->SendStreamToClientAndServer();

  this->Modified();
}

//----------------------------------------------------------------------------
void vtkPVColorMap::SetVectorComponent(int component)
{
  this->AddTraceEntry("$kw(%s) SetVectorComponent %d", 
                      this->GetTclName(), component);

  if (component < 0)
    {
    component = 0;
    }
  if (component >= this->NumberOfVectorComponents)
    {
    component = this->NumberOfVectorComponents-1;
    }

  if (this->VectorComponent == component)
    {
    return;
    }

  this->VectorComponent = component;

  // Change the title of the scalar bar.
  this->UpdateScalarBarTitle();

  vtkPVApplication *pvApp = this->GetPVApplication();
  if ( !pvApp )
    {
    return;
    }
  vtkPVProcessModule* pm = pvApp->GetProcessModule();
  pm->GetStream() << vtkClientServerStream::Invoke 
                  << this->LookupTableID << "SetVectorComponent"
                  << component
                  << vtkClientServerStream::End;
  pm->SendStreamToClientAndServer();
  this->Modified();
}


//----------------------------------------------------------------------------
void vtkPVColorMap::ResetScalarRange()
{
  this->ResetScalarRangeInternal();
  this->AddTraceEntry("$kw(%s) ResetScalarRange", this->GetTclName());
}

//----------------------------------------------------------------------------
void vtkPVColorMap::ResetScalarRangeInternal()
{
  double range[2];
  double tmp[2];
  vtkPVSourceCollection *sourceList;
  vtkPVSource *pvs;
  int component = this->VectorComponent;
  if (this->VectorMode == vtkPVColorMap::MAGNITUDE)
    {
    component = -1;
    }

  if (this->Application == NULL || this->PVRenderView == NULL)
    {
    vtkErrorMacro("Trying to reset scalar range without application and view.");
    return;
    }

  range[0] = VTK_DOUBLE_MAX;
  range[1] = -VTK_DOUBLE_MAX;

  // Compute global scalar range ...
  sourceList = this->PVRenderView->GetPVWindow()->GetSourceList("Sources");
  sourceList->InitTraversal();
  while ( (pvs = sourceList->GetNextPVSource()) )
    {
    // For point data ...
    vtkPVArrayInformation *ai;
    ai = pvs->GetDataInformation()->GetPointDataInformation()->GetArrayInformation(this->ArrayName);
    if (ai)
      {
      ai->GetComponentRange(component, tmp);
      if (tmp[0] < range[0])
        {
        range[0] = tmp[0];
        }
      if (tmp[1] > range[1])
        {
        range[1] = tmp[1];
        }
      }
    // For cell data ...
    ai = pvs->GetDataInformation()->GetCellDataInformation()->GetArrayInformation(this->ArrayName);
    if (ai)
      {  
      ai->GetComponentRange(component, tmp);
      if (tmp[0] < range[0])
        {
        range[0] = tmp[0];
        }
      if (tmp[1] > range[1])
        {
        range[1] = tmp[1];
        }
      }
    }

  if (range[1] < range[0])
    {
    range[0] = 0.0;
    range[1] = 1.0;
    }
  if (range[0] == range[1])
    {
    range[1] = range[0] + 0.001;
    }

  this->SetScalarRangeInternal(range[0], range[1]);

  if ( this->GetPVRenderView() )
    {
    this->GetPVRenderView()->EventuallyRender();
    }
}

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

//----------------------------------------------------------------------------
void vtkPVColorMap::IncrementUseCount()
{
  ++this->UseCount;
  this->UpdateInternalScalarBarVisibility();
}

//----------------------------------------------------------------------------
void vtkPVColorMap::DecrementUseCount()
{
  --this->UseCount;
  this->UpdateInternalScalarBarVisibility();
}


//----------------------------------------------------------------------------
void vtkPVColorMap::SetScalarBarVisibility(int val)
{
  if (this->ScalarBarVisibility == val)
    {
    return;
    }
  this->ScalarBarVisibility = val;
  
  // Make sure the UI is up to date.
  if (val)
    {
    this->ScalarBarCheck->SetState(1);
    }
  else
    {
    this->ScalarBarCheck->SetState(0);
    }

  this->AddTraceEntry("$kw(%s) SetScalarBarVisibility %d", this->GetTclName(),
                      val);
  
  this->UpdateInternalScalarBarVisibility();
}

//----------------------------------------------------------------------------
void vtkPVColorMap::UpdateInternalScalarBarVisibility()
{
  int visible = this->ScalarBarVisibility;

  if (this->UseCount == 0)
    {
    visible = 0;
    }

  if (this->InternalScalarBarVisibility == visible)
    {
    return;
    }
  this->InternalScalarBarVisibility = visible;


  if (!this->GetPVRenderView())
    {
    return;
    }
  
  vtkPVProcessModule* pm = this->GetPVApplication()->GetProcessModule();
  vtkPVRenderModule* rm = this->GetPVApplication()->GetRenderModule();
  if (rm == NULL)
    {
    return;
    }

  if (visible)
    {
    // This removes all renderers from the render window before enabling 
    // the widget. It then adds them back into the render window.
    // I assume the widget needs to know which renderer it uses.
    // It's the old poked renderer problem.
    this->GetPVRenderView()->Enable3DWidget(this->ScalarBar);

    // Since there is no interactor on the server, add the prop directly.
    pm->GetStream() << vtkClientServerStream::Invoke 
                    << this->ScalarBarID << "GetScalarBarActor"
                    << vtkClientServerStream::End;
    pm->GetStream() << vtkClientServerStream::Invoke 
                    << rm->GetRenderer2DID() << "AddActor"
                    << vtkClientServerStream::LastResult 
                    << vtkClientServerStream::End;
    pm->SendStreamToServer();
    
    // This is here in case a process has no geometry.  
    // We have to explicitly build the color map.  The mapper
    // skips this if there is nothing to render.
    // Shouldn't the scalar build the color map if necessary?
    pm->GetStream() << vtkClientServerStream::Invoke 
                    << this->LookupTableID << "Build"
                    << vtkClientServerStream::End;
    pm->GetStream() << vtkClientServerStream::Invoke 
                    << this->LookupTableID << "Modified"
                    << vtkClientServerStream::End;
    }
  else
    {
    this->ScalarBar->SetEnabled(0);

    // Since there is no interactor on the server, remove the prop directly.
    pm->GetStream() << vtkClientServerStream::Invoke 
                    << this->ScalarBarID << "GetScalarBarActor"
                    << vtkClientServerStream::End;
    pm->GetStream() << vtkClientServerStream::Invoke 
                    << rm->GetRenderer2DID() << "RemoveActor"
                    << vtkClientServerStream::LastResult 
                    << vtkClientServerStream::End;
    pm->SendStreamToServer();
    }

  this->Modified();
}


//----------------------------------------------------------------------------
void vtkPVColorMap::SaveInBatchScript(ofstream *file)
{
  if (this->VisitedFlag)
    {
    return;
    }
  this->VisitedFlag = 1;

  *file << "vtkLookupTable pvTemp" << this->LookupTableID << endl;
  *file << "\tpvTemp" << this->LookupTableID << " SetNumberOfTableValues " 
        << this->NumberOfColors << endl;
  *file << "\tpvTemp" << this->LookupTableID << " SetHueRange " 
        << this->StartHSV[0] << " " << this->EndHSV[0] << endl;
  *file << "\tpvTemp" << this->LookupTableID << " SetSaturationRange " 
        << this->StartHSV[1] << " " << this->EndHSV[1] << endl;
  *file << "\tpvTemp" << this->LookupTableID << " SetValueRange " 
        << this->StartHSV[2] << " " << this->EndHSV[2] << endl;
  *file << "\tpvTemp" << this->LookupTableID << " SetTableRange "
        << this->ScalarRange[0] << " " << this->ScalarRange[1] << endl;
  *file << "\tpvTemp" << this->LookupTableID << " SetVectorComponent " 
        << this->VectorComponent << endl;
  *file << "\tpvTemp" << this->LookupTableID << " Build" << endl;

  if (this->ScalarBarVisibility)
    {
    char scalarBarTclName[128];
    sprintf(scalarBarTclName, "ScalarBar%d", this->InstanceCount);
    ostrstream actor;

    //*file << "vtkScalarBarWidget " << scalarBarTclName << "\n";
    *file << "vtkScalarBarActor " << scalarBarTclName << "\n";
    actor << scalarBarTclName << ends;

    *file << "\t" << actor.str() << " SetLookupTable pvTemp" 
          << this->LookupTableID << "\n";

    *file << "\t" << actor.str() << " SetOrientation "
          << this->ScalarBar->GetScalarBarActor()->GetOrientation() << "\n";

    *file << "\t" << actor.str() << " SetWidth " 
          << this->ScalarBar->GetScalarBarActor()->GetWidth() << "\n";

    *file << "\t" << actor.str() << " SetHeight " 
          << this->ScalarBar->GetScalarBarActor()->GetHeight() << "\n";

    const double *pos = 
     this->ScalarBar->GetScalarBarActor()->GetPositionCoordinate()->GetValue();
    *file << "\t[" << actor.str() << " GetPositionCoordinate] SetValue " 
          << pos[0] << " " << pos[1] << "\n";

    *file << "\t" << actor.str() << " SetTitle {" 
          << this->ScalarBar->GetScalarBarActor()->GetTitle() << "}\n";

    *file << "\t" << actor.str() << " SetLabelFormat {" 
          << this->ScalarBar->GetScalarBarActor()->GetLabelFormat() << "}\n";

    ostrstream ttprop, tlprop;
    ttprop << "[" << actor.str() << " GetTitleTextProperty]" << ends;
    this->TitleTextPropertyWidget->SaveInTclScript(file, ttprop.str());
    ttprop.rdbuf()->freeze(0);

    tlprop << "[" << actor.str() << " GetLabelTextProperty]" << ends;
    this->LabelTextPropertyWidget->SaveInTclScript(file, tlprop.str());
    tlprop.rdbuf()->freeze(0);

    *file << "Ren1" << " AddActor " << scalarBarTclName << endl;

    actor.rdbuf()->freeze(0);
    }
}

//----------------------------------------------------------------------------
void vtkPVColorMap::UpdateScalarBarTitle()
{
  if (this->ScalarBar == NULL || this->ScalarBarTitle == NULL)
    {
    return;
    }

  if (this->VectorMode == vtkPVColorMap::MAGNITUDE)
    {
    ostrstream ostr;
    ostr << this->ScalarBarTitle << " " << this->VectorMagnitudeTitle << ends;
    this->ScalarBar->GetScalarBarActor()->SetTitle(ostr.str());
    this->ScalarBarVectorTitleEntry->SetValue(this->VectorMagnitudeTitle),
    ostr.rdbuf()->freeze(0);    
    }
  else if (this->NumberOfVectorComponents == 1)
    {
    this->ScalarBar->GetScalarBarActor()->SetTitle(this->ScalarBarTitle);
    }
  else
    {
    ostrstream ostr;
    ostr << this->ScalarBarTitle << " " 
         << this->VectorComponentTitles[this->VectorComponent] << ends;
    this->ScalarBar->GetScalarBarActor()->SetTitle(ostr.str());
    this->ScalarBarVectorTitleEntry->SetValue(
                        this->VectorComponentTitles[this->VectorComponent]);
    ostr.rdbuf()->freeze(0);    
    }

  this->RenderView();
}

//----------------------------------------------------------------------------
void vtkPVColorMap::ColorRangeEntryCallback()
{
  double min, max;

  min = this->ColorRangeMinEntry->GetEntry()->GetValueAsFloat();
  max = this->ColorRangeMaxEntry->GetEntry()->GetValueAsFloat();
  
  // Avoid the bad range error
  if (max <= min)
    {
    max = min + 0.00001;
    }

  this->SetScalarRange(min, max);
  if ( this->GetPVRenderView() )
    {
    this->GetPVRenderView()->EventuallyRender();
    }
}

//----------------------------------------------------------------------------
void vtkPVColorMap::RGBToHSV(double rgb[3], double hsv[3])
{
  double hue = 0;
  double sat = 0;
  double val = 0;
  double lx, ly, lz;

  if (rgb[0] <= 0.0 && rgb[1] <= 0.0 && rgb[2] <= 0.0)
    {
    hsv[0] = 0.0;
    hsv[1] = 0.0;
    hsv[2] = 0.0;
    return;
    }

  if (rgb[0] == rgb[1] && rgb[1] == rgb[2])
    {
    hsv[2] = rgb[0];
    hsv[1] = 0.0;
    hsv[0] = 0.0;
    return;
    }

  if (rgb[0] >= rgb[1] && rgb[1] >= rgb[2])
    { // case 0
    val = rgb[0];
    lz = rgb[1];
    lx = rgb[2];
    sat = 1.0 - (lx/val);
    hue = (0.0 + (1.0 - ((1.0 - (lz/val))/sat)))/6.0;
    }
  else if (rgb[1] >= rgb[0] && rgb[0] >= rgb[2])
    { // case 1
    ly = rgb[0];
    val = rgb[1];
    lx = rgb[2];
    sat = 1.0 - (lx/val);
    hue = (1.0 + ((1.0 - (ly/val))/sat))/6.0;
    }
  else if (rgb[1] >= rgb[2] && rgb[2] >= rgb[0])
    { // case 2
    lx = rgb[0];
    val = rgb[1];
    lz = rgb[2];
    sat = 1.0 - (lx/val);
    hue = (2.0 + (1.0 - ((1.0 - (lz/val))/sat)))/6.0;
    }
  else if (rgb[2] >= rgb[1] && rgb[1] >= rgb[0])
    { // case 3
    lx = rgb[0];
    ly = rgb[1];
    val = rgb[2];
    sat = 1.0 - (lx/val);
    hue = (3.0 + ((1.0 - (ly/val))/sat))/6.0;
    }
  else if (rgb[2] >= rgb[0] && rgb[0] >= rgb[1])
    { // case 4
    lz = rgb[0];
    lx = rgb[1];
    val = rgb[2];
    sat = 1.0 - (lx/val);
    hue = (4.0 + (1.0 - ((1.0 - (lz/val))/sat)))/6.0;
    }
  else if (rgb[0] >= rgb[2] && rgb[2] >= rgb[1])
    { // case 5
    val = rgb[0];
    lx = rgb[1];
    ly = rgb[2];
    sat = 1.0 - (lx/val);
    hue = (5.0 + ((1.0 - (ly/val))/sat))/6.0;
    }
  hsv[0] = hue;
  hsv[1] = sat;
  hsv[2] = val;
}

//----------------------------------------------------------------------------
// Only used to get the color of the button when HSV is set from script.
// It might be easier to save the RGB values.
void vtkPVColorMap::HSVToRGB(double hsv[3], double rgb[3])
{
  double hue = hsv[0];
  double sat = hsv[1];
  double val = hsv[2];
  double lx, ly, lz;

  // Wrap hue into expected range.
  while (hue >= 1.0)
    {
    hue = hue-1.0;
    }
  while (hue < 0.0)
    {
    hue = hue+1.0;
    }

  // Gray.
  if (sat == 0.0)
    {
    rgb[0] = rgb[1] = rgb[2] = val;
    return;
    }

  // Red (green)
  if (hue < (1.0/6.0))
    {
    rgb[0] = val;
    lx = (1.0-sat)*val;
    lz = val*(1.0 - ((1.0 - (6.0*hue))*sat));
    rgb[1] = lz;
    rgb[2] = lx;
    return;
    }
  // Green (red)
  if (hue < 2.0/6.0)
    {
    rgb[1] = val;
    lx = (1.0-sat)*val;
    ly = val*(1.0 - (((6.0*hue) - 1.0)*sat));
    rgb[0] = ly;
    rgb[2] = lx;
    return;
    }
  // Green (blue)
  if (hue< (3.0/6.0))
    { // case 2
    rgb[1] = val;
    lx = (1.0-sat)*val;
    lz = val*(1.0 - ((1.0 - ((6.0*hue) - 2.0))*sat));
    rgb[0] = lx;
    rgb[2] = lz;
    return;
    }
  // Blue (green)
  if (hue < (4.0/6.0))
    {
    rgb[2] = val;
    lx = (1.0 - sat)*val;
    ly = val*(1.0 - (((6.0*hue)-3.0)*sat));
    rgb[0] = lx;
    rgb[1] = ly;
    return;
    }
  // Blue (red)
  if (hue < 5.0/6.0)
    { // case 4
    rgb[2] = val;
    lx = (1.0-sat)*val;
    lz = val* (1.0 - ((1.0 - ((6.0*hue)-4.0))*sat));
    rgb[0] = lz;
    rgb[1] = lx;
    return;
    }
  // Red (blue).
  if (hue < 1.0)
    {
    rgb[0] = val;
    lx = (1.0-sat)*val;    
    ly = val*(1.0 - (((6.0*hue)-5.0)*sat));
    rgb[1] = lx;
    rgb[2] = ly;
    return;
    }
}

//----------------------------------------------------------------------------
void vtkPVColorMap::MapConfigureCallback(int width, int height)
{
  this->UpdateMap(width, height);
}

//----------------------------------------------------------------------------
void vtkPVColorMap::VectorModeMagnitudeCallback()
{
  vtkPVApplication *pvApp = this->GetPVApplication();

  this->AddTraceEntry("$kw(%s) VectorModeMagnitudeCallback", 
                      this->GetTclName());

  vtkPVProcessModule* pm = pvApp->GetProcessModule();
  pm->GetStream() << vtkClientServerStream::Invoke 
                  << this->LookupTableID << "SetVectorModeToMagnitude"
                  << vtkClientServerStream::End;
  pm->SendStreamToClientAndServer();
  this->VectorMode = vtkPVColorMap::MAGNITUDE;
  this->Script("pack forget %s",
               this->VectorComponentMenu->GetWidgetName());
  this->UpdateScalarBarTitle();
  this->RenderView();
}

//----------------------------------------------------------------------------
void vtkPVColorMap::VectorModeComponentCallback()
{
  vtkPVApplication *pvApp = this->GetPVApplication();

  if (this->VectorComponentMenu->GetApplication() == NULL)
    { // Sanity check
    return;
    }

  this->AddTraceEntry("$kw(%s) VectorModeComponentCallback", 
                      this->GetTclName());

  vtkPVProcessModule* pm = pvApp->GetProcessModule();
  pm->GetStream() << vtkClientServerStream::Invoke 
                  << this->LookupTableID << "SetVectorModeToComponent"
                  << vtkClientServerStream::End;
  pm->SendStreamToClientAndServer();
  this->VectorMode = vtkPVColorMap::COMPONENT;
  this->Script("pack %s -side left -expand f -fill both -padx 2",
               this->VectorComponentMenu->GetWidgetName());
  this->UpdateScalarBarTitle();
  this->RenderView();
}

//----------------------------------------------------------------------------
void vtkPVColorMap::VectorComponentCallback(int component)
{
  this->SetVectorComponent(component);
  this->UpdateScalarBarTitle();
}

//----------------------------------------------------------------------------
void vtkPVColorMap::UpdateMap(int width, int height)
{
  int size;
  int i, j;
  double *range;
  double val, step;
  unsigned char *rgba;  
  unsigned char *ptr;  

  size = width*height;
  if (this->MapDataSize < size)
    {
    if (this->MapData)
      {
      delete [] this->MapData;
      }
    this->MapData = new unsigned char[size*3];
    this->MapDataSize = size;
    }
  this->MapWidth = width;
  this->MapHeight = height;

  if (this->LookupTable == NULL)
    {
    return;
    }

  range = this->LookupTable->GetRange();
  step = (range[1]-range[0])/(double)(width);
  ptr = this->MapData;
  for (j = 0; j < height; ++j)
    {
    for (i = 0; i < width; ++i)
      {
      val = range[0] + ((double)(i)*step);
      rgba = this->LookupTable->MapValue(val);
      
      ptr[0] = rgba[0];
      ptr[1] = rgba[1];
      ptr[2] = rgba[2];
      ptr += 3;
      }
    }

  if (size > 0)
    {
    this->Map->SetImageOption(this->MapData, width, height, 3);
    }
}

//----------------------------------------------------------------------------
void vtkPVColorMap::SetScalarBarPosition1(float x, float y)
{
  vtkScalarBarActor* sact = this->ScalarBar->GetScalarBarActor();
  sact->GetPositionCoordinate()->SetValue(x, y);
  this->AddTraceEntry("$kw(%s) SetScalarBarPosition1 %f %f", 
                      this->GetTclName(), x, y);
  this->RenderView();
}

//----------------------------------------------------------------------------
void vtkPVColorMap::SetScalarBarPosition2(float x, float y)
{
  vtkScalarBarActor* sact = this->ScalarBar->GetScalarBarActor();
  sact->GetPosition2Coordinate()->SetValue(x,y);
  this->AddTraceEntry("$kw(%s) SetScalarBarPosition2 %f %f", 
                      this->GetTclName(), x, y);
  this->RenderView();
}

//----------------------------------------------------------------------------
void vtkPVColorMap::SetScalarBarOrientation(int o)
{
  vtkScalarBarActor* sact = this->ScalarBar->GetScalarBarActor();
  sact->SetOrientation(o);
  this->AddTraceEntry("$kw(%s) SetScalarBarOrientation %d", 
                      this->GetTclName(), o);
  this->RenderView();
}

//----------------------------------------------------------------------------
void vtkPVColorMap::ExecuteEvent(vtkObject* vtkNotUsed(wdg), 
                                 unsigned long event,  
                                 void* vtkNotUsed(calldata))
{
  switch ( event )
    {
    case vtkCommand::StartInteractionEvent:
      this->PVRenderView->GetPVWindow()->InteractiveRenderEnabledOn();
      break;
    case vtkCommand::EndInteractionEvent:
      this->PVRenderView->GetPVWindow()->InteractiveRenderEnabledOff();
      this->RenderView();
      vtkScalarBarActor* sact = this->ScalarBar->GetScalarBarActor();
      double *pos1 = sact->GetPositionCoordinate()->GetValue();
      double *pos2 = sact->GetPosition2Coordinate()->GetValue();
      this->AddTraceEntry("$kw(%s) SetScalarBarPosition1 %lf %lf", 
                          this->GetTclName(), pos1[0], pos1[1]);
      this->AddTraceEntry("$kw(%s) SetScalarBarPosition2 %lf %lf", 
                          this->GetTclName(), pos2[0], pos2[1]);
      this->AddTraceEntry("$kw(%s) SetScalarBarOrientation %d",
                          this->GetTclName(), sact->GetOrientation());
      break;
    }
}

//----------------------------------------------------------------------------
void vtkPVColorMap::SaveState(ofstream *file)
{
  // Just manually initialize.
  *file << "set kw(" << this->GetTclName() << ") [$kw(" 
        << this->PVRenderView->GetPVWindow()->GetTclName() 
        << ") GetPVColorMap {" << this->ArrayName << "} " 
        << this->NumberOfVectorComponents << "]\n";

  if (strcmp(this->ScalarBarTitle, this->ArrayName) != 0)
    {
    *file << "$kw(" << this->GetTclName() << ") SetScalarBarTitle {" 
          << this->ScalarBarTitle << "}\n"; 
    }

  if (strcmp(this->VectorMagnitudeTitle, "Magnitude") != 0)
    {
    *file << "$kw(" << this->GetTclName() << ") SetScalarBarVectorTitle {" 
          << this->VectorMagnitudeTitle << "}\n"; 
    }

  if (strcmp(this->ScalarBarLabelFormat, "%-#6.3g") != 0)
    {
    *file << "$kw(" << this->GetTclName() << ") SetScalarBarLabelFormat {" 
          << this->ScalarBarLabelFormat << "}\n"; 
    }

  *file << "$kw(" << this->GetTclName() << ") SetScalarRange " 
        << this->ScalarRange[0] << " " << this->ScalarRange[1] << endl;

  *file << "$kw(" << this->GetTclName() << ") SetStartHSV " 
        << this->StartHSV[0] << " " << this->StartHSV[1] << " " 
        << this->StartHSV[2] << endl;
  *file << "$kw(" << this->GetTclName() << ") SetEndHSV " 
        << this->EndHSV[0] << " " << this->EndHSV[1] << " " 
        << this->EndHSV[2] << endl;

  if (this->NumberOfColors != 256)
    {
    *file << "$kw(" << this->GetTclName() << ") SetNumberOfColors " 
          << this->NumberOfColors << endl;
    }
  if (this->VectorMode == vtkPVColorMap::MAGNITUDE)
    {
    *file << "$kw(" << this->GetTclName() << ") VectorModeMagnitudeCallback\n";
    }
  if (this->VectorMode == vtkPVColorMap::COMPONENT && this->NumberOfVectorComponents > 1)
    {
    *file << "$kw(" << this->GetTclName() << ") VectorModeComponentCallback\n";
    if (this->VectorComponent != 0)
      {
      *file << "$kw(" << this->GetTclName() << ") SetVectorComponent " 
            << this->VectorComponent << endl;
      }
    }

  *file << "$kw(" << this->GetTclName() << ") SetScalarBarVisibility " 
        << this->ScalarBarVisibility << endl;

  vtkScalarBarActor* sact = this->ScalarBar->GetScalarBarActor();
  double *pos1 = sact->GetPositionCoordinate()->GetValue();
  double *pos2 = sact->GetPosition2Coordinate()->GetValue();

  if (pos1[0] != 0.87 || pos1[1] != 0.25)
    {    
    *file << "$kw(" << this->GetTclName() << ") SetScalarBarPosition1 " 
          << pos1[0] << " " << pos1[1] << endl; 
    }
  if (pos2[0] != 0.13 || pos2[1] != 0.5)
    {
    *file << "$kw(" << this->GetTclName() << ") SetScalarBarPosition2 " 
          << pos2[0] << " " << pos2[1] << endl;
    }
  if (sact->GetOrientation() != 1)
    {
    *file << "$kw(" << this->GetTclName() << ") SetScalarBarOrientation " 
         << sact->GetOrientation() << endl;
    }
}

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

  this->PropagateEnableState(this->ColorMapFrame);
  this->PropagateEnableState(this->ArrayNameLabel);
  this->PropagateEnableState(this->NumberOfColorsScale);
  this->PropagateEnableState(this->ColorEditorFrame);
  this->PropagateEnableState(this->StartColorButton);
  this->PropagateEnableState(this->Map);
  this->PropagateEnableState(this->EndColorButton);
  this->PropagateEnableState(this->VectorFrame);
  this->PropagateEnableState(this->VectorModeMenu);
  this->PropagateEnableState(this->VectorComponentMenu);
  this->PropagateEnableState(this->ScalarBarVectorTitleEntry);
  this->PropagateEnableState(this->ScalarBarFrame);
  this->PropagateEnableState(this->ScalarBarCheck);
  this->PropagateEnableState(this->ScalarBarTitleFrame);
  this->PropagateEnableState(this->ScalarBarTitleLabel);
  this->PropagateEnableState(this->ScalarBarTitleEntry);
  this->PropagateEnableState(this->ScalarBarLabelFormatFrame);
  this->PropagateEnableState(this->ScalarBarLabelFormatLabel);
  this->PropagateEnableState(this->ScalarBarLabelFormatEntry);
  this->PropagateEnableState(this->TitleTextPropertyWidget);
  this->PropagateEnableState(this->LabelTextPropertyWidget);
  this->PropagateEnableState(this->PresetsMenuButton);
  this->PropagateEnableState(this->ColorRangeFrame);
  this->PropagateEnableState(this->ColorRangeResetButton);
  this->PropagateEnableState(this->ColorRangeMinEntry);
  this->PropagateEnableState(this->ColorRangeMaxEntry);
  this->PropagateEnableState(this->BackButton);
}

//----------------------------------------------------------------------------
void vtkPVColorMap::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  os << indent << "UseCount: " << this->UseCount << endl;
  os << indent << "ScalarBarTitle: " 
     << (this->ScalarBarTitle ? this->ScalarBarTitle : "none" )
     << endl;
  os << indent << "ScalarBarLabelFormat: " 
     << (this->ScalarBarLabelFormat ? this->ScalarBarLabelFormat : "none" )
     << endl;
  os << indent << "ArrayName: " 
     << (this->ArrayName ? this->ArrayName : "none" )
     << endl;
  os << indent << "NumberOfVectorComponents: " 
     << this->NumberOfVectorComponents << endl;

  os << indent << "VectorComponent: " << this->VectorComponent << endl;
  os << indent << "LookupTableID: " 
     << this->LookupTableID
     << endl;
  os << indent << "ScalarBar: " << this->ScalarBar << endl;
  os << indent << "ScalarBarCheck: " << this->ScalarBarCheck << endl;
  os << indent << "TitleTextPropertyWidget: " << this->TitleTextPropertyWidget << endl;
  os << indent << "LabelTextPropertyWidget: " << this->LabelTextPropertyWidget << endl;
  
  os << indent << "ScalarBarVisibility: " << this->ScalarBarVisibility << endl;

  os << indent << "ScalarRange: " << this->ScalarRange[0] << ", "
     << this->ScalarRange[1] << endl;
  os << indent << "VisitedFlag: " << this->VisitedFlag << endl;
  os << indent << "ScalarBarCheck: " << this->ScalarBarCheck << endl;
}

