//===========================================================================
// The Level-Set Segmentation Library (LSSEG)
//
//
// Copyright (C) 2000-2005 SINTEF ICT, Applied Mathematics, Norway.
//
// This program 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 version 2 of the License. 
//
// 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 this program; if not, write to the Free Software            
// Foundation, Inc.,                                                      
// 59 Temple Place - Suite 330,                                           
// Boston, MA  02111-1307, USA.                                           
//
// Contact information: e-mail: tor.dokken@sintef.no                      
// SINTEF ICT, Department of Applied Mathematics,                         
// P.O. Box 124 Blindern,                                                 
// 0314 Oslo, Norway.                                                     
// 
//
// Other licenses are also available for this software, notably licenses
// for:
// - Building commercial software.                                        
// - Building software whose source code you wish to keep private.        
//
//===========================================================================
//===========================================================================
//                                                                           
// File: MRBalloonForce.h                                                    
//                                                                           
// Created: Fri Feb 24 13:35:56 2006                                         
//                                                                           
// Author: Odd A. Andersen <Odd.Andersen@sintef.no>
//                                                                           
// Revision: $Id: MRBalloonForce.h,v 1.7 2006/11/13 02:29:25 oan Exp $
//                                                                           
// Description:
/// \file
/// \brief Contains the definition of the \ref lsseg::ForceGenerator "ForceGenerator"
///        called \ref lsseg::MRBalloonForce "MRBalloonForce".
//                                                                           
//===========================================================================

#ifndef _MRBALLOONFORCE_H
#define _MRBALLOONFORCE_H

#include "Image.h"
#include "Mask.h"
#include "simple_tools.h"
#include "LevelSetFunction.h"
#include "ForceGenerator.h" // only documentation
#include "errormacros.h"
#include <assert.h>
#include <vector>

namespace lsseg {

//===========================================================================
/// \brief This ForceGenerator creates a  \ref anchor_NormalForceField "normal force field", 
/// which does not depend on the underlying image, only on its current segmentation.
/// 
/// The \ref anchor_NormalForceField "normal force field" generated by this class
/// is constant over the whole domain, and inversely proportional to the area (volume in 3D)
/// of the \em closed domain of the current segmentation.  Thus, the bigger the 
/// interior of this domain is, the weaker the force will be.
/// This ForceGenerator might not be very useful for segmentation purposes,
/// but can be used to make predictable \ref anchor_NormalForceField "normal force field"
/// for testing or debug purposes.  
class MRBalloonForce : public ForceGenerator
//===========================================================================
{
public:
    /// \brief Constructor taking as argument the force field's magnitude and a current
    /// segmentation.
    ///
    /// \param fac The generated force field will be constant, on the form <tt>K/vol</tt>,
    ///            where \c vol is the area (volume in 3D) of the \em interior region
    ///            of the current segmentation.  The parameter \c fac to the constructor
    ///            specifies the constant \c K in the above formula.
    /// \param phi A LevelSetFuncion used to specify the current segmentation, and thus the
    ///            \c vol parameter in the above formula.
    MRBalloonForce(double fac, const LevelSetFunction& phi) 
	: fac_(fac) { update(phi); }
    
    /// \brief virtual destructor
    virtual ~MRBalloonForce() {}

    /// \brief Initializes the MRBalloonForce ForceGenerator.
    ///
    /// inherited from ForceGenerator.  For this class, however, the image information
    /// will not contribute to the determination of the force field, which is constant over
    /// the whole image domain for a given segmentation.
    /// 
    /// \param img (pointer to) the image that the ForceGenerator should use to 
    ///            derive the force field (i.e. the Image to be segmented).  For this class,
    ///            the image information will \em not participate in the determination of the
    ///            (constant) force field.  However, the \em domain of the defined force field 
    ///            will be that ot the image.
    /// \param mask (pointer to) an optional \ref Mask that specifies which part(s) of the
    ///             image are active.  (No forces will be computed for the inactive
    ///             part(s) of an image).  If this pointer is left at zero, the whole
    ///             of \c img is considered to be active.
    virtual void init(const Image<double>* img, const Mask* mask) {
	MESSAGE("Warning: neither 'img' nor 'm' used in MRBalloonForce::init()");
    }

    virtual void update(const LevelSetFunction& phi) {
	double tmp = negative_ratio(phi); 
	cur_force_ = (tmp > 0) ? fac_ / tmp : 0;
    }
    virtual double force2D(int x, int y) const { return cur_force_;}
    virtual double force3D(int x, int y, int z) const {return cur_force_;}
    virtual double force(size_t ix) const {return cur_force_;}
    virtual void force(LevelSetFunction& phi, const Mask* mask = 0) const {
	phi = cur_force_;
    }
    
private:
    /// the multiplicative factor which determines the overall strength of the (constant) force field
    const double fac_;

    /// value for the constant force field given the current segmentation.
    double cur_force_;

    inline void report() const;
};


}; //end namespace lsseg
#endif // _MRBALLOONFORCE_H

