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

Copyright (c) 1998-2003 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 "vtkKWWindow.h"

#include "KitwareLogo.h"
#include "vtkKWApplication.h"
#include "vtkKWApplicationSettingsInterface.h"
#include "vtkKWCheckButton.h"
#include "vtkKWEvent.h"
#include "vtkKWFrame.h"
#include "vtkKWIcon.h"
#include "vtkKWLabel.h"
#include "vtkKWLoadSaveDialog.h"
#include "vtkKWMenu.h"
#include "vtkKWMessageDialog.h"
#include "vtkKWNotebook.h"
#include "vtkKWProgressGauge.h"
#include "vtkKWSplitFrame.h"
#include "vtkKWTclInteractor.h"
#include "vtkKWTkUtilities.h"
#include "vtkKWToolbar.h"
#include "vtkKWView.h"
#include "vtkKWViewCollection.h"
#include "vtkKWWidgetCollection.h"
#include "vtkKWWindowCollection.h"
#include "vtkObjectFactory.h"
#include "vtkString.h"
#include "vtkVector.txx"
#include "vtkVectorIterator.txx"

#define VTK_KW_HIDE_PROPERTIES_LABEL "Hide Left Panel" 
#define VTK_KW_SHOW_PROPERTIES_LABEL "Show Left Panel"
#define VTK_KW_WINDOW_GEOMETRY_REG_KEY "WindowGeometry"
#define VTK_KW_WINDOW_FRAME1_SIZE_REG_KEY "WindowFrame1Size"

vtkCxxRevisionMacro(vtkKWWindow, "1.160.2.1");
vtkCxxSetObjectMacro(vtkKWWindow, PropertiesParent, vtkKWWidget);

class vtkKWWindowMenuEntry
{
public:
  static vtkKWWindowMenuEntry *New() 
    {return new vtkKWWindowMenuEntry;};

  void Delete() {
    this->UnRegister(); }
  void Register() { this->ReferenceCount ++; }
  void Register(vtkObject *) {
    this->Register(); }
  void UnRegister()
    {
      if (--this->ReferenceCount <= 0)
        {
        delete this;
        }
    }
  void UnRegister(vtkObject *) {
    this->UnRegister(); }
  
  int Same( const char *filename, const char*fullfile, vtkKWObject *target, 
            const char *command )
    {
      if ( !this->Command || !this->File || !filename || !target || !command) 
        {
        return 0;
        }
      return (strcmp(fullfile, this->FullFile) == 0);
    }
  int InsertToMenu(int pos, const char* menuEntry, vtkKWMenu *menu);
  void SetFile(const char *file)
    {
      if ( this->File )
        {
        delete [] this->File;
        this->File = 0;
        }
      if ( file )
        {
        this->File = vtkString::Duplicate(file);
        }
    }
  void SetFullFile(const char *file)
    {
      if ( this->FullFile )
        {
        delete [] this->FullFile;
        this->FullFile = 0;
        }
      if ( file )
        {
        this->FullFile = vtkString::Duplicate(file);
        }
    }
  void SetCommand(const char *command)
    {
      if ( this->Command )
        {
        delete [] this->Command;
        this->Command = 0;
        }
      if ( command )
        {
        this->Command = vtkString::Duplicate(command);
        }
    }
  void SetTarget(vtkKWObject *target)
    {
      this->Target = target;
    }
  char *GetFile() { return this->File; }
  char *GetFullFile() { return this->FullFile; }
  char *GetCommand() { return this->Command; }
  vtkKWObject *GetTarget() { return this->Target; }
  
  static int TotalCount;

private:
  int ReferenceCount;

  vtkKWWindowMenuEntry()
    {
      this->File    = 0;
      this->FullFile= 0;
      this->Target  = 0;
      this->Command = 0;
      this->ReferenceCount = 1;
      this->TotalCount ++;
    }
  ~vtkKWWindowMenuEntry();
  char *File;
  char *FullFile;
  char *Command;
  vtkKWObject *Target;  
};

int vtkKWWindowMenuEntry::TotalCount = 0;

vtkKWWindowMenuEntry::~vtkKWWindowMenuEntry()
{
  if ( this->File )
    {
    delete [] this->File;
    }
  if ( this->FullFile )
    {
    delete [] this->FullFile;
    }
  if ( this->Command )
    {
    delete [] this->Command;
    }
  this->TotalCount --;
}

int vtkKWWindowMenuEntry::InsertToMenu( int pos, const char* menuEntry,
                                        vtkKWMenu *menu )
{
  if ( this->File && this->Target && this->Command )
    {
    char *file = vtkString::Duplicate(this->File);
    file[0] = pos + '0';
    ostrstream str;
    str << this->Command << " \"" << this->FullFile << "\"" << ends;
    menu->InsertCommand( menu->GetIndex(menuEntry), 
                         file, this->Target, str.str(), 0, this->FullFile );
    delete [] file;
    delete [] str.str();
    return 1;
    }
  return 0;
}

//----------------------------------------------------------------------------
vtkStandardNewMacro(vtkKWWindow );

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

