// 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 __CollectiveBasisFunction_h__
#define __CollectiveBasisFunction_h__

#include "BasisFunction.hpp"
#include <vector>

template<unsigned int Dim>
class CollectiveBasisFunction
{
public:
  typedef typename BasisFunction<Dim>::ShapeDerivMatrix ShapeDerivMatrix;
  typedef typename BasisFunction<Dim>::ShapeMatrix ShapeMatrix;

  CollectiveBasisFunction():
    _computeShape(true),
    _computeShapeDeriv(true)
    {
      ;
    } 
  
  ~CollectiveBasisFunction() { }

  void resizeAllCollective(const unsigned int dofs, const unsigned int qpoints)
  {
    this->_shape.resize(dofs, qpoints);
    for (unsigned int d = 0; d < Dim; d++)
      this->_shapeDeriv(d).resize(dofs, qpoints);
  }
  
  bool computeShape() { return _computeShape; }

  bool computeShapeDeriv() { return _computeShapeDeriv; }
  
  bool computeShape() const { return _computeShape; }

  bool computeShapeDeriv() const { return _computeShapeDeriv; }
  
  void doComputeShape(bool computeShape) { _computeShape = computeShape; }

  void doComputeShapeDeriv(bool computeShapeDeriv) { _computeShapeDeriv = computeShapeDeriv; }
  
  ShapeDerivMatrix& getShapeFunctionDeriv() 
  {
    return this->_shapeDeriv; 
  }

  ShapeMatrix& getShapeFunction() 
  {
    return this->_shape; 
  }
  
  const ShapeDerivMatrix& getShapeFunctionDeriv() const 
  {
    return this->_shapeDeriv; 
  }

  const ShapeMatrix& getShapeFunction() const
  {
    return this->_shape; 
  }

private:

  ShapeMatrix _shape;
  
  ShapeDerivMatrix _shapeDeriv;

  bool _computeShape;

  bool _computeShapeDeriv;
  
};

#endif
