/*=========================================================================
 *
 *  Copyright NumFOCUS
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/
#ifndef itkLevelSetNode_h
#define itkLevelSetNode_h

#include "itkIndex.h"
#include "itkImage.h"
#include "itkVectorContainer.h"
#include "itkVector.h"

namespace itk
{
/**
 * \class LevelSetNode
 * \brief Represent a node in a level set.
 *
 * LevelSetNode is a simple templated class that represents a node
 * or grid position of a level set. A group or collection of
 * LevelSetNode can then be used to represents a narrowband or
 * region of interest.
 *
 * LevelSetNode is templated over the data type and dimension of the
 * level set.
 *
 * \ingroup LevelSetSegmentation
 *
 * \ingroup ITKFastMarching
 */
template <typename TPixel, unsigned int VSetDimension = 2>
class LevelSetNode
{
public:
  /** Standard class type aliases. */
  using Self = LevelSetNode;

  /** Pixel type alias. */
  using PixelType = TPixel;

  /** Level set dimension. */
  static constexpr unsigned int SetDimension = VSetDimension;

  /** Index type alias. */
  using IndexType = Index<VSetDimension>;

  /** Operator >. A LevelSetNode is sorted by its value field. */
  bool
  operator>(const Self & node) const
  {
    return m_Value > node.m_Value;
  }

  /** Operator <. A LevelSetNode is sorted by its value field. */
  bool
  operator<(const Self & node) const
  {
    return m_Value < node.m_Value;
  }

  /** Operator <=. A LevelSetNode is sorted by its value field. */
  bool
  operator<=(const Self & node) const
  {
    return m_Value <= node.m_Value;
  }

  /** Operator >=. A LevelSetNode is sorted by its value field. */
  bool
  operator>=(const Self & node) const
  {
    return m_Value >= node.m_Value;
  }

  /** Operator =. Two nodes are equal if both their value and index fields
   * are the same. */
  Self &
  operator=(const Self & rhs)
  {
    if (this != &rhs)
    {
      m_Value = rhs.m_Value;
      m_Index = rhs.m_Index;
    }
    return *this;
  }

  /** Get/Set level set value. */
  PixelType &
  GetValue()
  {
    return m_Value;
  }
  const PixelType &
  GetValue() const
  {
    return m_Value;
  }
  void
  SetValue(const PixelType & input)
  {
    m_Value = input;
  }

  /** Get/Set index. */
  IndexType &
  GetIndex()
  {
    return m_Index;
  }
  const IndexType &
  GetIndex() const
  {
    return m_Index;
  }
  void
  SetIndex(const IndexType & input)
  {
    m_Index = input;
  }

  /** Default constructor */
  LevelSetNode()
    : m_Value(NumericTraits<PixelType>::ZeroValue())
  {
    m_Index.Fill(0);
  }

  /** Copy constructor */
  LevelSetNode(const Self & node)
    : m_Value(node.m_Value)
    , m_Index(node.m_Index)
  {}

private:
  PixelType m_Value;
  IndexType m_Index;
};
} // end namespace itk

#endif
