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

#include "vtkArrayCalculator.h"
#include "vtkDataArray.h"
#include "vtkDataSet.h"
#include "vtkLineSource.h"
#include "vtkNew.h"
#include "vtkPointData.h"
#include "vtkProbeFilter.h"

// Gets the number of points the probe filter counted as valid.
// The parameter should be the output of the probe filter
int GetNumberOfValidPoints(vtkDataSet* pd)
{
  vtkDataArray* data = pd->GetPointData()->GetScalars("vtkValidPointMask");
  int numValid = 0;
  for (int i = 0; i < data->GetNumberOfTuples(); ++i)
  {
    if (data->GetVariantValue(i).ToDouble() == 1)
    {
      ++numValid;
    }
  }
  return numValid;
}

// Tests the CompteThreshold and Threshold parameters on the vtkProbeFilter
int TestProbeFilterThreshold()
{
  vtkNew<vtkLineSource> line1;
  line1->SetPoint1(-1, 0, 0);
  line1->SetPoint2(10, 0, 0);
  line1->SetResolution(11);

  vtkNew<vtkLineSource> line2;
  line2->SetPoint1(-0.499962, -0.00872654, 0);
  line2->SetPoint2(10.4996, 0.0872654, 0);
  line2->SetResolution(11);

  vtkNew<vtkArrayCalculator> calc;
  calc->SetInputConnection(line1->GetOutputPort());
  calc->AddCoordinateScalarVariable("coordsX");
  calc->SetFunction("sin(coordsX)");

  vtkNew<vtkProbeFilter> probe;
  probe->SetInputConnection(calc->GetOutputPort());
  probe->SetSourceConnection(line2->GetOutputPort());
  probe->Update();

  int validDefault = GetNumberOfValidPoints(probe->GetOutput());
  if (validDefault != 2)
  {
    return 1;
  }
  // turn off computing tolerance and set it to 11 times what is was.
  // 11 is magic number to get all the points within line1 selected.
  probe->SetComputeTolerance(false);
  probe->SetTolerance(11 * probe->GetTolerance());
  probe->Update();

  int validNext = GetNumberOfValidPoints(probe->GetOutput());

  if (validNext != 11)
  {
    return 1;
  }
  // threshold is still set high, but we tell it to ignore it
  probe->SetComputeTolerance(true);
  probe->Update();

  int validIgnore = GetNumberOfValidPoints(probe->GetOutput());
  return (validIgnore == 2) ? 0 : 1;
}

// Currently only tests the ComputeThreshold and Threshold.  Other tests
// should be added
int TestProbeFilter(int, char*[])
{
  return TestProbeFilterThreshold();
}
