#include "vtkMRIBiasPoly.h"

#include "vtkObjectFactory.h"
#include "vtkXMLImageDataReader.h"
#include "vtkKWApplication.h"
#include "vtkKWWindow.h"

#include "vtkKWWidgetsPaths.h"
#include "vtkToolkits.h"

#include <vtksys/SystemTools.hxx>
#include <vtksys/CommandLineArguments.hxx>

#include "vtkKWWindow.h"
#include "vtkXMLImageDataReader.h"
#include "vtkCornerAnnotation.h"
#include "vtkImageData.h"
#include "vtkImageViewer2.h"
#include "vtkKWApplication.h"
#include "vtkKWFrame.h"
#include "vtkKWFrameWithLabel.h"
#include "vtkKWMenu.h"
#include "vtkKWMenuButton.h"
#include "vtkKWMenuButtonWithSpinButtons.h"
#include "vtkKWMenuButtonWithSpinButtonsWithLabel.h"
#include "vtkKWNotebook.h"
#include "vtkKWRenderWidget.h"
#include "vtkKWScale.h"
#include "vtkKWWindowLevelPresetSelector.h"
#include "vtkKWWidgetSet.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
//#include "vtkMRIBiasPolySliceView.h"

//----------------------------------------------------------------------------
vtkStandardNewMacro( vtkMRIBiasPoly );
vtkCxxRevisionMacro(vtkMRIBiasPoly, "$Revision: 1.5 $");


