/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * 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
 *
 * 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 otbImageToLabelMapWithAttributesFilter_h
#define otbImageToLabelMapWithAttributesFilter_h

#include "itkShapeLabelMapFilter.h"
#include "otbAttributesMapLabelObjectWithClassLabel.h"
#include "otbLabelImageToLabelMapWithAdjacencyFilter.h"
#include "otbShapeAttributesLabelMapFilter.h"
#include "otbBandsStatisticsAttributesLabelMapFilter.h"
#include "otbLabelMapWithClassLabelToClassLabelImageFilter.h"


namespace otb
{

/** \class ImageToLabelMapWithAttributesFilter
 * \brief Convert a labeled image to a label map with adjacency information
 *        and computes feature attributes for each LabelObject
 *
 * Convert a labeled image and its associated vector image
 * to a label map with adjacency information, and computes shape and
 * radiometric attributes for each LabelObject.
 *
 * It is suitable to be used with otb::LabelMapWithAdjacency<otb::AttributesMapLabelObject>
 *
 * \ingroup OTBLabelMap
 */
template <class TInputImage, class TLabeledImage, class TLabel, class TLabelObject >
class ITK_EXPORT ImageToLabelMapWithAttributesFilter
  : public itk::ImageToImageFilter< TInputImage, LabelMapWithAdjacency<TLabelObject> >
{

public:
  /** Standard class typedefs */
  typedef ImageToLabelMapWithAttributesFilter      Self;
  typedef itk::SmartPointer<Self>                  Pointer;
  typedef itk::SmartPointer<const Self>            ConstPointer;
  typedef itk::ImageToImageFilter< TInputImage, LabelMapWithAdjacency<TLabelObject> > Superclass;

  /** Standard type macro */
  itkTypeMacro(ImageToLabelMapWithAttributesFilter, itk::ImageToImageFilter);

  /** New macro*/
  itkNewMacro(Self);

  typedef TInputImage                 InputImageType;
  typedef TLabeledImage               LabeledImageType;
  typedef TLabelObject                LabelObjectType;

  typedef typename LabelObjectType::LabelType                                  LabelType;
  typedef LabelMapWithAdjacency<LabelObjectType>                               LabelMapType;
  typedef typename LabelMapType::AdjacentLabelsContainerType                   AdjacentLabelsContainerType;

  typedef LabelImageToLabelMapWithAdjacencyFilter<LabeledImageType, LabelMapType> LabelMapFilterType;
  typedef ShapeAttributesLabelMapFilter<LabelMapType>                             ShapeLabelMapFilterType;
  typedef BandsStatisticsAttributesLabelMapFilter<LabelMapType, InputImageType>   BandStatisticsLabelMapFilterType;

  using Superclass::SetInput;
  void SetInput( const InputImageType *image) override;
  virtual void SetLabeledImage( const LabeledImageType * image);
  const InputImageType * GetInput(void);
  const LabeledImageType * GetLabeledImage();
  virtual LabelMapType* GetOutput();

  void GenerateData() override;

protected:
  /** Constructor */
  ImageToLabelMapWithAttributesFilter();
  /** Destructor */
  ~ImageToLabelMapWithAttributesFilter() override{};

  void GenerateInputRequestedRegion() override;


private:
  ImageToLabelMapWithAttributesFilter(const Self&); //purposely not implemented
  void operator=(const Self&); //purposely not implemented

  typename LabelMapType::Pointer   m_Output;

};
}

#ifndef OTB_MANUAL_INSTANTIATION
#include "otbImageToLabelMapWithAttributesFilter.txx"
#endif
#endif

