/* -*- mia-c++  -*-
 *
 * This file is part of MIA - a toolbox for medical image analysis 
 * Copyright (c) Leipzig, Madrid 1999-2017 Gert Wollny
 *
 * MIA is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with MIA; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#ifndef mia_2d_register_hh
#define mia_2d_register_hh

#include <mia/2d/model.hh>
#include <mia/2d/timestep.hh>
#include <mia/2d/cost.hh>
#include <mia/2d/fatcost.hh>
#include <mia/2d/transformfactory.hh>

NS_MIA_BEGIN


/**
   @ingroup registration 
   \brief A 2D non-rigid registration class for time-marching PDE based registration  

   The 2D non-rigid image registration class. This class allows the combination of 
   various image cost functions, provides multi-level registration and the use 
   of various PDE models (depending on the provided plug-ins.
*/
class EXPORT_2D C2DMultiImageNonrigidRegister {
public: 
	/**
	   The constructor: 
	   \param start_size an approximate size for the lowest 
	        resolution in the multi-resolution registration
	   \param max_iter maximum number of times steps to be 
                used at each multi-grid level
	   \param model the registration model (e.g.- navier for 
                linear elasticity operator)
	   \param time_step the time step model (e.g. fluid to let 
                the model operator work on the velocity field instead 
                of the deformation field)
	   \param trans_factory factory for creation of transformations
           \param outer_epsilon a relative cost function value per 
                multi-grid level to stop registration
	*/
	C2DMultiImageNonrigidRegister(size_t start_size, size_t max_iter, 
				      C2DRegModel& model, 
				      C2DRegTimeStep& time_step, 
				      C2DTransformCreator& trans_factory, 
				      float outer_epsilon); 

	/**
	   The registration operator that does the registration
	   \param cost cost function combination to be optimized 
	   \param ipf interpolator to be used for image transformations 
	   \returns a vector field describing the registration
	 */
	P2DTransformation operator () (C2DImageFatCostList& cost, P2DInterpolatorFactory  ipf);
private: 
	void reg_level(C2DImageFatCostList& cost, C2DGridTransformation& result, const C2DInterpolatorFactory& ipf); 
	void reg_level_regrid(C2DImageFatCostList& cost, C2DGridTransformation& result, const C2DInterpolatorFactory& ipf); 
	
	size_t m_start_size;
	size_t m_max_iter; 
	C2DRegModel& m_model; 
	C2DRegTimeStep& m_time_step; 
	float m_outer_epsilon; 
}; 


NS_MIA_END

#endif

