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

#include "smtk/bridge/polygon/Operator.h"

#include "smtk/common/UnionFind.h"

#include <map>
#include <set>
#include <vector>

namespace smtk {
  namespace bridge {
    namespace polygon {

struct EdgeFragmentComparator;
struct EdgeFragment;
struct Neighborhood;
struct Region;
struct SweepEvent;
struct SweeplinePosition;

typedef size_t FragmentId;
typedef std::set<SweepEvent> SweepEventSet;
typedef std::vector<SweepEvent> SweepEventArray;
typedef std::set<FragmentId, EdgeFragmentComparator> ActiveFragmentTree;
typedef std::vector<EdgeFragment> FragmentArray;
typedef int RegionId;
typedef smtk::common::UnionFind<RegionId> RegionIdSet;
typedef std::map<RegionId, smtk::shared_ptr<Region> > RegionDefinitions;

/**\brief Create a face given a set of point coordinates or edges (but not both).
  *
  */
class SMTKPOLYGONSESSION_EXPORT CreateFaces : public Operator
{
public:
  smtkTypeMacro(CreateFaces);
  smtkCreateMacro(CreateFaces);
  smtkSharedFromThisMacro(Operator);
  smtkDeclareModelOperator();

protected:
  virtual smtk::model::OperatorResult operateInternal();

  void processNeighborhood(
    Neighborhood& n,
    RegionDefinitions& regions,
    RegionIdSet& regionIds);
  void processSegmentStart(
    const SweepEvent& event,
    FragmentArray& fragments,
    SweeplinePosition& sweepPosn,
    ActiveFragmentTree& activeEdges,
    SweepEventArray& edgesToInsertAfterAdvance,
    Neighborhood& n);
  void processSegmentEnd(
    const SweepEvent& event,
    FragmentArray& fragments,
    Neighborhood& n);
  void processSegmentCross(
    const SweepEvent& event,
    FragmentArray& fragments,
    SweeplinePosition& sweepPosn,
    ActiveFragmentTree& activeEdges,
    SweepEventArray& edgesToInsertAfterAdvance,
    Neighborhood& n);
};

    } // namespace polygon
  } //namespace bridge
} // namespace smtk

#endif // __smtk_session_polygon_CreateFaces_h
