/**============================================================================
 *
 * \file   filter.hxx
 * \brief  Apply a filter to an image (generic implementations).
 *
 * \author Leblanc Christophe.
 * \date   07/11/2012
 * \email cleblancad@gmail.com
 *
 * Code inspired from:
 * 'Getting Started with ITK + VTK'
 * L. Ibanez, W. Schroeder, Insight Software Consortium.
 *
 *
 *===========================================================================*/

#ifndef TOMOPROCESS_FILTER_FILTER_HXX
#define TOMOPROCESS_FILTER_FILTER_HXX

#include "filter.hpp"

TOMOPROCESS_OPEN_GLOBAL_NAMESPACE
TOMOPROCESS_OPEN_FILTER_NAMESPACE

template<class ITKFilterT, class ImageT>
Filter<ITKFilterT, ImageT>::Filter():
  SuperClass(),
  m_Draw(false),
  m_Verbose(false)
{
  m_Filter = ITKFilterType::New();
  
  this->SetClassName(m_Filter->GetNameOfClass());
  this->SetDescription(m_Filter->GetObjectName());
}

template<class ITKFilterT, class ImageT>
Filter<ITKFilterT, ImageT>::Filter(const Filter &rhs):
  SuperClass(rhs),
  m_Draw(rhs.m_Draw),
  m_Verbose(rhs.m_Verbose),
  m_Filter(rhs.m_Filter->Clone())
{}

template<class ITKFilterT, class ImageT>
Filter<ITKFilterT, ImageT>& Filter<ITKFilterT, ImageT>::operator=(
  const Filter &rhs)
{
  if(this != &rhs)
  {
    SuperClass::operator=(rhs);
    
    m_Draw    = rhs.m_Draw;
    m_Verbose = rhs.m_Verbose;
    m_Filter  = rhs.m_Filter->Clone();
  }
  
  return *this;
}

template<class ITKFilterT, class ImageT>
Filter<ITKFilterT, ImageT>* Filter<ITKFilterT, ImageT>::Clone() const
{
  Filter* clone = new Filter(*this);
  return clone;
}

template<class ITKFilterT, class ImageT>
void Filter<ITKFilterT, ImageT>::Update()
{   
  m_Filter->Update();
}

//============================================================================
//=========================== Template Specialization ========================
//============================================================================

template<class ImageT>
Filter<itk::SimpleFilterWatcher, ImageT>::Filter():
  SuperClass(),
  m_Draw(false),
  m_Verbose(false),
  m_Filter(NULL)
{
  this->SetClassName("WatchFilter");
  this->SetDescription("Monitor a filter");
}

template<class ImageT>
Filter<itk::SimpleFilterWatcher, ImageT>::Filter(const Filter &rhs):
  SuperClass(rhs),
  m_Draw(rhs.m_Draw),
  m_Verbose(rhs.m_Verbose),
  m_Filter(new ITKFilterType(*rhs.m_Filter))
{}

template<class ImageT>
Filter<itk::SimpleFilterWatcher, ImageT>&
Filter<itk::SimpleFilterWatcher, ImageT>::operator=(const Filter &rhs)
{
  if(this != &rhs)
  {
    SuperClass::operator=(rhs);
    
    m_Draw    = rhs.m_Draw;
    m_Verbose = rhs.m_Verbose;
    m_Filter  = new ITKFilterType(*rhs.m_Filter);
  }
  
  return *this;
}

template<class ImageT>
Filter<itk::SimpleFilterWatcher, ImageT>*
Filter<itk::SimpleFilterWatcher, ImageT>::Clone() const
{
  Filter* clone = new Filter(*this);
  return clone;
}

template<class ImageT>
void Filter<itk::SimpleFilterWatcher, ImageT>::SetParameters(
  FilterToWatchPtrType filterToWatch,
  const std::string &filterName)
{
  delete m_Filter;
  m_Filter = new ITKFilterType(filterToWatch, filterName.c_str());
}

TOMOPROCESS_CLOSE_FILTER_NAMESPACE
TOMOPROCESS_CLOSE_GLOBAL_NAMESPACE

#endif // TOMOPROCESS_FILTER_FILTER_HXX