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

// .NAME
// .SECTION Description
// this program tests the vtkSelection::Subtract method

#include "vtkIdTypeArray.h"
#include "vtkIndent.h"
#include "vtkSelection.h"
#include "vtkSelectionNode.h"
#include "vtkSmartPointer.h"

#include <iostream>

#define VTK_CREATE(type, name) vtkSmartPointer<type> name = vtkSmartPointer<type>::New()

#define DEBUG 0

#if DEBUG
// ------------------------------------------------------------------------------------------------
static void PrintSelectionNodes(vtkSmartPointer<vtkSelection>& sel, const char* tag = nullptr)
{
  vtkIdType numNodes = sel->GetNumberOfNodes();

  if (tag)
  {
    cout << tag << endl;
  }

  for (int iNode = 0; iNode < numNodes; iNode++)
  {
    if (tag)
      cout << "\t";
    cout << "Node: " << iNode << endl;
    vtkIdType listSize = sel->GetNode(iNode)->GetSelectionList()->GetNumberOfTuples();
    for (int iVal = 0; iVal < listSize; iVal++)
    {
      if (tag)
        cout << "\t";
      cout << "\t" << iVal << "\t" << sel->GetNode(iNode)->GetSelectionList()->GetVariantValue(iVal)
           << endl;
    }
  }
}
#endif

// ------------------------------------------------------------------------------------------------
int TestSelectionSubtract(int, char*[])
{
  // Create a selection, sel1, of PEDIGREEIDS containing {1, 2, 3}
  VTK_CREATE(vtkSelection, sel1);
  VTK_CREATE(vtkSelectionNode, sel1Node);
  VTK_CREATE(vtkIdTypeArray, sel1Arr);
  sel1->AddNode(sel1Node);
  sel1Node->SetContentType(vtkSelectionNode::PEDIGREEIDS);
  sel1Node->SetFieldType(vtkSelectionNode::VERTEX);
  sel1Node->SetSelectionList(sel1Arr);
  sel1Arr->InsertNextValue(1);
  sel1Arr->InsertNextValue(2);
  sel1Arr->InsertNextValue(3);

  // Create a selection, sel2, of PEDIGREEIDS containing {2, 3}
  VTK_CREATE(vtkSelection, sel2);
  VTK_CREATE(vtkSelectionNode, sel2Node);
  VTK_CREATE(vtkIdTypeArray, sel2Arr);
  sel2->AddNode(sel2Node);
  sel2Node->SetContentType(vtkSelectionNode::PEDIGREEIDS);
  sel2Node->SetFieldType(vtkSelectionNode::VERTEX);
  sel2Node->SetSelectionList(sel2Arr);
  sel2Arr->InsertNextValue(3);
  sel2Arr->InsertNextValue(1);

  // debugging
#if DEBUG
  PrintSelectionNodes(sel1, "sel1");
  PrintSelectionNodes(sel2, "sel2");
#endif

  // Subtract sel2 from sel1
#if DEBUG
  cout << endl << "Subtract sel2 from sel1 ..." << endl << endl;
#endif
  sel1->Subtract(sel2);

  // debugging
#if DEBUG
  PrintSelectionNodes(sel1, "sel1");
#endif

  // Correctness check.
  bool failed = false;
  cout << "Check # of nodes == 1 ....... ";
  if (sel1->GetNumberOfNodes() != 1)
  {
    cout << "FAILED" << endl;
    failed = true;
  }
  else
  {
    cout << "OK" << endl;
  }

  cout << "Check # of tuples == 1 ...... ";
  if (sel1->GetNode(0)->GetSelectionList()->GetNumberOfTuples() != 1)
  {
    cout << "FAILED" << endl;
    failed = true;
  }
  else
  {
    cout << "OK" << endl;
  }

  cout << "Check selection value is 2 .. ";
  if (sel1->GetNode(0)->GetSelectionList()->GetVariantValue(0) != 2)
  {
    cout << "FAILED" << endl;
    failed = true;
  }
  else
  {
    cout << "OK" << endl;
  }

  return failed ? EXIT_FAILURE : EXIT_SUCCESS;
}
