// SPDX-FileCopyrightText: Copyright (c) Kitware Inc.
// SPDX-License-Identifier: BSD-3-Clause
/**
 * @class vtkBlockDeliveryPreprocessor
 * @brief prepares data for certain table-based representations
 *
 * Despite its name, vtkBlockDeliveryPreprocessor is simply a filter that
 * prepares an input data for certain representations that work with tables
 * alone e.g. vtkSpreadSheetView, vtkChartRepresentation. Using
 * vtkAttributeDataToTableFilter this convert any input data to a vtkTable (or
 * composite of vtkTables). If FlattenTable, it uses `vtkSplitColumnComponents`
 * to split multicomponent arrays into single component arrays with special
 * names.
 *
 * When dealing with composite datasets, it uses `vtkExtractBlock` to pass only
 * the selected blocks.
 */

#ifndef vtkBlockDeliveryPreprocessor_h
#define vtkBlockDeliveryPreprocessor_h

#include "vtkDataObjectAlgorithm.h"
#include "vtkPVVTKExtensionsFiltersRenderingModule.h" // needed for export macro
#include "vtkSplitColumnComponents.h"                 //  needed for enum

class VTKPVVTKEXTENSIONSFILTERSRENDERING_EXPORT vtkBlockDeliveryPreprocessor
  : public vtkDataObjectAlgorithm
{
public:
  static vtkBlockDeliveryPreprocessor* New();
  vtkTypeMacro(vtkBlockDeliveryPreprocessor, vtkDataObjectAlgorithm);
  void PrintSelf(ostream& os, vtkIndent indent) override;

  ///@{
  /**
   * In case of Composite datasets, set the flat index of the subtree to pass.
   * Default or empty results in passing the entire composite tree.
   */
  void AddCompositeDataSetIndex(unsigned int index);
  void RemoveAllCompositeDataSetIndices();
  ///@}

  ///@{
  /**
   * Allow user to enable/disable cell connectivity generation in the datamodel
   */
  vtkSetMacro(GenerateCellConnectivity, bool);
  vtkGetMacro(GenerateCellConnectivity, bool);
  ///@}

  ///@{
  /**
   * Select the attribute type. Accepted values are
   * \li vtkDataObject::FIELD_ASSOCIATION_POINTS,
   * \li vtkDataObject::FIELD_ASSOCIATION_CELLS,
   * \li vtkDataObject::FIELD_ASSOCIATION_NONE,
   * \li vtkDataObject::FIELD_ASSOCIATION_VERTICES,
   * \li vtkDataObject::FIELD_ASSOCIATION_EDGES,
   * \li vtkDataObject::FIELD_ASSOCIATION_ROWS
   * If value is vtkDataObject::FIELD_ASSOCIATION_NONE, then FieldData
   * associated with the input dataobject is extracted.
   */
  vtkSetMacro(FieldAssociation, int);
  vtkGetMacro(FieldAssociation, int);
  ///@}

  ///@{
  /**
   * Flatten the table, i.e. split any multicomponent columns into separate
   * components, internally the vtkSplitColumnComponents filter is used.
   */
  vtkSetMacro(FlattenTable, int);
  vtkGetMacro(FlattenTable, int);
  ///@}

  ///@{
  /**
   * Corresponds to `vtkSplitColumnComponents::NamingMode`. Pick which mode to
   * use to name arrays when `FlattenTable` is true. Default is
   * `vtkSplitColumnComponents::NAMES_WITH_UNDERSCORES`.
   */
  vtkSetClampMacro(SplitComponentsNamingMode, int, vtkSplitColumnComponents::NUMBERS_WITH_PARENS,
    vtkSplitColumnComponents::NAMES_WITH_UNDERSCORES);
  vtkGetMacro(SplitComponentsNamingMode, int);
  ///@}

  ///@{
  /**
   * When set (default) the vtkOriginalIndices array will be added to the
   * output. Can be overridden by setting this flag to 0.
   * This is only respected when AddMetaData is true.
   */
  vtkSetMacro(GenerateOriginalIds, bool);
  vtkGetMacro(GenerateOriginalIds, bool);
  ///@}

protected:
  vtkBlockDeliveryPreprocessor();
  ~vtkBlockDeliveryPreprocessor() override;

  /**
   * This is called by the superclass.
   * This is the method you should override.
   */
  int RequestDataObject(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;

  int RequestData(vtkInformation*, vtkInformationVector**, vtkInformationVector*) override;

  int FieldAssociation;
  int FlattenTable;
  bool GenerateOriginalIds;
  bool GenerateCellConnectivity;
  int SplitComponentsNamingMode;

private:
  vtkBlockDeliveryPreprocessor(const vtkBlockDeliveryPreprocessor&) = delete;
  void operator=(const vtkBlockDeliveryPreprocessor&) = delete;

  class CompositeDataSetIndicesType;
  CompositeDataSetIndicesType* CompositeDataSetIndices;
};

#endif
