// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
// SPDX-License-Identifier: BSD-3-Clause

#include "vtkResampleWithDataSet.h"

#include "vtkActor.h"
#include "vtkArrayCalculator.h"
#include "vtkCamera.h"
#include "vtkCellData.h"
#include "vtkContourFilter.h"
#include "vtkDataSet.h"
#include "vtkExodusIIReader.h"
#include "vtkImageData.h"
#include "vtkPointData.h"
#include "vtkPolyDataMapper.h"
#include "vtkRegressionTestImage.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkTestUtilities.h"

enum
{
  TEST_PASSED_RETVAL = 0,
  TEST_FAILED_RETVAL = 1
};

int TestResampleWithDataSet2(int argc, char* argv[])
{
  vtkNew<vtkExodusIIReader> reader;
  char* fname = vtkTestUtilities::ExpandDataFileName(argc, argv, "Data/can.ex2");
  reader->SetFileName(fname);
  delete[] fname;

  reader->UpdateInformation();
  reader->SetObjectArrayStatus(vtkExodusIIReader::NODAL, "VEL", 1);
  reader->Update();

  // based on can.ex2 bounds
  double origin[3] = { -7.8, -1.0, -15 };
  double spacing[3] = { 0.127, 0.072, 0.084 };
  int dims[3] = { 128, 128, 128 };

  vtkNew<vtkImageData> input;
  input->SetExtent(0, dims[0] - 1, 0, dims[1] - 1, 0, dims[2] - 1);
  input->SetOrigin(origin);
  input->SetSpacing(spacing);

  vtkNew<vtkResampleWithDataSet> resample;
  resample->SetInputData(input);
  resample->SetSourceConnection(reader->GetOutputPort());
  resample->UpdateTimeStep(0.00199999);

  auto result = vtkImageData::SafeDownCast(resample->GetOutput());
  // remove ghost array since we want to preserve the ghosts
  result->GetCellData()->RemoveArray(vtkDataSetAttributes::GhostArrayName());
  result->GetPointData()->RemoveArray(vtkDataSetAttributes::GhostArrayName());

  // Render
  vtkNew<vtkContourFilter> toPoly;
  toPoly->SetInputData(result);
  toPoly->SetInputArrayToProcess(
    0, 0, 0, vtkDataObject::FIELD_ASSOCIATION_POINTS, "vtkValidPointMask");
  toPoly->SetValue(0, 0.5);

  vtkNew<vtkArrayCalculator> calculator;
  calculator->SetInputConnection(toPoly->GetOutputPort());
  calculator->AddVectorArrayName("VEL");
  calculator->SetFunction("mag(VEL)");
  calculator->SetResultArrayName("VEL_MAG");
  calculator->Update();

  double range[2];
  vtkDataSet::SafeDownCast(calculator->GetOutput())
    ->GetPointData()
    ->GetArray("VEL_MAG")
    ->GetRange(range);

  vtkNew<vtkPolyDataMapper> mapper;
  mapper->SetInputConnection(calculator->GetOutputPort());
  mapper->SetScalarRange(range);

  vtkNew<vtkActor> actor;
  actor->SetMapper(mapper);

  vtkNew<vtkRenderer> renderer;
  renderer->AddActor(actor);
  renderer->GetActiveCamera()->SetPosition(0.0, -1.0, 0.0);
  renderer->GetActiveCamera()->SetViewUp(0.0, 0.0, 1.0);
  renderer->ResetCamera();

  vtkNew<vtkRenderWindow> renWin;
  renWin->AddRenderer(renderer);

  vtkNew<vtkRenderWindowInteractor> iren;
  iren->SetRenderWindow(renWin);
  iren->Initialize();

  renWin->Render();

  int retVal = vtkRegressionTestImage(renWin);
  if (retVal == vtkRegressionTester::DO_INTERACTOR)
  {
    iren->Start();
  }

  return !retVal;
}
