// EstimatorControl.java
package org.eclipse.stem.util.analysis.views;

/*******************************************************************************
 * Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018
 * IBM Corporation, BfR, and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation and new features
 *     Bundesinstitut für Risikobewertung - Pajek Graph interface, new Veterinary Models
 *******************************************************************************/

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.eclipse.birt.chart.model.attribute.ColorDefinition;
import org.eclipse.birt.chart.model.attribute.impl.ColorDefinitionImpl;
import org.eclipse.emf.common.util.EList;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.stem.core.common.util.LogInitializationException;
import org.eclipse.stem.util.analysis.Activator;
import org.eclipse.stem.util.analysis.CSVAnalysisWriter;
import org.eclipse.stem.util.analysis.PhaseSpaceCoordinate;
import org.eclipse.stem.util.analysis.ScenarioAnalysisSuite;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

/**
 * This class is a SWT GUI component that uses BIRT to plot
 */
public class LyapunovControl extends AnalysisControl {
	
		
	/**
	 * used to identify user preferences for this class
	 * This String is not human readable so does not need to be NLS'd. It is a key in a map
	 */
	private static final String CONSUMER = "LYAPUNOV_CONTROL";
	
	/**
	 * used to remember the primary directory in the user preferences
	 * This String is not human readable so does not need to be NLS'd. It is a key in a map
	 */
	private static final String PRIMARY_FOLDER_KEY = CONSUMER+"_PRIMARY";
	/**
	 * used to remember the secondary directory in the user preferences
	 * This String is not human readable so does not need to be NLS'd. It is a key in a map
	 */
	private static final String SECONDARY_FOLDER_KEY = CONSUMER+"_SECONDARY";

	/**
	 *  First Scenario Label - indicates number of regions being watched for analysis.
	 *  There are locations with relative value history providers attached
	 */
	Label firstScenarioFolderLabel;
	
	/**
	 *  Second Scenario Label - indicates number of regions being watched for analysis.
	 *  There are locations with relative value history providers attached
	 */
	Label secondScenarioFolderLabel;
	
	/**
	 *  A Label to give feedbak on the computation action
	 */
	//Label userFeedbackLabel;
	
	/**
	 * First input text field for the scenario folder of data to use in making the estimation
	 */
	Text text1;
	

	/**
	 * Second Input text field for the scenario folder of data to be compared
	 **/
	Text text2;
	

	
	
	/**
	 * A label to report status (not yet used)
	 */
	Label statusLabel;
	
	
	/**
	 * Results of analysis
	 */
	Label resultsLabel;
	
	/**
	 * the chart of two (or more) trajectories in phase space
	 */
	LyapunovTrajectoryCanvas lyapunovTrajectoryCanvas;
	
	/**
	 * the time series chart of the divergence of the Lyapunov trajectory(ies) from the reference trajectory
	 */
	TimeSeriesCanvas timeSeriesCanvas;
	/**
	 * Colors for the time series chart
	 */
	static final ColorDefinition foreGround = ColorDefinitionImpl.create(180, 0, 0);
	static final ColorDefinition backgroundGround = ColorDefinitionImpl.create(255, 255, 225);
	static final ColorDefinition frameColor = ColorDefinitionImpl.WHITE();
	
	/**
	 * Label for line series Data (legend)
	 */

	
	/**
	 * the results of various scenario comparisons
	 * TODO: eventually this might be a map keyed by comparison id
	 * for now there is only one comparison, the mean square difference.
	 */
	List<PhaseSpaceCoordinate[]> comparisonValues = new ArrayList<PhaseSpaceCoordinate[]>();
	
	/**
	 * this is the cumulative deviation between the trajectories (relative to the reference
	 * trajectory
	 */
	List<EList<Double>> cumulativeDeviation = new ArrayList<EList<Double>>();
	
