/*
 * Copyright 2006-2021 The MZmine Development Team
 *
 * This file is part of MZmine.
 *
 * MZmine 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 2 of the
 * License, or (at your option) any later version.
 *
 * MZmine 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 MZmine; if not,
 * write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

package io.github.mzmine.modules.dataprocessing.featdet_mobilityscanmerger;

import io.github.mzmine.datamodel.Frame;
import io.github.mzmine.datamodel.IMSRawDataFile;
import io.github.mzmine.datamodel.MobilityScan;
import io.github.mzmine.datamodel.features.SimpleFeatureListAppliedMethod;
import io.github.mzmine.datamodel.impl.SimpleFrame;
import io.github.mzmine.datamodel.impl.masslist.ScanPointerMassList;
import io.github.mzmine.parameters.ParameterSet;
import io.github.mzmine.parameters.parametertypes.selectors.ScanSelection;
import io.github.mzmine.parameters.parametertypes.tolerances.MZTolerance;
import io.github.mzmine.taskcontrol.AbstractTask;
import io.github.mzmine.taskcontrol.TaskStatus;
import io.github.mzmine.util.maths.CenterFunction;
import io.github.mzmine.util.maths.Weighting;
import io.github.mzmine.util.scans.SpectraMerging;
import io.github.mzmine.util.scans.SpectraMerging.MergingType;
import java.time.Instant;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jetbrains.annotations.NotNull;

public class MoblityScanMergerTask extends AbstractTask {

  private static final Logger logger = Logger.getLogger(MoblityScanMergerTask.class.getName());

  private final ScanSelection scanSelection;
  private final IMSRawDataFile rawDataFile;
  private final MZTolerance mzTolerance;
  private final Weighting weighting;
  private final ParameterSet parameters;
  private final double noiseLevel;
  private int totalFrames;
  private int processedFrames;

  public MoblityScanMergerTask(final IMSRawDataFile file, ParameterSet parameters, @NotNull Instant moduleCallDate) {
    super(null, moduleCallDate); // for now, the merged data points are added to the frame on the raw data
    // level. In the future, we will generate a mass list.
    processedFrames = 0;
    totalFrames = 1;
    this.parameters = parameters;
    this.rawDataFile = file;

    mzTolerance = parameters.getParameter(MobilityScanMergerParameters.mzTolerance).getValue();
    weighting = parameters.getParameter(MobilityScanMergerParameters.weightingType)
        .getValue();
    scanSelection = parameters.getParameter(MobilityScanMergerParameters.scanSelection).getValue();
    noiseLevel = parameters.getParameter(MobilityScanMergerParameters.noiseLevel).getValue();
  }


  @Override
  public String getTaskDescription() {
    return "Merging mobility scans for frame " + processedFrames + "/" + totalFrames;
  }

  @Override
  public double getFinishedPercentage() {
    return processedFrames / (double) totalFrames;
  }

  @Override
  public void run() {

    setStatus(TaskStatus.PROCESSING);

    final CenterFunction cf = new CenterFunction(SpectraMerging.DEFAULT_CENTER_MEASURE, weighting);

    List<? extends Frame> frames = scanSelection
        .getMatchingScans(rawDataFile.getFrames());
    totalFrames = frames.size();

    try {
      for (Frame f : frames) {
        SimpleFrame frame = (SimpleFrame) f;
        double[][] merged = SpectraMerging
            .calculatedMergedMzsAndIntensities(frame.getMobilityScans().stream().map(
                MobilityScan::getMassList).toList(), mzTolerance,
                MergingType.SUMMED, cf, noiseLevel, null);

        frame.setDataPoints(merged[0], merged[1]);
        frame.addMassList(new ScanPointerMassList(frame));

        processedFrames++;
      }
    } catch (NullPointerException e) {
      logger.log(Level.SEVERE, e.getMessage(), e);
      setErrorMessage("No mass list present in " + rawDataFile.getName() + ".\nPlease run mass detection first.");
      setStatus(TaskStatus.ERROR);
      return;
    }

    rawDataFile.getAppliedMethods()
        .add(new SimpleFeatureListAppliedMethod(MobilityScanMergerModule.class, parameters, getModuleCallDate()));

    setStatus(TaskStatus.FINISHED);
  }
}

@@ -1727,31 +1727,8 @@
 nt;%0A
-import java.util.Date;%0A
 impo
@@ -2253,16 +2253,57 @@
 eLevel;%0A
+  private final MergingType mergingType;%0A
   privat
@@ -2435,16 +2435,22 @@
 ameters,
+%0A     
  @NotNul
@@ -2492,16 +2492,24 @@
 er(null,
+%0A       
  moduleC
@@ -2853,24 +2853,120 @@
 getValue();%0A
+    mergingType = parameters.getParameter(MobilityScanMergerParameters.mergingType).getValue();%0A
     weightin
@@ -3036,25 +3036,16 @@
 ingType)
-%0A        
 .getValu
@@ -3248,17 +3248,16 @@
 );%0A  %7D%0A%0A
-%0A
   @Overr
@@ -3723,25 +3723,16 @@
 election
-%0A        
 .getMatc
@@ -3929,29 +3929,16 @@
 aMerging
-%0A            
 .calcula
@@ -3964,16 +3964,29 @@
 nsities(
+%0A            
 frame.ge
@@ -4015,33 +4015,16 @@
 m().map(
-%0A                
 Mobility
@@ -4081,13 +4081,9 @@
     
- 
-   M
+m
 ergi
@@ -4092,15 +4092,8 @@
 Type
-.SUMMED
 , cf
@@ -4422,16 +4422,26 @@
 etName()
+%0A         
  + %22.%5CnP
@@ -4566,16 +4566,21 @@
 ethods()
+.add(
 %0A       
@@ -4580,21 +4580,16 @@
         
-.add(
 new Simp
@@ -4658,16 +4658,28 @@
 ameters,
+%0A           
  getModu

fix MobilityScanMering always summing