/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkAMRInterpolatedVelocityField.h

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
/**
 * @class   vtkAMRInterpolatedVelocityField
 * @brief   A concrete class for obtaining
 *  the interpolated velocity values at a point in AMR data.
 *
 *
 *
 * The main functionality supported here is the point location inside vtkOverlappingAMR data set.
*/

#ifndef vtkAMRInterpolatedVelocityField_h
#define vtkAMRInterpolatedVelocityField_h

#include "vtkFiltersFlowPathsModule.h" // For export macro

#include "vtkAbstractInterpolatedVelocityField.h"

class vtkOverlappingAMR;

class VTKFILTERSFLOWPATHS_EXPORT vtkAMRInterpolatedVelocityField
  : public vtkAbstractInterpolatedVelocityField
{
public:
  vtkTypeMacro( vtkAMRInterpolatedVelocityField,
                vtkAbstractInterpolatedVelocityField );

  static vtkAMRInterpolatedVelocityField * New();

  vtkGetMacro(AmrDataSet,vtkOverlappingAMR*);
  void SetAMRData(vtkOverlappingAMR* amr);

  bool GetLastDataSetLocation(unsigned int& level, unsigned int& id);

  bool SetLastDataSet(int level, int id);

  void SetLastCellId( vtkIdType c, int dataindex ) override;

  /**
   * Set the cell id cached by the last evaluation.
   */
  void SetLastCellId( vtkIdType c ) override
    { this->Superclass::SetLastCellId( c ); }

  using Superclass::FunctionValues;
  /**
   * Evaluate the velocity field f at point p.
   * If it succeeds, then both the last data set (this->LastDataSet) and
   * the last data set location (this->LastLevel, this->LastId) will be
   * set according to where p is found.  If it fails, either p is out of
   * bound, in which case both the last data set and the last location
   * will be invalid or, in a multi-process setting, p is inbound but not
   * on the processor.  In the last case, the last data set location is
   * still valid
   */

  int FunctionValues( double * x, double * f ) override;

  void PrintSelf( ostream & os, vtkIndent indent ) override;

  // Descriptino:
  // Point location routine.
  static bool FindGrid(double q[3],vtkOverlappingAMR *amrds, unsigned int& level, unsigned int& gridId);

protected:
  vtkOverlappingAMR* AmrDataSet;
  int LastLevel;
  int LastId;

  vtkAMRInterpolatedVelocityField();
  ~vtkAMRInterpolatedVelocityField() override;
  int FunctionValues( vtkDataSet * ds, double * x, double * f ) override
    { return this->Superclass::FunctionValues( ds, x, f ); }

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

};

#endif
