//----------------------------------------------------------------------------------
//! Handle field changes of the field field.
//----------------------------------------------------------------------------------
void FuzzyConnectedness::handleNotification (Field *field)
{
  ML_TRACE_IN("FuzzyConnectedness::handleNotification ()");
  // Calculation will only be performed if either the start 
  // button is pressed or  the auto update mechanism is used. 
  if ((field ==_startButtonFld) || ((field != _startButtonFld) && _autoUpdateFld->isOn()))
  {
    _state = ML_RESULT_OK;
    //If either input image is open the calculation will be cancelled.
    if(!getUpdatedInImg(0) || !getUpdatedInImg(1))
    {
      _state = ML_DISCONNECTED_GRAPH;
      clearData();
      getOutImg(0)->setOutOfDate();
      getOutImg(1)->setOutOfDate();
      getOutField(0)->notifyAttachments();
      getOutField(1)->notifyAttachments();
    }
    else
    {
      // Same extent of image data and seed point image are required
      if ( getUpdatedInImg(0)->getImgExt() != getUpdatedInImg(1)->getImgExt() )
      {
        _state=ML_BAD_DIMENSION;
      }
      // Calculation will be started here
      else{
        _state = calculate(getUpdatedInImg(0),getUpdatedInImg(1));
      }
    }
    // Let the connected modules know that the output has changed.
    getOutField(0)->notifyAttachments();
    getOutField(1)->notifyAttachments();
  }
}
//----------------------------------------------------------------------------------
//! Constructor
//----------------------------------------------------------------------------------
SegmentationEvaluationMetric::SegmentationEvaluationMetric ()
  : BaseOp(2, 0)
{
  ML_TRACE_IN("SegmentationEvaluationMetric::SegmentationEvaluationMetric ()");

  // Suppress calls of handleNotification on field changes to
  // avoid side effects during initialization phase.
  handleNotificationOff();

  // Get reference to the container for parameters/fields.
  FieldContainer &fields = *getFieldContainer();

  // Add fields to the module and set their values.
  // Also attach them to the output images to notify connected modules about changes.

  (_segmentationThresholdFld = fields.addInt("segmentationThreshold"))->setIntValue(0);
  (_referenceThresholdFld = fields.addInt("referenceThreshold"))->setIntValue(0);
  
  (_truePositiveFld = fields.addInt("truePositive"))->setIntValue(0);
  (_trueNegativeFld = fields.addInt("trueNegative"))->setIntValue(0);
  (_falsePositiveFld = fields.addInt("falsePositive"))->setIntValue(0);
  (_falseNegativeFld = fields.addInt("falseNegative"))->setIntValue(0);
  (_sensitivityFld = fields.addDouble("sensitivity"))->setDoubleValue(0.0);
  (_specificityFld = fields.addDouble("specificity"))->setDoubleValue(0.0);
  (_prevalenceFld = fields.addDouble("prevalence"))->setDoubleValue(0.0);
  (_levelOfTestFld = fields.addDouble("levelOfTest"))->setDoubleValue(0.0);
  (_diceSimilarityCoefficientFld = fields.addDouble("diceSimilarityCoefficient"))->setDoubleValue(0.0);
  (_cFactorFld = fields.addDouble("cFactor"))->setDoubleValue(0.0);

  (_isAutoApplyFld = fields.addBool("isAutoApply"))->setBoolValue(false);
  _applyFld = fields.addNotify("apply");

  // Connect input field(s) with output field(s) to notify
  // connected modules if input image(s) change.
  for (int inIdx=0; inIdx < 2; ++inIdx){
    for (int outIdx=0; outIdx < 0; ++outIdx){
      getInField(inIdx)->attachField(getOutField(outIdx));
    }
  }

  // Reactivate calls of handleNotification on field changes.
  handleNotificationOn();

  // Activate inplace data buffers for output outIndex and input inIndex.
  // setOutImgInplace(outIndex, inIndex);

  // Activate page data bypass from input inIdx to output outIdx.
  // Note that the module must still be able to calculate the output image.
  // setBypass(outIndex, inIndex);

  // Activate parallel execution of calcOutSubImage.
  // setThreadSupport(supportMode);
  // with supportMode =
  //   NO_THREAD_SUPPORT                 //! The module is not thread safe at all.
  //   CALC_OUTSUBIMAGE_ON_STD_TYPES     //! calcOutSubImage can be called in parallel for scalar voxel types.
  //   CALC_OUTSUBIMAGE_ON_CARRIER_TYPES //! calcOutSubImage can be called in parallel for carrier voxel types.
  //   CALC_OUTSUBIMAGE_ON_ALL_TYPES     //! calcOutSubImage can be called in parallel for all voxel types.
  // Warning: You should be familiar with multithreading before activating this feature.

  // Specify whether the module can only process standard scalar voxel types or
  // also registered voxel types (vec2, mat2, complexf, Vector, etc.)
  // setVoxelDataTypeSupport(permittedTypes);
  // with permittedTypes =
  //   ONLY_STANDARD_TYPES               //! Only standard scalar voxels are supported.
  //   FULLY_OPERATIONAL                 //! Scalar and registered voxels types are supported.
  //   MINIMUM_OPERATIONAL               //! Scalar and registered voxel types are supported.
  //                                     //! Voxel operators are not used by algorithm.
  //
  // See ML Programming Guide, "Configuring Image Processing Behaviour of the BaseOp"
  // for further details.
}