	protected static final String LYAPUNOV_FILE_PREFIX = Messages.getString("LYA.TITLE");
	protected static final String LYAPUNOV_DEVIATION_FILE_PREFIX = Messages.getString("LYA.DEVIATION");
	protected static final String SELECT_FOLDER_DIALOG_TEXT = Messages.getString("LYA.SELECTFOLDERDIALG");
	
	ScenarioAnalysisSuite analyzer = new ScenarioAnalysisSuite(this);
	
	Composite parentComposite;
	
	/**
	 * 
	 * @param parent
	 */
	public LyapunovControl(final Composite parent) {
		super(parent, SWT.None);
		parentComposite = parent;
		createContents();
	} // EstimatorControl

	/**
	 * Create the contents of the plotter
	 */
	private void createContents() {
		setLayout(new FormLayout());
		Display display = this.getDisplay();

		identifiableTitle = new Label(this, SWT.BORDER);
		identifiableTitle.setText(Messages.getString("LYA.TITLE"));
		identifiableTitle.setFont(getLargerFont(18, display));
		
		
		
		
		statusLabel = new Label(this, SWT.BORDER);
		statusLabel.setText("");
		
		firstScenarioFolderLabel = new Label(this, SWT.NONE);
		//firstScenarioFolderLabel.setBackground(labelBackground);
		firstScenarioFolderLabel.setText(Messages.getString("LYA.FOLDER1LABEL"));
		
		text1 = new Text(this, SWT.BORDER);
	    text1.setBounds(10, 10, 100, 20);
	    String primaryDir=prefs.getRecentFolder(PRIMARY_FOLDER_KEY);
	    text1.setText(primaryDir);
	    
	    secondScenarioFolderLabel = new Label(this, SWT.NONE);
	    // secondScenarioFolderLabel.setBackground(labelBackground);
	    secondScenarioFolderLabel.setText(Messages.getString("LYA.FOLDER2LABEL"));
		
		text2 = new Text(this, SWT.BORDER);
	    text2.setBounds(10, 10, 100, 20);
	    String secondaryDir=prefs.getRecentFolder(SECONDARY_FOLDER_KEY);
	    text2.setText(secondaryDir);
		  
	    Composite analyzeButtonComposite = getAnalyzeButtonComposite(this,Messages.getString("LYA.COMPARISON"));

		resultsLabel = new Label(this, SWT.SHADOW_OUT);
		resultsLabel.setText("");
		
		final FormData titleFormData = new FormData();
		identifiableTitle.setLayoutData(titleFormData);
		titleFormData.top = new FormAttachment(0, 0);
		titleFormData.left = new FormAttachment(0, 0);
		titleFormData.right = new FormAttachment(25, 0);
		
		final FormData resultsFormData = new FormData();
		resultsLabel.setLayoutData(resultsFormData);
		resultsFormData.top = new FormAttachment(0, 0);
		resultsFormData.left = new FormAttachment(25, 0);
		resultsFormData.right = new FormAttachment(75, 0);

		int spacer = 10;
		int buttonspacer = 5;
		
        /////////////////////////////////////////////////////////////////////////
		// TextField folder label
		final FormData firstScenarioFolderLabelFormData = new FormData();
		// propertySelectorFormData.top = new FormAttachment(cSVLoggerCanvas,
		// 0);
		firstScenarioFolderLabelFormData.top = new FormAttachment(identifiableTitle, spacer);
		//firstScenarioFolderLabelFormData.bottom = new FormAttachment(bottom, 0);
		firstScenarioFolderLabelFormData.left = new FormAttachment(0, 0);
		firstScenarioFolderLabelFormData.right = new FormAttachment(15, 0);
		firstScenarioFolderLabel.setLayoutData(firstScenarioFolderLabelFormData);

		// first text field for parameter Estimator
		final FormData text1FormData = new FormData();
		text1FormData.top = new FormAttachment(identifiableTitle, spacer);
		text1FormData.left = new FormAttachment(firstScenarioFolderLabel, 5);
		text1FormData.right = new FormAttachment(85, 0);
		text1.setLayoutData(text1FormData);
		
		Button selectFolder1Button = new Button(this, SWT.NONE);
		selectFolder1Button.setText(Messages.getString("LYA.SELECTFOLDER"));
		final FormData selectFolder1FormData = new FormData();
		selectFolder1FormData.top = new FormAttachment(identifiableTitle, buttonspacer);
		//selectFolder1FormData.bottom = new FormAttachment(bottom, 0);
		selectFolder1FormData.left = new FormAttachment(text1, 5);
		selectFolder1Button.setLayoutData(selectFolder1FormData);
		
		final Shell shell = this.getShell();
		
		selectFolder1Button.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(@SuppressWarnings("unused")
			final SelectionEvent e) {
				final DirectoryDialog dd = new DirectoryDialog(
						shell, SWT.OPEN);
					dd.setText(Messages.getString("LYA.SELECTFOLDERDIALOG")); //$NON-NLS-1$
					String beginSearch = text1.getText();
					if((beginSearch==null)||(beginSearch.length()<1)) beginSearch = ROOT_PATH;
					
					dd.setFilterPath(beginSearch);
					final String selected = dd.open();
					if(selected!=null) text1.setText(selected);
			}
		});
        /////////////////////////////////////////////////////////////////////////
		
	//	bottom += deltaBottom;
		
        /////////////////////////////////////////////////////////////////////////
		// TextField folder label
		final FormData secondScenarioFolderLabelFormData = new FormData();
		// propertySelectorFormData.top = new FormAttachment(cSVLoggerCanvas,
		// 0);
		secondScenarioFolderLabelFormData.top = new FormAttachment(firstScenarioFolderLabel, spacer);
		secondScenarioFolderLabelFormData.left = new FormAttachment(0, 0);
		secondScenarioFolderLabelFormData.right = new FormAttachment(15, 0);
		secondScenarioFolderLabel.setLayoutData(secondScenarioFolderLabelFormData);

		// first text field for parameter Estimator
		final FormData text2FormData = new FormData();
		text2FormData.top = new FormAttachment(firstScenarioFolderLabel, spacer);
		text2FormData.left = new FormAttachment(secondScenarioFolderLabel, 5);
		text2FormData.right = new FormAttachment(85, 0);
		text2.setLayoutData(text2FormData);
		
		Button selectFolder2Button = new Button(this, SWT.NONE);
		selectFolder2Button.setText(Messages.getString("LYA.SELECTFOLDER"));
		final FormData selectFolder2FormData = new FormData();
		selectFolder2FormData.top = new FormAttachment(firstScenarioFolderLabel, buttonspacer);
		selectFolder2FormData.left = new FormAttachment(text2, 5);
		selectFolder2Button.setLayoutData(selectFolder2FormData);
		
		selectFolder2Button.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(@SuppressWarnings("unused")
			final SelectionEvent e) {
				final DirectoryDialog dd = new DirectoryDialog(
						shell, SWT.OPEN);
					dd.setText(SELECT_FOLDER_DIALOG_TEXT); //$NON-NLS-1$
					String beginSearch = text2.getText();
					if((beginSearch==null)||(beginSearch.length()<1)) beginSearch = ROOT_PATH;
					
					dd.setFilterPath(beginSearch);
					final String selected = dd.open();
					if(selected!=null) text2.setText(selected);
			}
		});
		
		/////////////////////////////////////////////////////////////////////////
		
	//	bottom += deltaBottom;
		// AnalyzeButton
		final FormData analysisButtonFormData = new FormData();
		// propertySelectorFormDataX.top = new FormAttachment(propertySelectorY,
		// 0);
		analysisButtonFormData.top = new FormAttachment(secondScenarioFolderLabel, spacer);
		//analysisButtonFormData.bottom = new FormAttachment(bottom, 0);
		analysisButtonFormData.left = new FormAttachment(0, 0);
		analysisButtonFormData.right = new FormAttachment(100, 0);
		analyzeButtonComposite.setLayoutData(analysisButtonFormData);
		
		
		
		// Trajectories
		lyapunovTrajectoryCanvas = new LyapunovTrajectoryCanvas(this);
		final FormData trajectoryChartFormData = new FormData();
		lyapunovTrajectoryCanvas.setLayoutData(trajectoryChartFormData);
		trajectoryChartFormData.top = new FormAttachment(analyzeButtonComposite, 0);
		trajectoryChartFormData.bottom = new FormAttachment(100, 0);
		trajectoryChartFormData.left = new FormAttachment(0, 0);
		trajectoryChartFormData.right = new FormAttachment(50, 0);
		
		// divergence graph
		timeSeriesCanvas = new TimeSeriesCanvas(this,
													Messages.getString("LYA.DIVERGENCELEGEND"),
													Messages.getString("LYA.DIVERGENCEYAXIS"),
													Messages.getString("LYA.DIVERGENCEYAXIS"),
													foreGround,
													backgroundGround,
													frameColor, 0);
		
		
		
		final FormData analysisChartFormData = new FormData();
		timeSeriesCanvas.setLayoutData(analysisChartFormData);
		analysisChartFormData.top = new FormAttachment(analyzeButtonComposite, 0);
		analysisChartFormData.bottom = new FormAttachment(100, 0);
		analysisChartFormData.left = new FormAttachment(50, 0);
		analysisChartFormData.right = new FormAttachment(100, 0);
		
		
		final ProgressMonitorDialog progressDialog = new ProgressMonitorDialog(this.getShell());

		analyzeButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(@SuppressWarnings("unused")
			final SelectionEvent e) {
				
				String referenceDirectory  = text1.getText();
				String comparisonDirectory = text2.getText();
				Display display = parentComposite.getDisplay();
				/*
				 * reset the label text
				 */
			    identifiableTitle.setText(Messages.getString("LYA.TITLE"));
			    resultsLabel.setText(Messages.getString("LYA.WORKING"));
			    /*
				 * reinitialize the graph
				 */
				comparisonValues.clear();
				cumulativeDeviation.clear();
				lyapunovTrajectoryCanvas.reset();
			    
				/*
				 * VALIDATE the text input Fields
				 */
				if(!analyzer.validate(referenceDirectory)) {
					identifiableTitle.setText(ScenarioAnalysisSuite.NOT_FOUND_MSG);
					text1.setText("");
				}
                if(!analyzer.validate(comparisonDirectory)) {
                	identifiableTitle.setText(ScenarioAnalysisSuite.NOT_FOUND_MSG);
                	text2.setText("");
				}
                if((!analyzer.validate(referenceDirectory)) || (!analyzer.validate(comparisonDirectory))) {
                	return;
                }
                
				try {
					
					List<PhaseSpaceCoordinate[]> data = analyzer.getLyapunovTrajectory(referenceDirectory, comparisonDirectory, progressDialog);
					if(data==null) {
						resultsLabel.setBackground(display.getSystemColor(SWT.COLOR_RED));
					    resultsLabel.setText(Messages.getString("LYA.ERROR1"));
					    
					} else {
						comparisonValues.addAll(data);
						//success... remember the users prefs
						prefs.setRecentFolder(PRIMARY_FOLDER_KEY,referenceDirectory);
						prefs.setRecentFolder(SECONDARY_FOLDER_KEY,comparisonDirectory);
						
						cumulativeDeviation.addAll(ScenarioAnalysisSuite.getCumulativePhaseSpaceDeviation(comparisonValues));
						
						//
						// now udate everything
						//
						lyapunovTrajectoryCanvas.draw();
						// Log the trajectory data
						String outFileName = LYAPUNOV_FILE_PREFIX+"_"+
						 getScenarioNameFromDirectoryName(referenceDirectory)+
						 "_"+
						 getScenarioNameFromDirectoryName(comparisonDirectory);
						
						CSVAnalysisWriter writer = new CSVAnalysisWriter(outFileName);
						writer.logData(2,comparisonValues);

						// Log the cumulative deviation data
						outFileName = LYAPUNOV_DEVIATION_FILE_PREFIX+"_"+
						 getScenarioNameFromDirectoryName(referenceDirectory)+
						 "_"+
						 getScenarioNameFromDirectoryName(comparisonDirectory);
						 CSVAnalysisWriter writer2 = new CSVAnalysisWriter(outFileName);
						 writer2.logData(cumulativeDeviation);
						 timeSeriesCanvas.draw();
						 resultsLabel.setText(Messages.getString("LYA.COMPLETE"));
					}
 					
				} catch(LogInitializationException sie) {
					Activator.logError("", sie);
				}
				
				// done
			}
		});
		
	} // createContents
	
	
	


	/**
	 * @param dirName
	 * @return short name of scenario
	 */
	public static String getScenarioNameFromDirectoryName(String dirName) {
		int last = dirName.lastIndexOf("/");
		int last2 = dirName.lastIndexOf("\\");
		if (last2 > last)
			last = last2;
		if (last <= 0)
			last = 0;
		String retVal = dirName.substring(last + 1, dirName.length());
		return retVal;
	}
	
	/**
	 * This returns the results of a comparison of type comparisonType
	 * as an array of double. 
	 * 
	 * @param trajectory the trajectory to return
	 * @return comparison
	 */
	public PhaseSpaceCoordinate[] getPointValues(int trajectory) {
		
		return comparisonValues.get(trajectory);
	}
	
	/**
	 * returns the analysis of lyapunov tractory(ies) relative to reference.
	 * @param chartIndex not used (only one chart)
	 * @param trajectory 
	 * @return Cumulative deviation from reference trajectory
	 */
	@SuppressWarnings("boxing")
	@Override
	public double[] getValues(int chartIndex, int trajectory) {
		
		EList<Double> l = cumulativeDeviation.get(trajectory);
		double [] res = new double[l.size()];
		for(int i=0;i<res.length;++i) res[i] = l.get(i);
		return res;
	}

	/**
	 * Not used
	 * @param chartIndex not used (only one chart)
	 * @param state
	 * @return property name
	 */
	@Override
	public String getProperty(int chartIndex, int state) {
		return Messages.getString("LYA.DIVERGENCEYAXIS");
	}
	
	/**
	 * Only one property to plot = the RMS difference
	 * @param chartIndex not used (only one chart)
	 * @return the number of properties
	 * @see org.eclipse.stem.util.analysis.views.AnalysisControl#getNumProperties(int chartIndex)
	 */
	@Override
	public int getNumProperties(int chartIndex) {
		return 1;
	}


	
	
	/**
	 * to remove the control e.g. by a remove button event
	 */
	@Override
	public void remove() {
		updateStatusLabel();
	}

	
	

	protected void updateStatusLabel() {
		statusLabel.setText(Messages.getString("COMMON.STATUS"));
	}
	
	

	/**
	 * Initialize the header label
	 * 
	 * @param folderName
	 */
	@Override
	protected void initializeHeader(String folderName) {
		simulationNameLabel.setText("analyzing "+folderName);

	} // initializeFromSimulation


	
	
	

	/**
	 * @see org.eclipse.swt.widgets.Widget#dispose()
	 */
	@Override
	public void dispose() {
						
		super.dispose();
		
	} // dispose

	/**
	 * Each Control class may add objects to this map
	 * @return the control parameters maps
	 */
	public Map<String, Object> getControlParametersMap() {
		// add nothing for now
		return controlParametersMap;
	}
	

} // EstimatorControl
