/* Copyright (c) 2009 Stanford University, School of Medicine All rights reserved. 
* 
* STANFORD ACADEMIC SOFTWARE LICENSE AGREEMENT 
* FOR AngioLocalize SOURCE CODE: 
* 
* 1.  This is a legal agreement between you, RECIPIENT, and STANFORD UNIVERSITY.  
*       By accepting, receiving, and using AngioLocalize.including any accompanying information, materials or 
*       manuals (Program), you are agreeing to be bound by the terms of this Agreement.  
*       If you do not agree to the terms of this Agreement, promptly return the Program to the STANFORD.

* 2.  STANFORD grants to RECIPIENT a royalty-free, nonexclusive, and nontransferable license to use the Program 
*       and accompanying source code furnished hereunder, upon the terms and conditions set out below. 
*       documentation and/or other materials provided with the distribution. 
* 3.  RECIPIENT acknowledges that the Program is a research tool still in the development stage and that 
*       it is being supplied as is, without any accompanying services, support or improvements from STANFORD.
* 4.  RECIPIENT agrees to use the Program solely for internal non-commercial purposes. 
* 5.  RECIPIENT may create derivatives and further transfer the Program under the following terms and conditions: 
*        A) Recipient agrees to not commercially exploit the Program and agrees all uses will be for non-commercial purposes; and,
*        B) Recipient may not mark any derivatives with the title of Program and may not to use iPad mark for any derivatives; and,
*        C) Recipient agrees to mark and acknowledge all derivatives as follows: "This is a derivative work based on AngioLocalize:
*           Frameless AVM localization with 2D Digital Subtraction Angiography (DSA) and 3D Rotational Angiography (DRA) Images developed
*           by Dimitre Hristov, Lina Liu.
*        D) Recipient agrees to make all improvements, enhancements and derivatives available under 
*           similar terms and conditions to the research community. 
* 6.   RECIPIENT warrants that RECIPIENT will not remove or export any part of the software or Program from the United 
*       States except in full compliance with all United States and other applicable laws and regulations.
* 7.  RECIPIENT will use the Program in compliance with all applicable laws, policies and regulations including, but not 
*       limited to, any approvals, informed consent and patient confidentiality principles.
* 8.   RECIPIENT will indemnify, hold harmless, and defend Stanford against any claim of any kind arising out of or
*       related to the exercise of any rights granted under this Agreement or the breach of this Agreement by RECIPIENT.
* 9.  Title and copyright to the Program and any associated documentation shall at all times remain with STANFORD, 
*       and RECIPIENT agrees to preserve same.
*/ 

//----------------------------------------------------------------------------------
//! The ML module class ChamferMatching.
/*!
// \file    mlChamferMatching.h
// \author  linal
// \date    2008-08-28
//
// The 2DChamferMatching module matches a contour given as a XMarkerList to a distance 2D image by iteratively minimizing the sum of the (interpolated) pixel values at the marker positions.
*/
//----------------------------------------------------------------------------------


#ifndef __mlChamferMatching_H
#define __mlChamferMatching_H


// Local includes
#include "STUChamferMatchingSystem.h"

// ML includes
#include "mlOperatorIncludes.h"
#include "mlXMarkerList.h"
#include "mlRotation.h"

#include "nr3.h"
#include "amoeha.h"
#include "amebsa.h"
ML_START_NAMESPACE


//! The 2DChamferMatching module matches a contour given as a XMarkerList to a distance 2D image by iteratively minimizing the sum of the (interpolated) pixel values at the marker positions.
class STUCHAMFERMATCHING_EXPORT ChamferMatching : public BaseOp
{
public:

  //! Constructor.
  ChamferMatching ();
  ~ChamferMatching ()       {if (_outMarkerList) delete _outMarkerList;
							if (_filteredMarkerList) delete _filteredMarkerList;}

  //! algorithms 
  enum {
	  amoeba = 0,
	  amebsa = 1,
	  numAlgorithms             //!< Total number of algorithms, not to be used as enum value!
  };
  
  //@{ Access to module fields. See corresponding field comments for more information.
  inline MatrixField        &getMatrix1Fld () const { return *_matrix1Fld;}
  inline MatrixField        &getMatrix2Fld () const { return *_matrix2Fld;}
  inline MatrixField        &getMatrix3Fld () const { return *_matrix3Fld;}

