//=========================================================================
//  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 smtk_session_polygon_Session_txx
#define smtk_session_polygon_Session_txx

#include "smtk/model/Resource.h"
#include "smtk/model/Resource.txx"

namespace smtk
{
namespace session
{
namespace polygon
{

/** Consistently delete internal (and only polygon-session-specific) records related to the entities listed in \a container.
  *
  * This will call removeStorage() on each entity but additionally performs
  * cleanup on other entities referencing this entity.
  * For example, given a face, it will remove the face from all vertex records.
  * (Also, for faces, note that there is no internal face storage.)
  * Given an edge, it removes the corresponding incident-edge records from each endpoint.
  * Only lower-dimensional references are processed; this method assumes you have already
  * invoked consistentInternalDelete() on any parent entities.
  * Finally, the SMTK model resource (assumed to be the same for all entities in \a container)
  * is told to delete/reconcile records related to the entities.
  *
  * This method is provided by the session instead of the
  * polygon's internal pmodel class because the container
  * may include cells from multiple models.
  */
template<typename T, typename U, typename V>
void Session::consistentInternalDelete(T& container, U& modified, V& expunged, bool logDebug)
{
  smtk::model::Resource::Ptr resource;
  typename T::iterator it;
  for (it = container.begin(); it != container.end(); ++it)
  {
    if (!it->isCellEntity())
    {
      if (!it->isAuxiliaryGeometry())
      {
        smtkWarningMacro(
          this->log(),
          "Trying to delete polygon storage for " << it->name() << " (" << it->flagSummary()
                                                  << ")");
      }
      if (!resource)
      {
        resource = it->resource();
      }
      continue;
    }
    if (!resource)
    {
      resource = it->resource();
    }
    switch (it->dimensionBits())
    {
      case smtk::model::DIMENSION_2:
        this->removeFaceReferences(*it);
        break;
      case smtk::model::DIMENSION_1:
        this->removeEdgeReferences(*it);
        break;
      case smtk::model::DIMENSION_0:
        this->removeVertReferences(*it);
        break;
    }
  }
  if (resource)
  {
    resource->deleteEntities(container, modified, expunged, logDebug);
  }
}

} // namespace polygon
} //namespace session
} // namespace smtk

#endif // smtk_session_polygon_Session_txx
