// GenFem - A high-level finite element library
// Copyright (C) 2010-2026 Eric Bechet
//
// See the LICENSE file for license information and contributions.
// Please report all bugs and problems to <bechet@cadxfem.org>.
//
// Initial design: Eric Bechet (rev.873)


#ifndef _GEN_FILTERS_H_
#define _GEN_FILTERS_H_

#include "genGroupOfElements.h"

class MElement;
class Dof;

//--------------------------------------------------------------------------
// Element filters
//--------------------------------------------------------------------------

class genFilterElement
{
public :
  virtual bool operator()(MElement* e) const = 0;
};

class genFilterElementTrivial : public genFilterElement
{
public :
  genFilterElementTrivial(){}
  virtual bool operator()(MElement* e) const {return true;}
};

class genFilterElementGroup : public genFilterElement
{
protected :
  const genGroupOfElements* g;
public :
  genFilterElementGroup(const genGroupOfElements* g_) : g(g_) {}
  virtual bool operator()(MElement* e) const 
  {
    if (g->contains(e))
      return true;
    return false;
  }
};

class genFilterElementGroupParent : public genFilterElement
{
  const genGroupOfElements* g;
public :
  genFilterElementGroupParent(const genGroupOfElements* g_) : g(g_) {}
  virtual bool operator()(MElement* e) const
  {
    if (g->pcontains(e))
      return true;
    return false;
  }
};

class genFilterElementGroupVertex : public genFilterElement
{
protected :
  const genGroupOfElements* g;
public :
  genFilterElementGroupVertex(const genGroupOfElements* g_) : g(g_) {}
  virtual bool operator()(MElement* e) const;
};

class genFilterElementParent : public genFilterElement
{
public :
  genFilterElementParent(){}
  virtual bool operator()(MElement* e) const;
};

class genFilterElementChild : public genFilterElement
{
public :
  genFilterElementChild(){}
  virtual bool operator()(MElement* e) const;
};

class genFilterElementType : public genFilterElement
{
protected :
  int type;
public :
  genFilterElementType(int type_) : type(type_) {}
  virtual bool operator()(MElement* e) const;
};

class genFilterElementTypeMSH : public genFilterElement
{
protected :
  int type;
public :
  genFilterElementTypeMSH(int type_) : type(type_) {}
  virtual bool operator()(MElement* e) const;
};



class genFilterElementOperatorAnd : public genFilterElement
{
protected :
  genFilterElement* filter1;
  genFilterElement* filter2;
public :
  genFilterElementOperatorAnd(genFilterElement* filter1_, genFilterElement* filter2_) : filter1(filter1_), filter2(filter2_) {}
  virtual bool operator()(MElement* e) const
  {
    if ((*filter1)(e) && (*filter2)(e))
      return true;
    return false;
  }
};

class genFilterElementOperatorOr : public genFilterElement
{
protected :
  genFilterElement* filter1;
  genFilterElement* filter2;
public :
  genFilterElementOperatorOr(genFilterElement* filter1_, genFilterElement* filter2_) : filter1(filter1_), filter2(filter2_) {}
  virtual bool operator()(MElement* e) const
  {
    if ((*filter1)(e) || (*filter2)(e))
      return true;
    return false;
  }
};

class genFilterElementOperatorNeg : public genFilterElement
{
protected :
  genFilterElement* filter;
public :
  genFilterElementOperatorNeg(genFilterElement* filter_) : filter(filter_) {}
  virtual bool operator()(MElement* e) const
  {
    if (!(*filter)(e))
      return true;
    return false;
  }
};

class genFilterElementOperatorOnParent : public genFilterElement
{
protected :
  genFilterElement* filter;
public :
  genFilterElementOperatorOnParent(genFilterElement* filter_) : filter(filter_) {}
  virtual bool operator()(MElement* e) const;
};



//--------------------------------------------------------------------------
// Dof filters
//--------------------------------------------------------------------------

class genFilterDof
{
public :
  virtual bool operator()(const Dof &key) const = 0;
};

class genFilterDofTrivial : public genFilterDof
{
public :
  virtual bool operator()(const Dof &key) const {return true;}
};

class genFilterDofComponent : public genFilterDof
{
protected :
  int comp;
public :
  genFilterDofComponent(int comp_) : comp(comp_) {}
  virtual bool operator()(const Dof &key) const;
};

class genFilterDofMultiComponents : public genFilterDof
{
protected :
  std::set<int> comps;
public :
  genFilterDofMultiComponents(int comp_) {comps.insert(comp_);}
  genFilterDofMultiComponents(std::vector<int> &comps_) : comps(comps_.begin(),comps_.end()) {}
  virtual bool operator()(const Dof &key) const;
};

class genFilterDofEntity : public genFilterDof
{
protected :
  int entity; // number of the vertex
public :
  genFilterDofEntity(int entity_) : entity(entity_) {}
  virtual bool operator()(const Dof &key) const;
};

class genFilterDofMultiEntities : public genFilterDof
{
protected :
  const std::set<long int>* entities;
public :
  genFilterDofMultiEntities(const std::set<long int>* entities_) : entities(entities_) {}
  virtual bool operator()(const Dof &key) const;
};


class genFilterDofOperatorAnd : public genFilterDof
{
protected :
  genFilterDof* filter1;
  genFilterDof* filter2;
public :
  genFilterDofOperatorAnd(genFilterDof* filter1_, genFilterDof* filter2_) : filter1(filter1_), filter2(filter2_) {}
  virtual bool operator()(const Dof &key) const
  {
    if ((*filter1)(key) && (*filter2)(key))
      return true;
    return false;
  }
};

class genFilterDofOperatorOr : public genFilterDof
{
protected :
  genFilterDof* filter1;
  genFilterDof* filter2;
public :
  genFilterDofOperatorOr(genFilterDof* filter1_, genFilterDof* filter2_) : filter1(filter1_), filter2(filter2_) {}
  virtual bool operator()(const Dof &key) const
  {
    if ((*filter1)(key) || (*filter2)(key))
      return true;
    return false;
  }
};

class genFilterDofOperatorNeg : public genFilterDof
{
protected :
  genFilterDof* filter;
public :
  genFilterDofOperatorNeg(genFilterDof* filter_) : filter(filter_) {}
  virtual bool operator()(const Dof &key) const
  {
    if (!(*filter)(key))
      return true;
    return false;
  }
};



/*
class genFilterNodeEnriched : public genFilterDof
{
protected :
  std::set<int>* TagEnrichedVertex;
  std::set<int>* EnrichComp;

public :
  genFilterNodeEnriched(std::set<int>* TagEnrichedVertex_, std::set<int>* EnrichComp_)
  {
    TagEnrichedVertex = TagEnrichedVertex_;
    EnrichComp = EnrichComp_;
  }
  virtual bool operator()(const Dof &key) const;
};

class genFilterElementsCutByLevelSet : public genFilterDof
{
 private :
  std::set<int> TagEnrichedVertex;
  std::pair<int,int> _LevelSetEntity;
  std::set<int>* EnrichComp;
 public :
  genFilterElementsCutByLevelSet(std::pair<int,int> LevelSetEntity , std::set<int>*  EnrichComp_);
  virtual bool operator()(const Dof &key) const;
};
*/


#endif// _GEN_FILTERS_H_
