//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
// 
//  You should have received a copy of the GNU Lesser General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.

package org.uma.jmetal.runner.multiobjective;

import java.util.List;

import org.knowm.xchart.BitmapEncoder.BitmapFormat;
import org.uma.jmetal.algorithm.multiobjective.dmopso.DMOPSO;
import org.uma.jmetal.algorithm.multiobjective.dmopso.DMOPSO.FunctionType;
import org.uma.jmetal.algorithm.multiobjective.dmopso.DMOPSOMeasures;
import org.uma.jmetal.measure.MeasureListener;
import org.uma.jmetal.measure.MeasureManager;
import org.uma.jmetal.measure.impl.BasicMeasure;
import org.uma.jmetal.measure.impl.CountingMeasure;
import org.uma.jmetal.problem.DoubleProblem;
import org.uma.jmetal.runner.AbstractAlgorithmRunner;
import org.uma.jmetal.solution.DoubleSolution;
import org.uma.jmetal.util.AlgorithmRunner;
import org.uma.jmetal.util.JMetalLogger;
import org.uma.jmetal.util.ProblemUtils;
import org.uma.jmetal.util.chartcontainer.ChartContainer;
import org.uma.jmetal.util.front.imp.ArrayFront;

/**
 * Class for configuring and running the DMOPSO algorithm
 *
 * @author Antonio J. Nebro <antonio@lcc.uma.es>
 */

public class DMOPSOMeasuresRunner extends AbstractAlgorithmRunner {
    /**
     * @param args
     *            Command line arguments.
     * @throws org.uma.jmetal.util.JMetalException
     * @throws java.io.IOException
     * @throws SecurityException
     *             Invoking command: java
     *             org.uma.jmetal.runner.multiobjective.DMOPSORunner problemName
     *             [referenceFront]
     */
    public static void main(String[] args) throws Exception {
        DoubleProblem problem;
        DMOPSO algorithm;

        String referenceParetoFront = "";

        String problemName;
        if (args.length == 1) {
            problemName = args[0];
        } else if (args.length == 2) {
            problemName = args[0];
            referenceParetoFront = args[1];
        } else {
            problemName = "org.uma.jmetal.problem.multiobjective.zdt.ZDT1";
            referenceParetoFront = "jmetal-problem/src/test/resources/pareto_fronts/ZDT1.pf";
        }

        problem = (DoubleProblem) ProblemUtils.<DoubleSolution>loadProblem(problemName);

        algorithm = new DMOPSOMeasures(problem, 100, 150, 0.0, 0.1, 0.0, 1.0, 1.5, 2.5, 1.5, 2.5, 0.1, 0.4, -1.0, -1.0,
                FunctionType.TCHE, "MOEAD_Weights", 2);

        ((DMOPSOMeasures) algorithm).setReferenceFront(new ArrayFront(referenceParetoFront));

        /* Measure management */
        MeasureManager measureManager = ((DMOPSOMeasures) algorithm).getMeasureManager();

        BasicMeasure<List<DoubleSolution>> solutionListMeasure = (BasicMeasure<List<DoubleSolution>>) measureManager
                .<List<DoubleSolution>>getPushMeasure("currentPopulation");
        CountingMeasure iterationMeasure = (CountingMeasure) measureManager.<Long>getPushMeasure("currentEvaluation");
        BasicMeasure<Double> hypervolumeMeasure = (BasicMeasure<Double>) measureManager
                .<Double>getPushMeasure("hypervolume");
        BasicMeasure<Double> epsilonMeasure = (BasicMeasure<Double>) measureManager.<Double>getPushMeasure("epsilon");

        ChartContainer chart = new ChartContainer(algorithm.getName(), 200);
        chart.SetFrontChart(0, 1, referenceParetoFront);
        chart.SetVarChart(0, 1);
        chart.AddIndicatorChart("Hypervolume");
        chart.AddIndicatorChart("Epsilon");
        chart.InitChart();

        solutionListMeasure.register(new ChartListener(chart));
        iterationMeasure.register(new IterationListener(chart));
        hypervolumeMeasure.register(new IndicatorListener("Hypervolume", chart));
        epsilonMeasure.register(new IndicatorListener("Epsilon", chart));

        /* End of measure management */

        AlgorithmRunner algorithmRunner = new AlgorithmRunner.Executor(algorithm).execute();
        chart.SaveChart("./chart", BitmapFormat.PNG);

        List<DoubleSolution> population = algorithm.getResult();
        long computingTime = algorithmRunner.getComputingTime();

        JMetalLogger.logger.info("Total execution time: " + computingTime + "ms");

        printFinalSolutionSet(population);
        if (!referenceParetoFront.equals("")) {
            printQualityIndicators(population, referenceParetoFront);
        }

    }

    private static class ChartListener implements MeasureListener<List<DoubleSolution>> {
        private ChartContainer chart;
        private int iteration = 0;

        public ChartListener(ChartContainer chart) {
            this.chart = chart;
            this.chart.getFrontChart().setTitle("Iteration: " + this.iteration);
        }

        private void refreshChart(List<DoubleSolution> solutionList) {
            if (this.chart != null) {
                iteration++;
                this.chart.getFrontChart().setTitle("Iteration: " + this.iteration);
                this.chart.UpdateFrontCharts(solutionList);
                this.chart.RefreshCharts();
            }
        }

        @Override
        synchronized public void measureGenerated(List<DoubleSolution> solutions) {
            refreshChart(solutions);
        }
    }

    private static class IterationListener implements MeasureListener<Long> {
        ChartContainer chart;

        public IterationListener(ChartContainer chart) {
            this.chart = chart;
            this.chart.getFrontChart().setTitle("Iteration: " + 0);
        }

        @Override
        synchronized public void measureGenerated(Long iteration) {
            if (this.chart != null) {
                this.chart.getFrontChart().setTitle("Iteration: " + iteration);
            }
        }
    }

    private static class IndicatorListener implements MeasureListener<Double> {
        ChartContainer chart;
        String indicator;

        public IndicatorListener(String indicator, ChartContainer chart) {
            this.chart = chart;
            this.indicator = indicator;
        }

        @Override
        synchronized public void measureGenerated(Double value) {
            if (this.chart != null) {
                this.chart.UpdateIndicatorChart(this.indicator, value);
                this.chart.RefreshCharts(0);
            }
        }
    }
}

@@ -799,70 +799,8 @@
 at;%0A
-import org.uma.jmetal.algorithm.multiobjective.dmopso.DMOPSO;%0A
 impo
@@ -2159,24 +2159,32 @@
       DMOPSO
+Measures
  algorithm;%0A
@@ -2569,16 +2569,19 @@
 ront = %22
+../
 jmetal-p
@@ -2915,34 +2915,16 @@
 %0A       
- ((DMOPSOMeasures)
  algorit
@@ -2925,17 +2925,16 @@
 lgorithm
-)
 .setRefe

Remove unnecessary casting, use DMOPSOMeasures