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

#include "smtk/extension/vtk/source/Exports.h"

#include "smtk/model/EntityRef.h"

#include "smtk/PublicPointerDefs.h"

#include "vtkPolyDataAlgorithm.h"

/**\brief A VTK filter that provides polydata for an SMTK model manager instance.
  *
  */
class VTKSMTKSOURCEEXT_EXPORT vtkModelSource : public vtkPolyDataAlgorithm
{
public:
  static vtkModelSource* New();
  virtual void PrintSelf(ostream& os, vtkIndent indent);
  vtkTypeMacro(vtkModelSource, vtkPolyDataAlgorithm);

  vtkGetObjectMacro(CachedOutput, vtkPolyData);

  smtk::model::EntityRefs GetEntities();
  void SetEntities(const smtk::model::EntityRefs&);

  void Dirty();

protected:
  vtkModelSource();
  virtual ~vtkModelSource();

  struct SortByDim
  {
    bool operator()(const smtk::model::EntityRef& a, const smtk::model::EntityRef& b)
    {
      return (a.dimension() < b.dimension()) || (a.dimension() == b.dimension() && a < b) ? true
                                                                                          : false;
    }
  };
  typedef std::set<smtk::model::EntityRef, SortByDim> EntityRefsByDim;

  void AccumulateSortedEntities(
    EntityRefsByDim& accum, vtkIdType& npts, smtk::model::EntityRefs& toplevel);
  void GenerateRepresentationFromModel(
    vtkPolyData* poly, const EntityRefsByDim& model, vtkIdType npts);

  //virtual int FillInputPortInformation(int port, vtkInformation* request);
  //virtual int FillOutputPortInformation(int port, vtkInformation* request);

  virtual int RequestData(
    vtkInformation* request, vtkInformationVector** inInfo, vtkInformationVector* outInfo);

  void SetCachedOutput(vtkPolyData*);

  // Instance storage:
  smtk::model::EntityRefs Entities;
  vtkPolyData* CachedOutput;

private:
  vtkModelSource(const vtkModelSource&); // Not implemented.
  void operator=(const vtkModelSource&); // Not implemented.
};

#endif // __smtk_vtk_ModelSource_h