vtkKWWindow::vtkKWWindow()
{
  this->PropertiesParent = NULL;
  this->SelectedView = NULL;
  this->Views = vtkKWViewCollection::New();

  this->Menu = vtkKWMenu::New();
  this->Menu->SetParent(this);
  
  this->MenuFile = vtkKWMenu::New();
  this->MenuFile->SetParent(this->Menu);

  this->MenuHelp = vtkKWMenu::New();
  this->MenuHelp->SetParent(this->Menu);
  
  this->PageMenu = vtkKWMenu::New();
  this->PageMenu->SetParent(this->MenuFile);
  
  this->ToolbarFrame = vtkKWWidget::New();
  this->ToolbarFrame->SetParent(this);  

  this->MiddleFrame = vtkKWSplitFrame::New();
  this->MiddleFrame->SetParent(this);

  this->ViewFrame = vtkKWWidget::New();
  this->ViewFrame->SetParent(this->MiddleFrame->GetFrame2());

  this->StatusFrame = vtkKWWidget::New();
  this->StatusFrame->SetParent(this);
    
  this->StatusLabel = vtkKWLabel::New();
  this->StatusLabel->SetParent(this->StatusFrame);
  this->StatusImage = vtkKWWidget::New();
  this->StatusImage->SetParent(this->StatusFrame);
  this->StatusImageName = NULL;
  
  this->ProgressFrame = vtkKWWidget::New();
  this->ProgressFrame->SetParent(this->StatusFrame);
  this->ProgressGauge = vtkKWProgressGauge::New();
  this->ProgressGauge->SetParent(this->ProgressFrame);

  this->TrayFrame = vtkKWFrame::New();
  this->TrayFrame->SetParent(this->StatusFrame);

  this->TrayImageError = vtkKWLabel::New();
  this->TrayImageError->SetParent(this->TrayFrame);

  this->Notebook = vtkKWNotebook::New();
  
  this->CommandFunction = vtkKWWindowCommand;

  this->MenuEdit = NULL;
  this->MenuView = NULL;
  this->MenuWindow = NULL;
  this->NumberOfMRUFiles = 0;
  this->RealNumberOfMRUFiles = 0;
  this->PrintTargetDPI = 100;

  this->SupportHelp = 1;

  this->WindowClass = NULL;
  this->SetWindowClass("KitwareWidget");

  this->Title = NULL;

  this->PromptBeforeClose = 1;

  this->RecentFilesVector = 0;
  this->NumberOfRecentFiles = 5;

  this->ScriptExtension = 0;
  this->ScriptType = 0;
  this->SetScriptExtension(".tcl");
  this->SetScriptType("Tcl");

  this->InExit = 0;

  this->RecentFilesMenuTag =0;

  this->ExitDialogWidget = 0;

  this->TclInteractor = NULL;

  this->Toolbars = vtkVector<vtkKWToolbar*>::New();
}

