//============================================================================
//  Copyright (c) Kitware, Inc.
//  All rights reserved.
//  See LICENSE.txt 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.
//
//  Copyright 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
//  Copyright 2015 UT-Battelle, LLC.
//  Copyright 2015 Los Alamos National Security.
//
//  Under the terms of Contract DE-NA0003525 with NTESS,
//  the U.S. Government retains certain rights in this software.
//
//  Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
//  Laboratory (LANL), the U.S. Government retains certain rights in
//  this software.
//============================================================================
#ifndef vtk_m_rendering_raytracing_CellTables_h
#define vtk_m_rendering_raytracing_CellTables_h

#include <vtkm/Types.h>
#include <vtkm/internal/ExportMacros.h>

namespace vtkm
{
namespace rendering
{
namespace raytracing
{

class CellTables
{
private:
  struct Tables
  {
    vtkm::Int32 CellTypeLookUp[15];
    vtkm::Int32 FaceLookUp[5][3];
    vtkm::Int32 ShapesFaceList[20][5];
    vtkm::Int32 ZooTable[30][4];
    vtkm::Int32 ZooLookUp[5][2];
  };

public:
  VTKM_EXEC_CONT static const Tables& Get()
  {
    static const Tables tables = {
      // CellTypeLookUp: LookUp of Shapes to FaceLookUp
      {
        4, // 0 Nothing
        4, // 1 Vertex
        4, // 2 (Not Used) Poly Vertex
        4, // 3 Line
        4, // 4 (Not Used) Poly Line
        4, // 5 Triangle
        4, // 6 (not used) triangle strip
        4, // 7 Polygon
        4, // 8 (Not used)Pixel
        4, // 9 Quad
        1, // 10 Tetra
        4, // 11 (Not used) Voxel
        0, // 12 Hex
        2, // 13 Wedge
        3  // 14  Pyramid
      },

      // FaceLookUp
      {
        { 0, 6, 8 },  //hex offset into shapes face list,  num faces and number of Indices
        { 6, 4, 4 },  //tet
        { 10, 5, 6 }, //wedge
        { 15, 5, 5 }, //pyramid
        { -1, 0, 0 }  //unsupported shape
      },

      // ShapesFaceList:
      // The convention for the faces is that looking from the outside of
      // the shape at a face, triangles should wind CCW.
      // Quads are broken up by {4=quad,a,b,c,d}:
      // t1 = abc and t2 = acd. Indices of the face are ordered CW, and the mapping
      // of t1 and t2 become CCW.
      // Since we know the triangle winding, we could tell
      // if we hit an inside face or outside face.
      {                    //hex
        { 4, 0, 1, 5, 4 }, //face 0
        { 4, 1, 2, 6, 5 },
        { 4, 3, 7, 6, 2 },
        { 4, 0, 4, 7, 3 },
        { 4, 0, 3, 2, 1 },
        { 4, 4, 5, 6, 7 }, //face 5

        //tet
        { 3, 0, 3, 1, -1 },
        { 3, 1, 2, 3, -1 },
        { 3, 0, 2, 3, -1 },
        { 3, 0, 2, 1, -1 },

        //wedge
        { 3, 0, 1, 2, -1 },
        { 3, 3, 5, 4, -1 },
        { 4, 3, 0, 2, 5 },
        { 4, 1, 4, 5, 2 },
        { 4, 0, 3, 4, 1 },

        //pyramid
        { 3, 0, 4, 1, -1 },
        { 3, 1, 2, 4, -1 },
        { 3, 2, 3, 4, -1 },
        { 3, 0, 4, 3, -1 },
        { 4, 3, 2, 1, 0 } },

      // ZooTable:
      // Test of zoo table.
      // Format (faceNumber, triangle)
      //
      { { 0, 0, 1, 5 }, // hex
        { 0, 0, 5, 4 }, { 1, 1, 2, 6 }, { 1, 1, 6, 5 }, { 2, 3, 7, 6 }, { 2, 3, 6, 2 },
        { 3, 0, 4, 7 }, { 3, 0, 7, 3 }, { 4, 0, 3, 2 }, { 4, 0, 2, 1 }, { 5, 4, 5, 6 },
        { 5, 4, 6, 7 }, { 0, 0, 3, 1 },                                 // Tet
        { 1, 1, 2, 3 }, { 2, 0, 2, 3 }, { 3, 0, 2, 1 }, { 0, 0, 1, 2 }, // Wedge
        { 1, 3, 5, 4 }, { 2, 3, 0, 2 }, { 2, 3, 2, 5 }, { 3, 1, 4, 5 }, { 3, 1, 5, 2 },
        { 4, 0, 3, 4 }, { 4, 0, 4, 1 }, { 0, 0, 4, 1 }, // Pyramid
        { 1, 1, 2, 4 }, { 2, 2, 3, 4 }, { 3, 0, 4, 3 }, { 4, 3, 2, 1 }, { 4, 3, 1, 0 } },

      // ZooLookUp:
      // Offset into zoo table and the
      // number of triangles for the shape
      //
      {
        { 0, 12 }, //hex offset into shapes face list,  num faces and number of Indices
        { 12, 4 }, //tet
        { 16, 8 }, //wedge
        { 24, 6 }, //pyramid
        { -1, 0 }  //unsupported shape
      }
    };

    return tables;
  }
};

} // namespace raytracing
} // namespace rendering
} // namespace vtkm
#endif