  inline BoolField          &getApply1Fld () const { return *_apply1Fld;}
  inline BoolField          &getApply2Fld () const { return *_apply2Fld;}
  inline BoolField          &getApply3Fld () const { return *_apply3Fld;}

  inline NotifyField        &getStartFld () const { return *_startFld;}
  inline NotifyField        &getStopFld () const { return *_stopFld;}
  inline NotifyField        &getContinueFld () const { return *_continueFld;}
 
  inline IntField           &getIterationsFld () const { return *_iterationsFld;}
  inline IntField           &getUpdateFreqFld () const { return *_updateFreqFld;}
  inline IntField			&getnumMarkersFld () const {return *_numMarkersFld;}

  inline FloatField         &getAccuracyFld () const { return *_accuracyFld;}
  inline FloatField         &gettemperatureFld () const { return *_temperatureFld;}
  inline FloatField         &getannealingFld () const { return *_annealingFld;}
  inline FloatField         &getfinalCostFld () const { return *_finalCostFld;}

  //! Return which pattern mode is filled into the output image; default is mode 0 (XStripes).
  inline EnumField          *getModeFld()          const { return _modeFld; }

  void                      updateMatrix1Fld ();
  void                      updateMatrix2Fld ();
  void                      updateMatrix3Fld ();

  
  //! Handle field changes of the field field.
  virtual void              handleNotification (Field *field);

  //! Update internal module state after load or clone and enable notification handling again.
  virtual void              activateAttachments ();
  void                      doTransform();
  XMarkerList               *getOutMarkerList()  {return _outMarkerList;}
  void                      generateMatrices(NRvector<Doub> x);
  bool                      getVoxelValue(MLint OutIndex, XMarker  *marker, PagedImg *inImg, double ** voxelValue);
  void                      filter();
  void                      getValuesFromUI();

  friend double             cost(VecDoub &x, void *obj);   

   //! Configures (in)validation handling of inputs which are not connected or up to date.
  virtual INPUT_HANDLE handleInput(int inIndex, INPUT_STATE state) const;

private:

 //----------------------------------------------------------------------------------
 //! this function is to test the Amoeba algorithm. 
 //----------------------------------------------------------------------------------
  //void		  test();
 
  //! private fields
  //! test element numbers
  int         _elementNum;
  const static int   _NUM_PROJECTION_PARAMETERS = 2; //assuming that the focal length is fixed, 3 otherwise
  const static int   _NUM_AFFINE_PARAMETERS= 6;   //only rigid body transformations
  const static int   _DEL = 5; // this is del acording to the numerical recipies. 
  
  //! UI elemements
  BaseField   *_inMarkerListFld;
  XMarkerList *_inMarkerList;
  XMarkerList *_outMarkerList;
  XMarkerList *_filteredMarkerList;

  MatrixField *_matrix1Fld;
  MatrixField *_matrix2Fld;
  MatrixField *_matrix3Fld;

  BoolField   *_apply1Fld;
  BoolField   *_apply2Fld; 
  BoolField   *_apply3Fld; 

  NotifyField   *_startFld;
  NotifyField   *_stopFld;
  NotifyField   *_continueFld;
  
  //! parameter amoeba and amebsa require
  IntField    *_updateFreqFld;
  IntField    *_iterationsFld;
  IntField	  *_numMarkersFld;
  FloatField  *_accuracyFld;
  FloatField  *_temperatureFld;
  FloatField  *_annealingFld;
  FloatField  *_finalCostFld;


  //! these matrices are intermediate data that used in calculating minimum
  mat4        _affine1TempM;
  mat4        _perspectTempM;
  mat4        _matrixToUse; //combined affine and perspective transformation
  mat4        _affine2TempM;

  bool        _hasMaskImage;

   //! SubImage wrapping the input image.
  SubImg      _inputImage;
  PagedImg    *_input1Img;
  PagedImg    *_maskImg;

  EnumField   *_modeFld; 

  int          _updateFreq;
  int          _iterations;
  float        _accuracy;
  float		   _temperature;
  float		   _annealing;
  float		   _finalCost;
  //! Implements interface for the runtime type system of the ML.
  ML_BASEOP_CLASS_HEADER(ChamferMatching)
};


ML_END_NAMESPACE

#endif // __mlChamferMatching_H