vtkKWWindow::~vtkKWWindow()
{
  if (this->TclInteractor)
    {
    this->TclInteractor->Delete();
    this->TclInteractor = NULL;
    }

  if ( this->RecentFilesVector )
    {
    vtkKWWindowMenuEntry *kc = 0;
    while( this->RecentFilesVector->GetNumberOfItems() )
      {
      kc = 0;
      unsigned long cc = this->RecentFilesVector->GetNumberOfItems()-1;
      if ( this->RecentFilesVector->GetItem(cc, kc) == VTK_OK && kc )
        {
        kc->Delete();
        this->RecentFilesVector->RemoveItem(cc);
        }
      }
    this->RecentFilesVector->Delete();
    }

  this->SetRecentFilesMenuTag(0);
  this->Notebook->Delete();
  this->SetPropertiesParent(NULL);
  this->SetSelectedView(NULL);
  if (this->Views)
    {
    this->Views->Delete();
    this->Views = NULL;
    }

#if (TK_MAJOR_VERSION == 8) && (TK_MINOR_VERSION <= 2)
  // This "hack" is here to get around a Tk bug ( Bug: 3402 )
  // in tkMenu.c
  vtkKWMenu* menuparent = vtkKWMenu::SafeDownCast(this->PageMenu->GetParent());
  if (menuparent)
    {
    menuparent->DeleteMenuItem(VTK_KW_PAGE_SETUP_MENU_LABEL);
    }
#endif

  this->Menu->Delete();
  this->PageMenu->Delete();
  this->MenuFile->Delete();
  this->MenuHelp->Delete();
  this->ToolbarFrame->Delete();
  this->ViewFrame->Delete();
  this->MiddleFrame->Delete();
  this->StatusFrame->Delete();
  this->StatusImage->Delete();
  this->StatusLabel->Delete();
  this->ProgressFrame->Delete();
  this->ProgressGauge->Delete();
  this->TrayFrame->Delete();
  this->TrayImageError->Delete();
  
  if (this->MenuEdit)
    {
    this->MenuEdit->Delete();
    }
  if (this->MenuView)
    {
    this->MenuView->Delete();
    }
  if (this->MenuWindow)
    {
    this->MenuWindow->Delete();
    }

  this->SetStatusImageName(0);
  this->SetWindowClass(0);
  this->SetTitle(0);
  this->SetScriptExtension(0);
  this->SetScriptType(0);

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

void vtkKWWindow::DisplayHelp()
{
  this->Application->DisplayHelp(this);
}

void vtkKWWindow::AddView(vtkKWView *v) 
{
  v->SetParentWindow(this);
  this->Views->AddItem(v);
}
void vtkKWWindow::RemoveView(vtkKWView *v) 
{
  v->SetParentWindow(NULL);
  this->Views->RemoveItem(v);
}

void vtkKWWindow::CreateDefaultPropertiesParent()
{
  if (!this->PropertiesParent)
    {
    vtkKWWidget *pp = vtkKWWidget::New();
    pp->SetParent(this->MiddleFrame->GetFrame1());
    pp->Create(this->Application,"frame","-bd 0");
    this->Script("pack %s -side left -fill both -expand t -anchor nw",
                 pp->GetWidgetName());
    this->SetPropertiesParent(pp);
    pp->Delete();
    }
  else
    {
    vtkDebugMacro("Properties Parent already set for Window");
    }
}

void vtkKWWindow::SetSelectedView(vtkKWView *_arg)
{
  vtkDebugMacro(<< this->GetClassName() << " (" << this << "): setting SelectedView to " << _arg ); 
  if (this->SelectedView != _arg) 
    { 
    if (this->SelectedView != NULL) 
      {
      this->SelectedView->Deselect(this);
      this->SelectedView->UnRegister(this); 
      }
    this->SelectedView = _arg; 
    if (this->SelectedView != NULL) 
      { 
      this->SelectedView->Register(this); 
      this->SelectedView->Select(this);
      } 
    this->Modified(); 
    } 
}

// invoke the apps exit when selected
void vtkKWWindow::Exit()
{  
  if (this->Application->GetDialogUp())
    {
    this->Script("bell");
    return;
    }
  if (!this->InExit)
    {
    this->InExit = 1;
    }
  else
    {
    return;
    }
  if ( this->ExitDialog() )
    {
    this->PromptBeforeClose = 0;
    this->Application->Exit();
    }
  else
    {
    this->InExit = 0;
    }
}

// invoke the apps close when selected
void vtkKWWindow::Close()
{
  if (this->Application->GetDialogUp())
    {
    this->Script("bell");
    return;
    }
  if ( this->PromptBeforeClose &&
       this->Application->GetWindows()->GetNumberOfItems() <= 1 )
    {
    if ( !this->ExitDialog() )
      {
      return;
      }
    }
  this->CloseNoPrompt();
}

  
void vtkKWWindow::CloseNoPrompt()
{
  if (this->TclInteractor )
    {
    this->TclInteractor->SetMasterWindow(NULL);
    this->TclInteractor->Delete();
    this->TclInteractor = NULL;
    }

  // If it's the last win, save its geometry

  if (this->Application->GetWindows()->GetNumberOfItems() <= 1 &&
      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->Script("wm geometry %s", this->GetWidgetName());
    this->Application->SetRegisteryValue(
      2, "Geometry", VTK_KW_WINDOW_GEOMETRY_REG_KEY, "%s", 
      this->Application->GetMainInterp()->result);
    this->Application->SetRegisteryValue(
      2, "Geometry", VTK_KW_WINDOW_FRAME1_SIZE_REG_KEY, "%d", 
      this->MiddleFrame->GetFrame1Size());
    }

  vtkKWView *v;

  // Give each view a chance to close
  this->Views->InitTraversal();
  while ((v = this->Views->GetNextKWView()))
    {
    v->Close();
    }

  // Close this window in the application. The
  // application will exit if there are no more windows.
  this->Application->Close(this);
}

void vtkKWWindow::Render()
{
  vtkKWView *v;
  
  this->Views->InitTraversal();
  while ((v = this->Views->GetNextKWView()))
    {
    v->Render();
    }
}

// invoke the apps about dialog when selected
void vtkKWWindow::DisplayAbout()
{
  this->Application->DisplayAbout(this);
}

void vtkKWWindow::SetStatusText(const char *text)
{
  this->StatusLabel->SetLabel(text);
}

const char *vtkKWWindow::GetStatusText()
{
  return this->StatusLabel->GetLabel();
}

// some common menus we provide here
vtkKWMenu *vtkKWWindow::GetMenuEdit()
{
  if (this->MenuEdit)
    {
    return this->MenuEdit;
    }
  
  this->MenuEdit = vtkKWMenu::New();
  this->MenuEdit->SetParent(this->GetMenu());
  this->MenuEdit->SetTearOff(0);
  this->MenuEdit->Create(this->Application,"");
  // Make sure Edit menu is next to file menu
  this->Menu->InsertCascade(1, "Edit", this->MenuEdit, 0);
  return this->MenuEdit;
}

vtkKWMenu *vtkKWWindow::GetMenuView()
{
  if (this->MenuView)
    {
    return this->MenuView;
    }

  this->MenuView = vtkKWMenu::New();
  this->MenuView->SetParent(this->GetMenu());
  this->MenuView->SetTearOff(0);
  this->MenuView->Create(this->Application, "");
  // make sure Help menu is on the right
  if (this->MenuEdit)
    { 
    this->Menu->InsertCascade(2, "View", this->MenuView, 0);
    }
  else
    {
    this->Menu->InsertCascade(1, "View", this->MenuView, 0);
    }
  
  return this->MenuView;
}

vtkKWMenu *vtkKWWindow::GetMenuWindow()
{
  if (this->MenuWindow)
    {
    return this->MenuWindow;
    }

  this->MenuWindow = vtkKWMenu::New();
  this->MenuWindow->SetParent(this->GetMenu());
  this->MenuWindow->SetTearOff(0);
  this->MenuWindow->Create(this->Application, "");
  // make sure Help menu is on the right
  if (this->MenuEdit)
    { 
    this->Menu->InsertCascade(1, "Window", this->MenuWindow, 0);
    }
  else
    {
    this->Menu->InsertCascade(2, "Window", this->MenuWindow, 0);
    }
  
  return this->MenuWindow;
}

void vtkKWWindow::Create(vtkKWApplication *app, char *args)
{
  const char *wname;

  // Set the application

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

  this->SetApplication(app);
  Tcl_Interp *interp = this->Application->GetMainInterp();

  // create the top level
  wname = this->GetWidgetName();
  this->Script("toplevel %s -visual best %s -class %s",wname,args,
               this->WindowClass);
  this->Script("wm title %s {%s}",wname,
               this->GetTitle());
  this->Script("wm iconname %s {%s}",wname,
               app->GetApplicationName());
  this->Script("wm protocol %s WM_DELETE_WINDOW {%s Close}",
               wname, this->GetTclName());

  // Restore window geometry

  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_KW_WINDOW_GEOMETRY_REG_KEY))
    {
    char geometry[40];
    if (this->Application->GetRegisteryValue(
      2, "Geometry", VTK_KW_WINDOW_GEOMETRY_REG_KEY, geometry))
      {
      this->Script("wm geometry %s %s", wname, geometry);
      }
    }
  else
    {
    this->Script("wm geometry %s 900x700+0+0", wname);
    }

  this->StatusFrame->Create(app,"frame","");

  
  this->SetStatusImageName(this->Script("image create photo"));
  this->CreateStatusImage();
  this->StatusImage->Create(app,"label",
                            "-relief sunken -bd 1 -fg #ffffff -bg #ffffff -highlightbackground #ffffff -highlightcolor #ffffff -highlightthickness 0 -padx 0 -pady 0");
  this->Script("%s configure -image %s", 
               this->StatusImage->GetWidgetName(),
               this->StatusImageName);

  this->Script("pack %s -side left -anchor c -ipadx 1 -ipady 1 -fill y", 
               this->StatusImage->GetWidgetName());

  this->StatusLabel->Create(app,"-relief sunken -padx 3 -bd 1 -anchor w");
  this->Script("pack %s -side left -padx 2 -expand yes -fill both",
               this->StatusLabel->GetWidgetName());

  this->Script("pack %s -side bottom -fill x -pady 2",
               this->StatusFrame->GetWidgetName());

  this->ProgressFrame->Create(app, "frame", "-relief sunken -borderwidth 2");
  this->ProgressGauge->SetLength(200);
  this->ProgressGauge->SetHeight(
    vtkKWTkUtilities::GetPhotoHeight(interp, this->StatusImageName) - 4);
  this->ProgressGauge->Create(app, "");

  this->Script("pack %s -side left -padx 2 -fill y", 
               this->ProgressFrame->GetWidgetName());
  this->Script("pack %s -side right -padx 2 -pady 2",
               this->ProgressGauge->GetWidgetName());

  this->TrayFrame->Create(app, 0);
  this->Script("%s configure -borderwidth 0", 
               this->TrayFrame->GetWidgetName());
  this->Script(
    "pack %s -side left -ipadx 0 -ipady 0 -padx 0 -pady 0 -fill both", 
    this->TrayFrame->GetWidgetName());
  this->TrayImageError->Create(app, "");
  this->Script("%s configure -relief sunken -bd 2",
               this->TrayImageError->GetWidgetName());

  this->TrayImageError->SetImageOption(vtkKWIcon::ICON_SMALLERRORRED);
  this->TrayImageError->SetBind(this, "<Button-1>", "ProcessErrorClick");
  
  // To force the toolbar on top, I am creating a separate "MiddleFrame" 
  // for the ViewFrame and PropertiesParent

  this->MiddleFrame->SetSeparatorSize(0);
  int min_size = 380;
  this->MiddleFrame->SetFrame1MinimumSize(min_size);

  if (this->Application->HasRegisteryValue(
        2, "Geometry", VTK_KW_WINDOW_FRAME1_SIZE_REG_KEY) &&
      this->Application->GetIntRegisteryValue(
        2, "Geometry", VTK_KW_WINDOW_FRAME1_SIZE_REG_KEY) >= min_size)
    {
    this->MiddleFrame->SetFrame1Size(
      this->Application->GetIntRegisteryValue(
        2, "Geometry", VTK_KW_WINDOW_FRAME1_SIZE_REG_KEY));
    }
  else
    {
    this->MiddleFrame->SetFrame1Size(min_size);
    }

  this->MiddleFrame->Create(app);
  this->Script("pack %s -side bottom -fill both -expand t",
    this->MiddleFrame->GetWidgetName());

  this->ViewFrame->Create(app,"frame","");
  this->Script("pack %s -side right -fill both -expand yes",
               this->ViewFrame->GetWidgetName());

  this->ToolbarFrame->Create(app, "frame", "-bd 0");
  
  // Set up standard menus
  this->Menu->SetTearOff(0);
  this->Menu->Create(app,"");
  this->MenuFile->SetTearOff(0);
  this->MenuFile->Create(app,"");
  this->Menu->AddCascade("File", this->MenuFile, 0);

  // add render quality setting
  this->PageMenu->SetTearOff(0);
  this->PageMenu->Create(this->Application,"");

  char* rbv = 
    this->PageMenu->CreateRadioButtonVariable(this,"PageSetup");
  // now add our own menu options 
  this->Script( "set %s 0", rbv );
  this->PageMenu->AddRadioButton(0,"100 DPI",rbv,this,"OnPrint 1 0", 0);
  this->PageMenu->AddRadioButton(1,"150 DPI",rbv,this,"OnPrint 1 1", 1);
  this->PageMenu->AddRadioButton(2,"300 DPI",rbv,this,"OnPrint 1 2", 0);
  delete [] rbv;
  // add the Print option
  this->MenuFile->AddSeparator();
  this->MenuFile->AddCascade(VTK_KW_PAGE_SETUP_MENU_LABEL, this->PageMenu, 8);

  this->MenuFile->AddSeparator();
  this->MenuFile->AddCommand("Close", this, "Close", 0);
  this->MenuFile->AddCommand("Exit", this, "Exit", 1);
  // install the menu bar into this window
  this->InstallMenu(this->Menu);

  // Properties panel

  this->GetMenuWindow()->AddCommand(VTK_KW_HIDE_PROPERTIES_LABEL, this,
                                    "TogglePropertiesVisibilityCallback", 1 );

  // Window properties / Application settings (leading to preferences)

  this->CreateDefaultPropertiesParent();

  // Create the notebook

  this->Notebook->SetParent(this->GetPropertiesParent());
  this->Notebook->Create(this->Application,"");
  this->Notebook->AlwaysShowTabsOn();

  // Help menu

  this->MenuHelp->SetTearOff(0);
  this->MenuHelp->Create(app,"");
  if ( this->SupportHelp )
    {
    this->Menu->AddCascade("Help", this->MenuHelp, 0);
    }
  this->MenuHelp->AddCommand("OnLine Help", this, "DisplayHelp", 0);
  this->MenuHelp->AddCommand("About", this, "DisplayAbout", 0);

}

