// SpaFEDTe, a Template based C++ library for creating 
// Discontinuous Finite Element Spaces,
// Copyright (C) 2012 Lorenzo Alessio Botti

/* This library is free software; you can redistribute it and/or */
/* modify it under the terms of the GNU Lesser General Public */ 
/* License as published by the Free Software Foundation either */ 
/* version 3.0 of the License, or (at your option) any later version. */

/* This software is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU */
/* Lesser General Public License for more details. */

/* You should have received a copy of the GNU Lesser General Public */
/* License along with this software; if not, a copy of the full */
/* GNU Lesser General Public License can be found at */
/* http://www.gnu.org/licenses/. */

#ifndef __vtk_helper_spamesh_h__
#define __vtk_helper_spamesh_h__

#include "EnumElemType.hpp"
#include "Tuple.hpp"
#include <stdexcept>
#include <cassert>
#include <iostream>
#include "EntityTypesMesh.hpp"
#include "Quadrature.hpp"

using namespace SpaMesh;

struct VTKHelperSpaMesh
{
  typedef Quadrature::PointVector PointVector;
  
  static void getSubElementsNodesE(const ElemType& itemType, const unsigned int& order, PointVector& nodes);

  static unsigned int getNumberOfSubElementsUnlimited(const ElemType& elemType, const unsigned int& order);
  
  static unsigned int getNumberOfSubElementsUnlimited(const ElemTypesMesh& itemType, const unsigned int& order);
  
  static unsigned int getNumberOfSubElements(const ElemType& elemType, const unsigned int& order);
  
  static unsigned int getNumberOfSubElements(const ElemTypesMesh& itemType, const unsigned int& order);
  
  static unsigned int getSubElementsTotalNodesNumber(const ElemTypesMesh& itemType, const unsigned int& order, unsigned int& subElementNodesNumber);
  
  static unsigned int getSubElementsTotalNodesNumber(const ElemType& elemType, const unsigned int& order, unsigned int& subElementNodesNumber);

  static void getSubElementsNodesNumbering(const ElemTypesMesh itemType, const unsigned int order, 
	                                   Eigen::Matrix<unsigned int,Eigen::Dynamic,Eigen::Dynamic,Eigen::RowMajor>& numbering);

  static unsigned int vtkItemType(const ElemTypesMesh& itemType);
};
#endif
