#include <vtkm/worklet/WorkletMapField.h>

#include <vtkm/cont/Invoker.h>

#include <vtkm/cont/testing/Testing.h>

namespace
{

constexpr vtkm::Id ARRAY_SIZE = 10;

////
//// BEGIN-EXAMPLE SimpleWorklet.cxx
////
//// LABEL Inherit
struct PoundsPerSquareInchToNewtonsPerSquareMeter : vtkm::worklet::WorkletMapField
{
  //// LABEL ControlSignature
  //// BEGIN-EXAMPLE ControlSignature.cxx
  using ControlSignature = void(FieldIn psi, FieldOut nsm);
  //// END-EXAMPLE ControlSignature.cxx
  //// LABEL ExecutionSignature
  //// BEGIN-EXAMPLE ExecutionSignature.cxx
  using ExecutionSignature = void(_1, _2);
  //// END-EXAMPLE ExecutionSignature.cxx
  //// LABEL InputDomain
  //// BEGIN-EXAMPLE InputDomain.cxx
  using InputDomain = _1;
  //// END-EXAMPLE InputDomain.cxx

  //// LABEL OperatorStart
  //// BEGIN-EXAMPLE WorkletOperator.cxx
  template<typename T>
  VTKM_EXEC void operator()(const T& psi, T& nsm) const
  {
    //// END-EXAMPLE WorkletOperator.cxx
    // 1 psi = 6894.76 N/m^2
    nsm = T(6894.76) * psi;
    //// LABEL OperatorEnd
  }
};
////
//// END-EXAMPLE SimpleWorklet.cxx
////

void DemoWorklet()
{
  ////
  //// BEGIN-EXAMPLE WorkletInvoke.cxx
  ////
  vtkm::cont::ArrayHandle<vtkm::FloatDefault> psiArray;
  // Fill psiArray with values...
  //// PAUSE-EXAMPLE
  psiArray.Allocate(ARRAY_SIZE);
  SetPortal(psiArray.GetPortalControl());
  //// RESUME-EXAMPLE

  //// LABEL Construct
  vtkm::cont::Invoker invoke;

  vtkm::cont::ArrayHandle<vtkm::FloatDefault> nsmArray;
  //// LABEL Call
  invoke(PoundsPerSquareInchToNewtonsPerSquareMeter{}, psiArray, nsmArray);
  ////
  //// END-EXAMPLE WorkletInvoke.cxx
  ////
}

void Run()
{
  DemoWorklet();
}

} // anonymous namespace

int SimpleAlgorithm(int argc, char* argv[])
{
  return vtkm::cont::testing::Testing::Run(Run, argc, argv);
}