void vtkKWWindow::OnPrint(int propagate, int res)
{
  int dpis[] = { 100, 150, 300 };
  this->PrintTargetDPI = dpis[res];
  if ( propagate )
    {
    float dpi = res;
    this->InvokeEvent(vtkKWEvent::PrinterDPIChangedEvent, &dpi);
    }
  else
    {
    char array[][20] = { "100 DPI", "150 DPI", "300 DPI" };
    this->PageMenu->Invoke( this->PageMenu->GetIndex(array[res]) );
    }
}

int vtkKWWindow::GetPropertiesVisiblity()
{
  return (this->MiddleFrame && this->MiddleFrame->GetFrame1Visibility() ? 1 : 0);
}

void vtkKWWindow::SetPropertiesVisiblity(int arg)
{
  if (arg)
    {
    if (!this->GetPropertiesVisiblity())
      {
      this->MiddleFrame->Frame1VisibilityOn();
      this->Script("%s entryconfigure 0 -label {%s}",
                   this->GetMenuWindow()->GetWidgetName(),
                   VTK_KW_HIDE_PROPERTIES_LABEL);
      }
    }
  else
    {
    if (this->GetPropertiesVisiblity())
      {
      this->MiddleFrame->Frame1VisibilityOff();
      this->Script("%s entryconfigure 0 -label {%s}",
                   this->GetMenuWindow()->GetWidgetName(),
                   VTK_KW_SHOW_PROPERTIES_LABEL);
      }
    }
}

void vtkKWWindow::TogglePropertiesVisibilityCallback()
{
  int arg = !this->GetPropertiesVisiblity();
  this->SetPropertiesVisiblity(arg);
  float farg = arg;
  this->InvokeEvent(vtkKWEvent::UserInterfaceVisibilityChangedEvent, &farg);
}