//----------------------------------------------------------------------------
int vtkMRIBiasPoly::Run(int argc, char *argv[])
{
  // Process some command-line arguments
  // The --test option here is used to run this example as a non-interactive 
  // test for software quality purposes. You can ignore it.

  int option_test = 0;
  vtksys::CommandLineArguments args;
  args.Initialize(argc, argv);
  args.AddArgument(
                   "--test", vtksys::CommandLineArguments::NO_ARGUMENT, &option_test, "");
  args.Parse();
  
  // Create the application
  // If --test was provided, ignore all registry settings, and exit silently
  // Restore the settings that have been saved to the registry, like
  // the geometry of the user interface so far.

  vtkKWApplication *app = this->GetApplication();
  app->SetName("MRIBiasPoly");
  if (option_test)
    {
    app->SetRegistryLevel(0);
    app->PromptBeforeExitOff();
    }
  app->RestoreApplicationSettingsFromRegistry();

  // Set a help link. Can be a remote link (URL), or a local file

  app->SetHelpDialogStartingPage("http://www.kwwidgets.org");

  // Add a window
  // Set 'SupportHelp' to automatically add a menu entry for the help link

  vtkKWWindow *win = vtkKWWindow::New();
  win->SupportHelpOn();
  app->AddWindow(win);
  win->Create();
  win->SecondaryPanelVisibilityOff();

  // Create a volume reader

  vtkXMLImageDataReader *reader = vtkXMLImageDataReader::New();
  
  char data_path[2048];
  sprintf(data_path, "%s/Data/head100x100x47.vti", KWWidgets_EXAMPLES_DIR);
  if (!vtksys::SystemTools::FileExists(data_path))
    {
    sprintf(data_path, 
            "%s/..%s/Examples/Data/head100x100x47.vti",
            app->GetInstallationDirectory(), KWWidgets_INSTALL_DATA_DIR);
    }
  reader->SetFileName(data_path);
  reader->Update();

  for(unsigned i = 0; i < 2; i++)
    {
    for(unsigned j = 0; j < 3; j++)
      {
      // Add a render widget, attach it to the view frame, and pack
  
      this->RenderWidget[i][j] = vtkKWRenderWidget::New();
      this->RenderWidget[i][j]->SetParent(win->GetViewFrame());
      this->RenderWidget[i][j]->Create();
      this->RenderWidget[i][j]->CornerAnnotationVisibilityOn();
      this->RenderWidget[i][j]->ResetCamera();

      //       app->Script("pack %s -expand y -fill both -anchor c -expand y", 
      //                   this->RenderWidget[i][j]->GetWidgetName());
      char buf[512];
      sprintf(buf,"grid %s -row %d -column %d -sticky news",
              this->RenderWidget[i][j]->GetWidgetName(),i,j);
      app->Script(buf);
      // Create an image viewer
      // Use the render window and renderer of the renderwidget

      this->ImageViewer[i][j] = vtkImageViewer2::New();
      this->ImageViewer[i][j]->SetRenderWindow(this->RenderWidget[i][j]->GetRenderWindow());
      this->ImageViewer[i][j]->SetRenderer(this->RenderWidget[i][j]->GetRenderer());
      this->ImageViewer[i][j]->SetInput(reader->GetOutput());
      this->ImageViewer[i][j]->SetupInteractor
        (this->RenderWidget[i][j]->GetRenderWindow()->GetInteractor());
      this->ImageViewer[i][j]->SetInput(reader->GetOutput());
      switch(j)
        {
        case 0:
          this->ImageViewer[i][j]->SetSliceOrientationToXY();
          break;
        case 1:
          this->ImageViewer[i][j]->SetSliceOrientationToXZ();
          break;
        case 2:
          this->ImageViewer[i][j]->SetSliceOrientationToYZ();
          break;
        }
      double *range = reader->GetOutput()->GetScalarRange();
      this->ImageViewer[i][j]->SetColorWindow(range[1] - range[0]);
      this->ImageViewer[i][j]->SetColorLevel(0.5 * (range[1] + range[0]));
      // The corner annotation has the ability to parse "tags" and fill
      // them with information gathered from other objects.
      // For example, let's display the slice and window/level in one corner
      // by connecting the corner annotation to our image actor and
      // image mapper

      vtkCornerAnnotation *ca = this->RenderWidget[i][j]->GetCornerAnnotation();
      ca->SetImageActor(this->ImageViewer[i][j]->GetImageActor());
      ca->SetWindowLevel(this->ImageViewer[i][j]->GetWindowLevel());
      ca->SetText(2, "<slice>");
      ca->SetText(3, "<window>\n<level>");
      }
    }
#define SCALEW
#ifdef SCALEW
  for(unsigned i = 0; i < 3; i++)
    {
    char buf[512];
    this->SliceScale[i] = vtkKWScale::New();
    this->SliceScale[i]->SetParent(win->GetViewPanelFrame());
    this->SliceScale[i]->Create();
    this->SliceScale[i]->SetRange(this->ImageViewer[0][i]->GetSliceMin(),
                                  this->ImageViewer[0][i]->GetSliceMax());
    this->SliceScale[i]->SetValue(this->ImageViewer[0][i]->GetSlice());
    sprintf(buf,"SetSliceFromScaleCallback%d",i);
    this->SliceScale[i]->SetCommand(this,buf);

    sprintf(buf,"grid %s -row 2 -column %d -sticky news",
            this->SliceScale[i]->GetWidgetName(),i);
    app->Script(buf);
    }
#endif
  const char *frameName = win->GetViewFrame()->GetWidgetName();
  app->Script("grid columnconfigure %s 0 -weight 1",frameName);
  app->Script("grid columnconfigure %s 1 -weight 1",frameName);
  app->Script("grid columnconfigure %s 2 -weight 1",frameName);

  app->Script("grid rowconfigure %s 0 -weight 1",frameName);
  app->Script("grid rowconfigure %s 1 -weight 1",frameName);
#ifdef SCALEW
  app->Script("grid rowconfigure %s 2 -weight 0",frameName);
#endif  
  //   vtkMRIBiasPolySliceView *sliceView = vtkMRIBiasPolySliceView::New();
  //   sliceView->Init(app,win,reader);
  //   //sliceView->Create();
  //   sliceView->UpdateSliceRanges();
  //   app->Script("pack -expand y -fill both -anchor c %s",
  //               sliceView->GetWidgetName());
  // Start the application
  // If --test was provided, do not enter the event loop and run this example
  // as a non-interactive test for software quality purposes.

  int ret = 0;
  win->Display();
  if (!option_test)
    {
    app->Start(argc, argv);
    ret = app->GetExitStatus();
    }
  win->Close();

  // Deallocate and exit

  reader->Delete();
  //  wl_frame->Delete();
  //sliceView->Delete();
  //  animation_frame->Delete();
  //  this->AnimationWidget->Delete();
  win->Delete();

  return ret;
}

//----------------------------------------------------------------------------
void vtkMRIBiasPoly::SetSliceFromScaleCallback0(double value)
{
  this->ImageViewer[0][0]->SetSlice((int)value);
  this->ImageViewer[1][0]->SetSlice((int)value);
}
//----------------------------------------------------------------------------
void vtkMRIBiasPoly::SetSliceFromScaleCallback1(double value)
{
  this->ImageViewer[0][1]->SetSlice((int)value);
  this->ImageViewer[1][1]->SetSlice((int)value);
}
//----------------------------------------------------------------------------
void vtkMRIBiasPoly::SetSliceFromScaleCallback2(double value)
{
  this->ImageViewer[0][2]->SetSlice((int)value);
  this->ImageViewer[1][2]->SetSlice((int)value);
}
