//=========================================================================
//  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.
//=========================================================================

#ifndef __smoab_CellSets_h
#define __smoab_CellSets_h

#include "SimpleMoab.h"

namespace smoab
{
class CellSet
{
public:
  CellSet(smoab::EntityHandle p, const smoab::Range& c)
    : Entity(p)
    , Cells(c)
  {
  }

  const smoab::Range& cells() const { return this->Cells; }
  EntityHandle entity() const { return this->Entity; }

  bool contains(smoab::EntityHandle c) const { return this->Cells.find(c) != this->Cells.end(); }

  void erase(smoab::Range c)
  {
    //seems that erase() has a bug, so use subtract
    this->Cells = smoab::subtract(this->Cells, c);
  }

private:
  smoab::EntityHandle Entity;
  smoab::Range Cells;
};

//CellSets are just a vector of CellSets
typedef std::vector<CellSet> CellSets;

//templated so it works with FaceCellSets and CellSets
template <typename T>
smoab::Range getParents(const T& set)
{
  typedef typename T::const_iterator iterator;
  smoab::Range result;

  for (iterator i = set.begin(); i != set.end(); ++i)
  {
    result.insert(i->entity());
  }
  return result;
}

//templated so it works with FaceCellSets and CellSets
template <typename T>
smoab::Range getAllCells(const T& set)
{
  typedef typename T::const_iterator iterator;
  smoab::Range result;

  for (iterator i = set.begin(); i != set.end(); ++i)
  {
    smoab::Range c = i->cells();
    result.insert(c.begin(), c.end());
  }
  return result;
}

template <typename T>
std::vector<T> getTagValues(
  const smoab::Tag* tag, const smoab::CellSets& sets, const smoab::Interface& interface)
{
  std::vector<T> values;
  values.reserve(sets.size());

  typedef smoab::CellSets::const_iterator iterator;
  for (iterator i = sets.begin(); i != sets.end(); ++i)
  {
    int tagValue = interface.getTagData<int>(*tag, i->entity());
    T tvalue = static_cast<T>(tagValue);
    values.push_back(tvalue);
  }
  return values;
}
}

#endif