void vtkKWWindow::ShowWindowProperties()
{
  this->ShowProperties();
  
  // Forget current props and pack the notebook

  this->Script("pack forget [pack slaves %s]",
               this->Notebook->GetParent()->GetWidgetName());  

  this->Script("pack %s -pady 2 -padx 2 -fill both -expand yes -anchor n",
               this->Notebook->GetWidgetName());
}

void vtkKWWindow::ShowApplicationSettingsInterface()
{
  if (this->GetApplicationSettingsInterface())
    {
    this->ShowWindowProperties();
    this->GetApplicationSettingsInterface()->Raise();
    }
}

void vtkKWWindow::InstallMenu(vtkKWMenu* menu)
{ 
  this->Script("%s configure -menu %s", this->GetWidgetName(),
               menu->GetWidgetName());  
}

void vtkKWWindow::UnRegister(vtkObjectBase *o)
{
  if (!this->DeletingChildren)
    {
    // delete the children if we are about to be deleted
    if (this->ReferenceCount == this->Views->GetNumberOfItems() + 
        this->Children->GetNumberOfItems() + 1)
      {
      if (!(this->Views->IsItemPresent((vtkKWView *)o) ||
            this->Children->IsItemPresent((vtkKWWidget *)o)))
        {
        vtkKWWidget *child;
        vtkKWView *v;
        
        this->DeletingChildren = 1;
        this->Children->InitTraversal();
        while ((child = this->Children->GetNextKWWidget()))
          {
          child->SetParent(NULL);
          }
        // deselect if required
        if (this->SelectedView)
          {
          this->SetSelectedView(NULL);
          }
        this->Views->InitTraversal();
        while ((v = this->Views->GetNextKWView()))
          {
          v->SetParentWindow(NULL);
          }
        this->DeletingChildren = 0;
        }
      }
    }
  
  this->Superclass::UnRegister(o);
}

void vtkKWWindow::LoadScript()
{
  vtkKWLoadSaveDialog* loadScriptDialog = vtkKWLoadSaveDialog::New();
  this->RetrieveLastPath(loadScriptDialog, "LoadScriptLastPath");
  loadScriptDialog->SetParent(this);
  loadScriptDialog->Create(this->Application,"");
  loadScriptDialog->SaveDialogOff();
  loadScriptDialog->SetTitle("Load Script");
  loadScriptDialog->SetDefaultExtension(this->ScriptExtension);
  ostrstream filetypes;
  filetypes << "{{" << this->ScriptType << " Scripts} {" 
            << this->ScriptExtension << "}} {{All Files} {.*}}" << ends;
  loadScriptDialog->SetFileTypes(filetypes.str());
  filetypes.rdbuf()->freeze(0);

  if (loadScriptDialog->Invoke() && 
      vtkString::Length(loadScriptDialog->GetFileName()) > 0)
    {
    FILE *fin = fopen(loadScriptDialog->GetFileName(), "r");
    if (!fin)
      {
      vtkWarningMacro("Unable to open script file!");
      }
    else
      {
      this->SaveLastPath(loadScriptDialog, "LoadScriptLastPath");
      this->LoadScript(loadScriptDialog->GetFileName());
      }
    }
  loadScriptDialog->Delete();
}

void vtkKWWindow::LoadScript(const char *path)
{
  this->Script("set InitialWindow %s", this->GetTclName());
  this->Application->LoadScript(path);
}

void vtkKWWindow::CreateStatusImage()
{
  int x, y;
  Tk_PhotoHandle photo;
  Tk_PhotoImageBlock block;
  
  block.width = 128;
  block.height = 34;
  block.pixelSize = 3;
  block.pitch = block.width*block.pixelSize;
  block.offset[0] = 0;
  block.offset[1] = 1;
  block.offset[2] = 2;
  block.pixelPtr = new unsigned char [block.pitch*block.height];

  photo = Tk_FindPhoto(this->Application->GetMainInterp(),
                       this->StatusImageName);
  if (!photo)
    {
    vtkWarningMacro("error looking up color ramp image");
    return;
    }

  Tk_PhotoSetSize(photo, block.width, block.height);
  
  unsigned char *pp = block.pixelPtr;
  float *lp = KITLOGO + 33*128*3;
  for (y = 0; y < 34; y++)
    {
    for (x = 0; x < 128; x++)
      {
      pp[0] = (unsigned char)(*lp*255.0);
      lp++;
      pp[1] = (unsigned char)(*lp*255.0);
      lp++;
      pp[2] = (unsigned char)(*lp*255.0);
      lp++;
      pp += block.pixelSize;
      }
    lp = lp - 2*128*3;
    }
  
#if (TK_MAJOR_VERSION == 8) && (TK_MINOR_VERSION >= 4) && !defined(USE_COMPOSITELESS_PHOTO_PUT_BLOCK)
  Tk_PhotoPutBlock(photo, &block, 0, 0, block.width, block.height, TK_PHOTO_COMPOSITE_SET);
#else
  Tk_PhotoPutBlock(photo, &block, 0, 0, block.width, block.height);
#endif
  delete [] block.pixelPtr;
}

void vtkKWWindow::StoreRecentMenuToRegistery(const char * vtkNotUsed(key))
{
  char KeyNameP[10];
  char CmdNameP[10];
  unsigned int i;
  if ( !this->RealNumberOfMRUFiles )
    {
    return;
    }

  for (i = 0; i < this->NumberOfRecentFiles; i++)
    {
    sprintf(KeyNameP, "File%d", i);
    sprintf(CmdNameP, "File%dCmd", i);
    this->GetApplication()->DeleteRegisteryValue( 1, "MRU", KeyNameP );
    this->GetApplication()->DeleteRegisteryValue( 1, "MRU", CmdNameP );    
    if ( this->RecentFilesVector )
      {
      vtkKWWindowMenuEntry *vp = 0;
      if ( this->RecentFilesVector->GetItem(i, vp) == VTK_OK && vp )
        {
        this->GetApplication()->SetRegisteryValue(
          1, "MRU", KeyNameP, vp->GetFullFile());
        this->GetApplication()->SetRegisteryValue(
          1, "MRU", CmdNameP, vp->GetCommand());
        }
      }
    }
}

