#include <vtkm/io/reader/VTKDataSetReader.h>

#include <vtkm/rendering/Actor.h>
#include <vtkm/rendering/Camera.h>
#include <vtkm/rendering/CanvasRayTracer.h>
#include <vtkm/rendering/MapperRayTracer.h>
#include <vtkm/rendering/View3D.h>

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

namespace {

void DoBasicRender()
{
  // Load some data to render
  vtkm::cont::DataSet surfaceData;
  try
  {
    vtkm::io::reader::VTKDataSetReader reader("data/cow.vtk");
    surfaceData = reader.ReadDataSet();
  }
  catch (vtkm::io::ErrorIO &error)
  {
    std::cout << "Could not read file:" << std::endl
              << error.GetMessage() << std::endl;
    exit(1);
  }
  catch (...)
  {
    throw;
  }

  // Initialize VTK-m rendering classes
  ////
  //// BEGIN-EXAMPLE ConstructView.cxx
  ////
  ////
  //// BEGIN-EXAMPLE ActorScene.cxx
  ////
  vtkm::rendering::Actor actor(surfaceData.GetCellSet(),
                               surfaceData.GetCoordinateSystem(),
                               surfaceData.GetField("RandomPointScalars"));

  vtkm::rendering::Scene scene;
  scene.AddActor(actor);
  ////
  //// END-EXAMPLE ActorScene.cxx
  ////

  vtkm::rendering::MapperRayTracer mapper;
  ////
  //// BEGIN-EXAMPLE Canvas.cxx
  ////
  vtkm::rendering::CanvasRayTracer canvas(1920, 1080);
  ////
  //// END-EXAMPLE Canvas.cxx
  ////

  vtkm::rendering::View3D view(scene, mapper, canvas);
  view.Initialize();
  ////
  //// END-EXAMPLE ConstructView.cxx
  ////

  ////
  //// BEGIN-EXAMPLE ViewColors.cxx
  ////
  view.SetBackgroundColor(vtkm::rendering::Color(1.0f, 1.0f, 1.0f));
  view.SetForegroundColor(vtkm::rendering::Color(0.0f, 0.0f, 0.0f));
  ////
  //// END-EXAMPLE ViewColors.cxx
  ////

  ////
  //// BEGIN-EXAMPLE PaintView.cxx
  ////
  view.Paint();
  ////
  //// END-EXAMPLE PaintView.cxx
  ////

  ////
  //// BEGIN-EXAMPLE SaveView.cxx
  ////
  view.SaveAs("BasicRendering.ppm");
  ////
  //// END-EXAMPLE SaveView.cxx
  ////
}

void DoRender()
{
  DoBasicRender();
}

} // anonymous namespace

int Rendering(int, char*[])
{
  return vtkm::cont::testing::Testing::Run(DoRender);
}
