
// #include <vtkm/cont/DataSet.h>
 #include <vtkm/io/reader/VTKDataSetReader.h>
// #include <vtkm/io/writer/VTKDataSetWriter.h>
// #include <vtkm/cont/Initialize.h>
 #include <vtkm/filter/FBSampling.h>

#include <vector>
#include <vtkm/cont/DataSet.h>
//#include <vtkm/worklet/NDimsHistogram.h>

#include <vtkm/filter/Gradient.h>
#include <vtkm/filter/VectorMagnitude.h>
//#include <vtkm/io/writer/VTKDataSetWriter.h>
#include <vtkm/cont/Initialize.h>
#include <vtkm/filter/NDHistogram.h>

#include <vtkm/worklet/NDimsHistMarginalization.h>
#include <vtkm/worklet/FieldHistogram.h>
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>


typedef vtkm::Float64 CURRENT_DTYPE;

std::vector<std::string> readFileToVector(const std::string& filename)
{
    std::ifstream source;
    source.open(filename);
    std::vector<std::string> lines;
    std::string line;
    while (std::getline(source, line))
    {
        lines.push_back(line);
    }
    return lines;
}


int main(int argc, char *argv[])
{

  vtkm::cont::Initialize(argc, argv, vtkm::cont::InitializeOptions::None);

  
  std::string input_config_fname(argv[1]);
  std::vector<std::string> input_arg_vector = readFileToVector(input_config_fname);


  std::string input_fname = input_arg_vector[0];
  std::string output_fname = input_arg_vector[1];

  vtkm::Id fieldId = std::stoi(input_arg_vector[2]);
  vtkm::Id binCount = std::stoi(input_arg_vector[3]);
  vtkm::Float32 sample_percent = std::stoi(input_arg_vector[4])/100.0;

  vtkm::io::reader::VTKDataSetReader reader(input_fname);
  vtkm::cont::DataSet dataSet = reader.ReadDataSet();
 

  /// Using new vtkm filter
  vtkm::filter::FBSampling fb_sampler;

  fb_sampler.SetFieldId(fieldId);
  fb_sampler.SetBinCount(binCount);
  fb_sampler.SetSampleRate(sample_percent);

  vtkm::cont::DataSet sample_output = fb_sampler.Execute(dataSet);

  // verify the filter output
  std::cout << "new no. of fields [sample_output]=" << sample_output.GetNumberOfFields() << std::endl;
  std::cout << "field name = " << sample_output.GetField(0).GetName() << std::endl;
  std::cout << "No. of Coordinate Systems [sample_output] = " << sample_output.GetNumberOfCoordinateSystems() << std::endl;
  std::cout << "no. of values [sample_output]=" << sample_output.GetField(0).GetData().GetNumberOfValues() << std::endl;

  


  vtkm::cont::ArrayHandle <vtkm::Float64> sval;
  vtkm::cont::VariantArrayHandle sval_vah = sample_output.GetField(0).GetData();
  sval_vah.CopyTo(sval);
  auto port = sval.GetPortalConstControl();
  //// WRITE OUT THE STENCIL VECTOR FOR VISUALIZATION
  std::ofstream fout(output_fname.c_str());
  for(int i=0; i<sval.GetNumberOfValues(); i++)
  {  
    fout << port.Get(i) << '\n';
  }
  std::cout << "output writen to " << output_fname << std::endl;

}