void vtkKWWindow::AddRecentFilesToMenu(const char *menuEntry, vtkKWObject *target)
{
  char KeyNameP[10];
  char CmdNameP[10];
  int i = 0;
  char File[1024];
  char Cmd[1024];
  
  char *newMenuEntry = 0;
  if ( menuEntry )
    {
    newMenuEntry = new char[ vtkString::Length(menuEntry)+1 ];
    while ( menuEntry[i] )
      {
      if ( menuEntry[i] == '\\' )
        {
        newMenuEntry[i] = '/';
        }
      else
        {
        newMenuEntry[i] = menuEntry[i];
        }      
      i++;
      }
    newMenuEntry[i] = 0;
    }

  if ( newMenuEntry )
    {
    this->SetRecentFilesMenuTag(newMenuEntry);
    }
  else
    {
    this->SetRecentFilesMenuTag("Close");
    }
  for (i = this->NumberOfRecentFiles-1; i >=0; i--)
    {
    sprintf(KeyNameP, "File%d", i);
    sprintf(CmdNameP, "File%dCmd", i);
    if ( this->GetApplication()->GetRegisteryValue(1, "MRU", KeyNameP, File) )
      {
      if ( this->GetApplication()->GetRegisteryValue(1, "MRU", CmdNameP, Cmd) )
        {
        if (vtkString::Length(File) > 1)
          {
          this->InsertRecentFileToMenu(File, target, Cmd);
          }
        }
      }
    }
  this->UpdateRecentMenu(NULL);
  delete [] newMenuEntry;
}

void vtkKWWindow::AddRecentFile(const char *key, const char *name, vtkKWObject *target,
                                const char *command)
{  
  const char* filename = this->Application->ExpandFileName(name);
  this->InsertRecentFileToMenu(filename, target, command);
  this->UpdateRecentMenu(key);
  this->StoreRecentMenuToRegistery(key);
}

int vtkKWWindow::GetFileMenuIndex()
{
  // First find the print-related menu commands
  if ( this->GetMenuFile()->HasItem(VTK_KW_PAGE_SETUP_MENU_LABEL))
    {
    return this->GetMenuFile()->GetIndex(VTK_KW_PAGE_SETUP_MENU_LABEL) - 1;  
    }

  // Otherwise find Close or Exit if Close was removed
  int clidx;
  if ( this->GetMenuFile()->HasItem("Close") )
    {
    clidx = this->GetMenuFile()->GetIndex("Close");  
    }
  else
    {
    clidx = this->GetMenuFile()->GetIndex("Exit");  
    }
  if (this->NumberOfMRUFiles > 0)
    {
    clidx -= this->NumberOfMRUFiles + 1;
    }
  return clidx - 1;  
}

int vtkKWWindow::ExitDialog()
{
  this->Application->SetBalloonHelpWidget(0);
  if ( this->ExitDialogWidget )
    {
    return 1;
    }
  ostrstream title;
  title << "Exit " << this->GetApplication()->GetApplicationName() << ends;
  char* ttl = title.str();
  ostrstream str;
  str << "Are you sure you want to exit " 
      << this->GetApplication()->GetApplicationName() << "?" << ends;
  char* msg = str.str();
  
  vtkKWMessageDialog *dlg2 = vtkKWMessageDialog::New();
  this->ExitDialogWidget = dlg2;
  dlg2->SetStyleToYesNo();
  dlg2->SetMasterWindow(this);
  dlg2->SetOptions(
     vtkKWMessageDialog::QuestionIcon | vtkKWMessageDialog::RememberYes |
     vtkKWMessageDialog::Beep | vtkKWMessageDialog::YesDefault );
  dlg2->SetDialogName(VTK_KW_EXIT_DIALOG_NAME);
  dlg2->Create(this->GetApplication(),"");
  dlg2->SetText( msg );
  dlg2->SetTitle( ttl );
  int ret = dlg2->Invoke();
  this->ExitDialogWidget = 0;
  dlg2->Delete();

  delete[] msg;
  delete[] ttl;
 
  vtkKWApplicationSettingsInterface *asi =  
    this->GetApplicationSettingsInterface();
  if (asi)
    {
    asi->Update();
    }
 
  return ret;
}

void vtkKWWindow::UpdateRecentMenu(const char * vtkNotUsed(key))
{  
  int cc;
  for ( cc = 0; cc < this->RealNumberOfMRUFiles; cc ++ )
    {
    this->GetMenuFile()->DeleteMenuItem(
      this->GetMenuFile()->GetIndex(this->GetRecentFilesMenuTag()) - 1);
    }
  if ( this->RealNumberOfMRUFiles )
    {
    this->GetMenuFile()->DeleteMenuItem(
      this->GetMenuFile()->GetIndex(this->GetRecentFilesMenuTag()) - 1);
    }
  this->RealNumberOfMRUFiles = 0;
  if ( this->RecentFilesVector )
    {
    for ( cc = 0; static_cast<unsigned int>(cc)<this->NumberOfRecentFiles; 
          cc++ ) 
      {
      vtkKWWindowMenuEntry *kc = 0;
      if ( this->RecentFilesVector->GetItem(cc, kc) == VTK_OK && kc )
        {
        kc->InsertToMenu(cc, this->GetRecentFilesMenuTag(),
                         this->GetMenuFile());
        this->RealNumberOfMRUFiles ++;
        }
      }
    if ( this->NumberOfRecentFiles )
      {
      this->GetMenuFile()->InsertSeparator(
        this->GetMenuFile()->GetIndex(this->GetRecentFilesMenuTag()));    
      }
    }
  //this->PrintRecentFiles();
}

