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

  Program:   ParaView
  Module:    vtkPythonObservableWrapperUtilities.h

  Copyright (c) Kitware, Inc.
  All rights reserved.
  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html 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   vtkPythonObservableWrapperUtilities
 * @brief   Utilities to extract a python future out a vtkPythonObservableWrapper<>
 *
 * @sa vtkPythonObservableWrapper
 */

#ifndef vtkPythonObservableWrapperUtilities_h
#define vtkPythonObservableWrapperUtilities_h

#include "vtkPython.h" // include first

#include "vtkRemotingPythonAsyncCoreModule.h" //needed for exports

#include "vtkPythonObservableWrapper.h"
#include "vtkSmartPointer.h"

#define VTK_REMOTING_PYTHON_ASYNC_CORE_DEFINE_GET_FUTURE(objectType)                               \
  static PyObject* GetFuture(vtkPythonObservableWrapper<objectType> wrapper)                       \
  {                                                                                                \
    return GetFutureInternal(wrapper);                                                             \
  }

#define VTK_REMOTING_PYTHON_ASYNC_CORE_DEFINE_GET_ITERATOR(objectType)                             \
  static PyObject* GetIterator(vtkPythonObservableWrapper<objectType> wrapper)                     \
  {                                                                                                \
    return GetIteratorInternal(wrapper);                                                           \
  }

class VTKREMOTINGPYTHONASYNCCORE_EXPORT vtkPythonObservableWrapperUtilities
{
public:
  // Note: we need to explicitly instantiate  the different GetFuture functions
  // here so they are visible to the `vtkWrappingTools` infrastructure.

  VTK_REMOTING_PYTHON_ASYNC_CORE_DEFINE_GET_FUTURE(vtkObject*);
  VTK_REMOTING_PYTHON_ASYNC_CORE_DEFINE_GET_FUTURE(vtkSmartPointer<vtkObject>);
  VTK_REMOTING_PYTHON_ASYNC_CORE_DEFINE_GET_FUTURE(bool);
  VTK_REMOTING_PYTHON_ASYNC_CORE_DEFINE_GET_FUTURE(long);
  VTK_REMOTING_PYTHON_ASYNC_CORE_DEFINE_GET_FUTURE(vtkTypeUInt32);

  VTK_REMOTING_PYTHON_ASYNC_CORE_DEFINE_GET_ITERATOR(vtkSmartPointer<vtkObject>);
  VTK_REMOTING_PYTHON_ASYNC_CORE_DEFINE_GET_ITERATOR(long);
  VTK_REMOTING_PYTHON_ASYNC_CORE_DEFINE_GET_ITERATOR(std::vector<vtkSmartPointer<vtkObject>>);

  template <typename T>
  static PyObject* GetFutureInternal(vtkPythonObservableWrapper<T> wrapper);

  template <typename T>
  static PyObject* GetIteratorInternal(vtkPythonObservableWrapper<T> wrapper);
};

#ifndef __WRAP__
#include "vtkPythonObservableWrapperUtilities.txx" // for template implementations
#endif

#undef VTK_REMOTING_PYTHON_ASYNC_CORE_DEFINE_GET_FUTURE
#undef VTK_REMOTING_PYTHON_ASYNC_CORE_DEFINE_GET_ITERATOR

#endif
