//  Copyright (c) Kitware, Inc.  See license.md for details.

#include "vtkVolumeInspectionRepresentation.h"
#include "vtkVolumeInspectionWidget.h"

#include "vtkDataSetReader.h"
#include "vtkExtractCells.h"
#include "vtkImageData.h"
#include "vtkImageMandelbrotSource.h"
#include "vtkMatrix3x3.h"
#include "vtkNew.h"
#include "vtkOutlineFilter.h"
#include "vtkPolyDataMapper.h"
#include "vtkPolyDataWriter.h"
#include "vtkProperty.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkUnstructuredGrid.h"
#include "vtkUnstructuredGridWriter.h"

int TestVolumeInspector(int argc, char* argv[])
{
  (void)argc;
  (void)argv;

  int status = 0;

  vtkNew<vtkImageMandelbrotSource> ms;
  vtkNew<vtkOutlineFilter> of;
  vtkNew<vtkPolyDataMapper> om;
  vtkNew<vtkActor> oa;

  vtkNew<vtkVolumeInspectionRepresentation> vr;
  vtkNew<vtkVolumeInspectionWidget> vw;
  vtkNew<vtkRenderWindow> rw;
  vtkNew<vtkRenderer> rr;

  ms->SetWholeExtent(0, 63, 0, 63, 0, 63);
  ms->Update();

  of->SetInputConnection(ms->GetOutputPort());
  of->Update();
  std::array<double, 6> ob;
  of->GetOutput()->GetBounds(ob.data());
  std::cout << "points: " << of->GetOutput()->GetNumberOfPoints() << "\n";
  std::cout << "lines:  " << of->GetOutput()->GetNumberOfCells() << "\n";
  std::cout << "bounds: "
            << "(" << ob[0] << ", " << ob[2] << ", " << ob[4] << ") --"
            << "(" << ob[1] << ", " << ob[3] << ", " << ob[5] << ")"
            << " " << of->GetOutput()->GetClassName() << "\n";

  vtkNew<vtkPolyDataWriter> wr;
  wr->SetInputConnection(of->GetOutputPort());
  wr->SetFileName("/tmp/outline.vtk");
  wr->Write();

  om->SetInputConnection(of->GetOutputPort());
  oa->SetMapper(om);
  oa->GetProperty()->SetLineWidth(4);
  oa->GetProperty()->RenderLinesAsTubesOn();
  oa->GetProperty()->SetEdgeVisibility(1);
  oa->GetProperty()->SetEdgeColor(0, 1, 0);

  rw->SetMultiSamples(0);
  rw->AddRenderer(rr);
  rr->SetBackground(1., 0., 1.);
  rr->AddActor(oa);
  auto* ri = rw->MakeRenderWindowInteractor();
  rw->SetInteractor(ri);
  ri->SetRenderWindow(rw);
  rw->SetSize(600, 300);
  ri->Initialize();

  rr->ResetCamera();
  rr->ResetCameraClippingRange();
  rw->Render();

  std::array<double, 6> bds;
  std::array<double, 3> ctr;
  ms->GetOutput()->GetBounds(bds.data());
  for (int ii = 0; ii < 3; ++ii)
  {
    ctr[ii] = bds[2 * ii + 1] - bds[2 * ii];
    std::cout << "  " << bds[2 * ii] << " -- " << bds[2 * ii + 1] << "\n";
  }
  vtkNew<vtkMatrix3x3> tmat;
  double matdata[9] = { 0, 0, -1, 1, 0, 0, 0, -1, 0 };
  tmat->DeepCopy(matdata);
  vtkNew<vtkImageData> imagedata;
  imagedata->ShallowCopy(ms->GetOutput());
  imagedata->SetDirectionMatrix(tmat);
  // vr->SetInputData(ms->GetOutput());
  vr->SetInputData(imagedata);
  // vr->SetOrigin(ctr.data());
  // vr->PlaceWidget(bds.data());
  vr->SetSlice(5, 10, 15, false);
  vw->SetRepresentation(vr);
  vw->SetInteractor(ri);
  vw->EnabledOn();

  ri->Start();

  return status;
}