void vtkKWWindow::InsertRecentFileToMenu(const char *filename, 
                                         vtkKWObject *target, 
                                         const char *command)
{
  //this->PrintRecentFiles();
  int flen = vtkString::Length(filename);
  char *file = new char [flen + 3];
  if ( flen <= 40 )
    {
    sprintf(file, "  %s", filename);
    }
  else
    {
    int ii;
    int lastI, lastJ;
    lastI = 0;
    lastJ = 0;
    for(ii=0; ii<=15; ii++)
      {
      if ( filename[ii] == '/' )
        {
        lastI = ii;
        }
      }
    int flen = vtkString::Length(filename);
    for(ii=flen; ii > (flen-20); ii--)
      {
      if ( filename[ii] == '/' )
        {
        lastJ = ii;
        }
      }
    if (!lastJ)
      {
      lastJ = ii;
      }
    char format[20];
    sprintf(format, "  %%.%ds...%%s", lastI+1);
    sprintf(file, format, filename, filename + lastJ);
    }

  if ( !this->RecentFilesVector )
    {
    this->RecentFilesVector = vtkVector<vtkKWWindowMenuEntry*>::New();
    }

  // Find current one
  vtkKWWindowMenuEntry *recent = 0;
  vtkKWWindowMenuEntry *kc = 0;
  vtkIdType cc;
  for ( cc = 0; cc < this->RecentFilesVector->GetNumberOfItems(); cc ++ )
    {
    kc = 0;
    if ( this->RecentFilesVector->GetItem(cc, kc) == VTK_OK && kc &&
         kc->Same( file, filename, target, command ) )
      {
      recent = kc;
      // delete it from array
      this->RecentFilesVector->RemoveItem(cc);
      break;
      }
    }

  if ( ! recent )
    {
    recent = vtkKWWindowMenuEntry::New();
    recent->SetFile( file );
    recent->SetFullFile( filename );
    recent->SetTarget( target );
    recent->SetCommand( command );
    this->NumberOfMRUFiles++;
   }

  // prepend it to array  
  this->RecentFilesVector->PrependItem( recent );
  while ( this->RecentFilesVector->GetNumberOfItems() > 
          static_cast<vtkIdType>(this->NumberOfRecentFiles) )
    {
    kc = 0;
    if ( this->RecentFilesVector->GetItem(this->NumberOfRecentFiles, kc) ==
         VTK_OK && kc )
      {
      kc->Delete();
      this->RecentFilesVector->RemoveItem(this->NumberOfRecentFiles);
      }
    }

  delete [] file;
  //this->PrintRecentFiles();
}

float vtkKWWindow::GetFloatRegisteryValue(int level, const char* subkey, 
                                          const char* key)
{
  return this->GetApplication()->GetFloatRegisteryValue(level, subkey, key);
}

int vtkKWWindow::GetIntRegisteryValue(int level, const char* subkey, 
                                      const char* key)
{
  return this->GetApplication()->GetIntRegisteryValue(level, subkey, key);
}
void vtkKWWindow::SaveLastPath(vtkKWLoadSaveDialog *dialog, const char* key)
{
  //  "OpenDirectory"
  if ( dialog->GetLastPath() )
    {
    this->GetApplication()->SetRegisteryValue(
      1, "RunTime", key, dialog->GetLastPath());
    }
}

void vtkKWWindow::RetrieveLastPath(vtkKWLoadSaveDialog *dialog, const char* key)
{
  char buffer[1024];
  if ( this->GetApplication()->GetRegisteryValue(1, "RunTime", key, buffer) )
    {
    if ( *buffer )
      {
      dialog->SetLastPath( buffer );
      }  
    }
}

void vtkKWWindow::SaveColor(int level, const char* key, float rgb[3])
{
  this->GetApplication()->SetRegisteryValue(
    level, "RunTime", key, "Color: %f %f %f", rgb[0], rgb[1], rgb[2]);
}

int vtkKWWindow::RetrieveColor(int level, const char* key, float rgb[3])
{
  char buffer[1024];
  rgb[0] = -1;
  rgb[1] = -1;
  rgb[2] = -1;

  int ok = 0;
  if (this->GetApplication()->GetRegisteryValue(
        level, "RunTime", key, buffer) )
    {
    if (*buffer)
      {      
      sscanf(buffer, "Color: %f %f %f", rgb, rgb+1, rgb+2);
      ok = 1;
      }
    }
  return ok;
}

int vtkKWWindow::BooleanRegisteryCheck(int level, 
                                       const char* subkey,
                                       const char* key, 
                                       const char* trueval)
{
  return this->GetApplication()->BooleanRegisteryCheck(level, subkey, key, trueval);
}


//----------------------------------------------------------------------------
void vtkKWWindow::WarningMessage(const char* message)
{
  vtkKWMessageDialog::PopupMessage(
    this->GetApplication(), this, "VTK Warning",
    message, vtkKWMessageDialog::WarningIcon);
  this->SetErrorIcon(2);
}

//----------------------------------------------------------------------------
void vtkKWWindow::SetErrorIcon(int s)
{
  if (s) 
    {
    this->Script("pack %s -fill both -ipadx 4 -expand yes", 
                 this->TrayImageError->GetWidgetName());
    if ( s > 1 )
      {
      this->TrayImageError->SetImageOption(vtkKWIcon::ICON_SMALLERRORRED);
      }
    else
      {
      this->TrayImageError->SetImageOption(vtkKWIcon::ICON_SMALLERROR);
      }
    }
  else
    {
    this->Script("pack forget %s", this->TrayImageError->GetWidgetName());
    }
}

//----------------------------------------------------------------------------
void vtkKWWindow::ErrorMessage(const char* message)
{
  //cout << message << endl;
  vtkKWMessageDialog::PopupMessage(
    this->GetApplication(), this, "VTK Error",
    message, vtkKWMessageDialog::ErrorIcon);
  this->SetErrorIcon(2);
}

//----------------------------------------------------------------------------
void vtkKWWindow::PrintRecentFiles()
{
  cout << "PrintRecentFiles" << endl;
  if ( !this->RecentFilesVector && this->NumberOfRecentFiles )
    {
    cout << "Problem with the number: " << this->NumberOfRecentFiles
         << endl;
    }
  if ( !this->RecentFilesVector )
    {
    return;
    }
  unsigned long cc;
  for ( cc = 0; cc< this->NumberOfRecentFiles; cc ++ )
    {
    vtkKWWindowMenuEntry *kc = 0;
    if ( this->RecentFilesVector->GetItem(cc, kc) == VTK_OK )
      {
      cout << "Item: " << kc << endl;
      }
    }
}

//----------------------------------------------------------------------------
void vtkKWWindow::ProcessErrorClick()
{
  this->SetErrorIcon(1);
}

//----------------------------------------------------------------------------
void vtkKWWindow::SetTitle (const char* _arg)
{
  if (this->Title == NULL && _arg == NULL) 
    { 
    return;
    }

  if (this->Title && _arg && (!strcmp(this->Title, _arg))) 
    {
    return;
    }

  if (this->Title) 
    { 
    delete [] this->Title; 
    }

  if (_arg)
    {
    this->Title = new char[strlen(_arg)+1];
    strcpy(this->Title, _arg);
    }
  else
    {
    this->Title = NULL;
    }

  this->Modified();

  if (this->Application && this->Title)
    {
    this->Script("wm title %s {%s}", this->GetWidgetName(), this->GetTitle());
    }
} 

