/*=========================================================================

  Copyright (c) Kitware, Inc.
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/VolViewCopyright.htm 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 __itkLesionSegmentationImageFilter7_h
#define __itkLesionSegmentationImageFilter7_h

#include "itkImageToImageFilter.h"
#include "itkImage.h"
#include "itkFixedArray.h"
#include "itkCommand.h"
#include "itkImageSpatialObject.h"
#include "itkLandmarkSpatialObject.h"
#include "itkLungWallFeatureGenerator.h"
#include "itkSatoVesselnessSigmoidFeatureGenerator.h"
#include "itkSigmoidFeatureGenerator.h"
#include "itkGradientMagnitudeSigmoidFeatureGenerator.h"
#include "itkFastMarchingAndGeodesicActiveContourLevelSetSegmentationModule.h"
#include "itkMinimumFeatureAggregator.h"
#include "itkRegionOfInterestImageFilter.h"
#include "itkLesionSegmentationMethod.h"
#include "itkMinimumFeatureAggregator.h"
#include <string>

namespace itk
{

/** \class LesionSegmentationImageFilter7
 */
template<class TInputImage, class TOutputImage>
class VTK_EXPORT LesionSegmentationImageFilter7
  : public ImageToImageFilter<TInputImage, TOutputImage>
{
public:
  /** Standard "Self" & Superclass typedef.  */
  typedef LesionSegmentationImageFilter7                 Self;
  typedef ImageToImageFilter<TInputImage, TOutputImage> Superclass;
   
  /** Image typedef support   */
  typedef TInputImage  InputImageType;
  typedef TOutputImage OutputImageType;
      
  /** SmartPointer typedef support  */
  typedef SmartPointer<Self>        Pointer;
  typedef SmartPointer<const Self>  ConstPointer;

  /** Define pixel types. */
  typedef typename TInputImage::PixelType   InputImagePixelType;
  typedef typename TOutputImage::PixelType  OutputImagePixelType;
  typedef typename TInputImage::IndexType   IndexType;

  /** Method for creation through the object factory. */
  itkNewMacro(Self);  
    
  /** Typedef to describe the output image region type. */
  typedef typename TOutputImage::RegionType OutputImageRegionType;
  typedef typename TOutputImage::RegionType RegionType;
    
  /** Run-time type information (and related methods). */
  itkTypeMacro(LesionSegmentationImageFilter7, ImageToImageFilter);
  
  /** ImageDimension constant    */
  itkStaticConstMacro(ImageDimension, unsigned int,
                      TInputImage::ImageDimension);

  /** Get a status message for display purposes */
  itkGetStringMacro( StatusMessage );
  
  virtual void GenerateInputRequestedRegion() 
            throw(InvalidRequestedRegionError);

#ifdef ITK_USE_CONCEPT_CHECKING
  itkStaticConstMacro(OutputImageDimension, unsigned int,
                      TOutputImage::ImageDimension);

  /** Begin concept checking */
  itkConceptMacro(InputHasNumericTraitsCheck,
    (Concept::HasNumericTraits<InputImagePixelType>));
  itkConceptMacro(OutputHasNumericTraitsCheck,
    (Concept::HasNumericTraits<OutputImagePixelType>));
  itkConceptMacro(SameDimensionCheck,
    (Concept::SameDimension<ImageDimension, OutputImageDimension>));
  itkConceptMacro(OutputIsFloatingPointCheck,
    (Concept::IsFloatingPoint<OutputImagePixelType>));
  /** End concept checking */
#endif


  void ProgressUpdate( Object * caller, 
                       const EventObject & event );

  itkSetMacro( RegionOfInterest, RegionType );
  itkGetMacro( RegionOfInterest, RegionType );

  itkSetMacro( SigmoidBeta, double );
  itkGetMacro( SigmoidBeta, double );
  
  typedef itk::LandmarkSpatialObject< ImageDimension > SeedSpatialObjectType;
  typedef typename SeedSpatialObjectType::PointListType PointListType;

  void SetSeeds( PointListType p ) { this->m_Seeds = p; }
  PointListType GetSeeds() { return m_Seeds; }
  
  // Return the status message
  const char *GetStatusMessage() 
    {
    return m_StatusMessage.length() ? m_StatusMessage.c_str() : NULL;
    }

protected:
  LesionSegmentationImageFilter7();
  LesionSegmentationImageFilter7(const Self&) {}
  void PrintSelf(std::ostream& os, Indent indent) const;

  virtual void GenerateOutputInformation();
  void GenerateData();

  // Filters used by this class
  typedef LesionSegmentationMethod< ImageDimension > LesionSegmentationMethodType;
  typedef SatoVesselnessSigmoidFeatureGenerator< ImageDimension > VesselnessGeneratorType;
  typedef LungWallFeatureGenerator< ImageDimension > LungWallGeneratorType;
  typedef SigmoidFeatureGenerator< ImageDimension > SigmoidFeatureGeneratorType;
  typedef GradientMagnitudeSigmoidFeatureGenerator< ImageDimension > GradientMagnitudeSigmoidGeneratorType;  
  typedef MinimumFeatureAggregator< ImageDimension > FeatureAggregatorType;
  typedef FastMarchingAndGeodesicActiveContourLevelSetSegmentationModule< ImageDimension > SegmentationModuleType;
  typedef RegionOfInterestImageFilter< InputImageType, InputImageType > CropFilterType; 
  typedef typename SegmentationModuleType::SpatialObjectType       SpatialObjectType;
  typedef typename SegmentationModuleType::OutputSpatialObjectType OutputSpatialObjectType;
  typedef itk::ImageSpatialObject< ImageDimension, InputImagePixelType > InputImageSpatialObjectType;
  typedef typename RegionType::SizeType           SizeType;
  typedef MemberCommand< Self >  CommandType;


private:
  virtual ~LesionSegmentationImageFilter7(){};

  double                                m_Sigma;
  double                                m_SigmoidBeta;
  double                                m_GradientMagnitudeSigmoidBeta;
  double                                m_FastMarchingStoppingTime;
  double                                m_FastMarchingDistanceFromSeeds;
  typename LesionSegmentationMethodType::Pointer m_LesionSegmentationMethod;
  typename LungWallGeneratorType::Pointer        m_LungWallFeatureGenerator;
  typename VesselnessGeneratorType::Pointer      m_VesselnessFeatureGenerator;
  typename SigmoidFeatureGeneratorType::Pointer  m_SigmoidFeatureGenerator;
  typename GradientMagnitudeSigmoidGeneratorType::Pointer m_GradientMagnitudeSigmoidFeatureGenerator;
  typename FeatureAggregatorType::Pointer        m_FeatureAggregator;
  typename SegmentationModuleType::Pointer       m_SegmentationModule;
  typename CropFilterType::Pointer               m_CropFilter;
  typename InputImageSpatialObjectType::Pointer  m_InputSpatialObject;
  typename CommandType::Pointer                  m_CommandObserver;
  RegionType                                     m_RegionOfInterest;
  std::string                                    m_StatusMessage;
  typename SeedSpatialObjectType::PointListType  m_Seeds;
};

} //end of namespace itk

#ifndef ITK_MANUAL_INSTANTIATION
#include "itkLesionSegmentationImageFilter7.txx"
#endif
  
#endif

