#include <vtkm/cont/ColorTable.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/Initialize.h>
#include <vtkm/filter/Contour.h>
#include <vtkm/cont/Initialize.h>
#include <vtkm/source/Tangle.h>

#include <vtkm/io/reader/VTKDataSetReader.h>
#include <vtkm/io/writer/VTKDataSetWriter.h>
#include <vtkm/rendering/Actor.h>
#include <vtkm/rendering/Light.h>
#include <vtkm/rendering/CanvasRayTracer.h>
#include <vtkm/rendering/MapperRayTracer.h>
#include <vtkm/rendering/Scene.h>
#include <vtkm/rendering/View3D.h>

int main(int argc, char** argv)
{
  auto opts = vtkm::cont::InitializeOptions::DefaultAnyDevice;
  vtkm::cont::InitializeResult config = vtkm::cont::Initialize(argc, argv, opts);

  //Loading .vtk File
  vtkm::io::VTKDataSetReader reader("data/visityuh.vtk");
  vtkm::cont::DataSet ds_from_file = reader.ReadDataSet();
  ds_from_file.PrintSummary(std::cerr);

  //Cronstruct Scene
  vtkm::rendering::Scene scene;
  




  vtkm::rendering::Actor actor(ds_from_file.GetCellSet(),
                               ds_from_file.GetCoordinateSystem(),
                               ds_from_file.GetField("OBJVar1"));
  vtkm::cont::Field SecondaryField = ds_from_file.GetField("Normals"); 
  scene.AddActor(actor);

  //creating raytracer and adding normal field to it
  vtkm::rendering::MapperRayTracer mapper;
  mapper.SetRaytracerNormalField(SecondaryField);
  vtkm::rendering::CanvasRayTracer canvas(2048, 2048);

  //correct intialization of view3d to better conform to camera 
  vtkm::rendering::View3D view(scene, mapper, canvas);
  
  //this is just a test comment
  
  //get camera here
  vtkm::rendering::Camera &cam = view.GetCamera(); 
  //vtkm::Vec3f_32 lat(3.76, 4.1, 4.8); 
  vtkm::Vec3f_32 lat(3.5,0.0,0.0); 
  cam.SetLookAt(lat); 
  //vtkm::Vec3f_32 campos(3.0, 6.0, 8.0); 
  vtkm::Vec3f_32 campos(3.75, 7.25, 8.0); 
  cam.SetPosition(campos);
  cam.Print(); 

  //create light here
  vtkm::Vec3f_32 color(1.0, 1.0, 0.5);
  vtkm::Vec3f_32 color1(1.0, 0.5, 0.1);
  vtkm::Vec3f_32 color2(0.8, 0.8, 0.0);
  vtkm::rendering::Light light1((10.0, 10.0, 10.0), //light position
		                (0.0, 1.0, 0.0),    //light lookDir
				color,              //light color
				20.5f,               //light intensity
				false);             //light is directional

  vtkm::rendering::Light light2((-9.0, -9.0,-9.0), //light position
		                (0.0, 1.0, 0.0),    //light lookDir
				color1,             //light color
				30.5f,               //light intensity
				false);             //light is directional

  
  vtkm::rendering::Light light3(campos,             //light position
		                (0.0, 1.0, 0.0),    //light lookDir
				color2,             //light color
				5.5f,               //light intensity
				false);             //light is directional
  //scene.AddLight(light1);
  scene.AddLight(light2);
  scene.AddLight(light3);

  //Setting the background and foreground colors; optional.
  view.SetBackgroundColor(vtkm::rendering::Color(0.1f, 0.1f, 0.1f));
  view.SetForegroundColor(vtkm::rendering::Color(0.0f, 0.0f, 0.0f));

  //Painting View
  view.Paint();

  //Saving View
  view.SaveAs("PBR.ppm");

  return 0;
}