//----------------------------------------------------------------------------
char* vtkKWWindow::GetTitle()
{
  if (!this->Title && 
      this->Application && 
      this->Application->GetApplicationName())
    {
    return this->Application->GetApplicationName();
    }
  return this->Title;
}

//----------------------------------------------------------------------------
void vtkKWWindow::DisplayCommandPrompt()
{
  if ( ! this->TclInteractor )
    {
    this->TclInteractor = vtkKWTclInteractor::New();
    ostrstream title;
    if (this->GetTitle())
      {
      title << this->GetTitle() << " : ";
      }
    title << "Command Prompt" << ends;
    this->TclInteractor->SetTitle(title.str());
    title.rdbuf()->freeze(0);
    this->TclInteractor->SetMasterWindow(this);
    this->TclInteractor->Create(this->Application);
    }
  
  this->TclInteractor->Display();
}

//----------------------------------------------------------------------------
void vtkKWWindow::ProcessEvent( vtkObject* object,
                                unsigned long event, 
                                void *clientdata, void *calldata)
{   
  float *fArgs = 0;
  if (calldata)
    {    
    fArgs = reinterpret_cast<float *>(calldata);
    }

  vtkKWWindow *self = reinterpret_cast<vtkKWWindow *>(clientdata);
  self->InternalProcessEvent(object, event, fArgs, calldata);
}

//----------------------------------------------------------------------------
void vtkKWWindow::InternalProcessEvent(vtkObject*, unsigned long, 
                                       float *, void *)
{
  // No implementation
}

//----------------------------------------------------------------------------
void vtkKWWindow::UpdateToolbarAspect()
{
  int flat_frame;
  if (this->Application->HasRegisteryValue(
    2, "RunTime", VTK_KW_TOOLBAR_FLAT_FRAME_REG_KEY))
    {
    flat_frame = this->Application->GetIntRegisteryValue(
      2, "RunTime", VTK_KW_TOOLBAR_FLAT_FRAME_REG_KEY);
    }
  else
    {
    flat_frame = vtkKWToolbar::GetGlobalFlatAspect();
    }

  int flat_buttons;
  if (this->Application->HasRegisteryValue(
    2, "RunTime", VTK_KW_TOOLBAR_FLAT_BUTTONS_REG_KEY))
    {
    flat_buttons = this->Application->GetIntRegisteryValue(
      2, "RunTime", VTK_KW_TOOLBAR_FLAT_BUTTONS_REG_KEY);
    }
  else
    {
    flat_buttons = vtkKWToolbar::GetGlobalWidgetsFlatAspect();
    }

  if (this->Toolbars)
    {
    vtkKWToolbar *tb = NULL;
    vtkVectorIterator<vtkKWToolbar *> *it = this->Toolbars->NewIterator();
    it->InitTraversal();
    while (!it->IsDoneWithTraversal())
      {
      if (it->GetData(tb) == VTK_OK)
        {
        tb->SetFlatAspect(flat_frame);
        tb->SetWidgetsFlatAspect(flat_buttons);
        }
      it->GoToNextItem();
      }
    it->Delete();
    }

  // Now the split frame packing mechanism is so weird that I will have
  // to unpack the toolbar frame myself in case it's empty, otherwise
  // the middle frame won't claim the space used by the toolbar frame

  if (this->ToolbarFrame && this->ToolbarFrame->IsCreated())
    {
    if (this->ToolbarFrame->GetNumberOfPackedChildren())
      {
      this->Script("pack %s -side top -fill x -expand no -before %s",
                   this->ToolbarFrame->GetWidgetName(),
                   this->MiddleFrame->GetWidgetName());
      }
    else
      {
      this->ToolbarFrame->Unpack();
      }
    }
}

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

  // Update the toolbars

  if (this->Toolbars)
    {
    vtkKWToolbar *tb = NULL;
    vtkVectorIterator<vtkKWToolbar *> *it = this->Toolbars->NewIterator();
    it->InitTraversal();
    while (!it->IsDoneWithTraversal())
      {
      if (it->GetData(tb) == VTK_OK)
        {
        tb->SetEnabled(this->Enabled);
        }
      it->GoToNextItem();
      }
    it->Delete();
    }

  if (this->Notebook)
    {
    this->Notebook->SetEnabled(this->Enabled);
    }
}

//----------------------------------------------------------------------------
void vtkKWWindow::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  os << indent << "Menu: " << this->GetMenu() << endl;
  os << indent << "MenuFile: " << this->GetMenuFile() << endl;
  os << indent << "Notebook: " << this->GetNotebook() << endl;
  os << indent << "NumberOfRecentFiles: " << this->GetNumberOfRecentFiles() 
     << endl;
  os << indent << "PrintTargetDPI: " << this->GetPrintTargetDPI() << endl;
  os << indent << "ProgressGauge: " << this->GetProgressGauge() << endl;
  os << indent << "PromptBeforeClose: " << this->GetPromptBeforeClose() 
     << endl;
  os << indent << "PropertiesParent: " << this->GetPropertiesParent() << endl;
  os << indent << "ScriptExtension: " << this->GetScriptExtension() << endl;
  os << indent << "ScriptType: " << this->GetScriptType() << endl;
  os << indent << "SelectedView: " << this->GetSelectedView() << endl;
  os << indent << "SupportHelp: " << this->GetSupportHelp() << endl;
  os << indent << "ToolbarFrame: " << this->GetToolbarFrame() << endl;
  os << indent << "StatusFrame: " << this->GetStatusFrame() << endl;
  os << indent << "ViewFrame: " << this->GetViewFrame() << endl;
  os << indent << "WindowClass: " << this->GetWindowClass() << endl;  
  os << indent << "TclInteractor: " << this->GetTclInteractor() << endl;
  os << indent << "Title: " 
     << ( this->GetTitle() ? this->GetTitle() : "(none)" ) << endl;  
  os << indent << "Toolbars: " << this->GetToolbars() << endl;
}


