// AutoExpControl.java
package org.eclipse.stem.analysis.automaticexperiment.views;

/*******************************************************************************
 * Copyright (c) 2007, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

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

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.resource.ImageRegistry;
import org.eclipse.stem.analysis.ErrorResult;
import org.eclipse.stem.analysis.automaticexperiment.ALGORITHM_STATUS;
import org.eclipse.stem.analysis.automaticexperiment.AutomaticExperimentManager;
import org.eclipse.stem.analysis.automaticexperiment.AutomaticExperimentManagerEvent;
import org.eclipse.stem.analysis.automaticexperiment.AutomaticExperimentManagerListener;
import org.eclipse.stem.analysis.automaticexperiment.ErrorAnalysisAlgorithm;
import org.eclipse.stem.analysis.automaticexperiment.ErrorAnalysisAlgorithmEvent;
import org.eclipse.stem.analysis.automaticexperiment.ErrorAnalysisAlgorithmListener;
import org.eclipse.stem.analysis.automaticexperiment.MANAGER_STATUS;
import org.eclipse.stem.core.common.Identifiable;
import org.eclipse.stem.ui.ISharedImages;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Text;

/**
 * This class is a SWT GUI component that uses BIRT to plot
 */
public class AutoExpControl extends AnalysisControl {
	
	
	private static Display display = null;
	
	private ImageRegistry imageRegistry = null;
	
	private static AutomaticExperimentManager manager = null;
	
	/**
	 * Folder to contain the data
	 * 
	 */
	static CTabFolder tabFolder;
	
	static boolean pauseTrigger = false;
	
	static double[] referenceIncidence;
	static double[] modelIncidence;
	
	
	/**
	 * A label to report status (not yet used)
	 */
	//static Label statusLabel;
	
	/**
	 * stop button
	 */
	 Button stopButton = null;
	
	 /**
	  * restart button
	  */
	 Button restartButton = null; 
	/**
	 * 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();
	
	// some colors
	private static Color cyan;
	private static Color cyanDark;
	private static Color darkRed;
	private static Color white;
	private static Color lightGreen;
	private static Color lightBlue;
	
	
	
	protected static RunHistoryCanvas errorConvergenceByRun = null;
	static final int ERROR_CONVERGENCE_BY_RUN_ID = 0;
	
	protected static ErrorTimeSeriesCanvas currentErrorByTime = null;
	static final int CURRENT_ERROR_BY_TIME_ID = 1;
	
	protected static AggregateTimeSeriesCanvas aggregateErrorByTime = null;
	static final int AGGREGATE_BY_TIME_ID = 2;


	private static final int NUMROWS = 10;
	
	//protected static Composite chartComposite;
	protected static Composite errorTimeSeriesComposite;
	protected static Composite aggregateTimeSeriesComposite;
	protected static Composite runHistoryComposite;
	protected static Composite valuesComposite;
	protected static Composite controlsComposite;
	protected static Composite controlsActionComposite;
	protected static Composite controlsValuesComposite;
	protected static Composite settingsComposite;
	
	private static List<Double> errorHistoryList = new ArrayList<Double>();
	private static double[] errorHistory;
	private static double[] bestSeries;
	private static double bestError = Double.MAX_VALUE;
	private static double bestVError = Double.MAX_VALUE;
	private static double[] newErrorTimeSeries;
	
	protected static String[] runParamNames;
	protected static double[] bestParamValues;
	
	protected static double[][] recentParamValues;
	protected static double[] restartParamValues;
	protected static double[] recentErrors;
	protected static double[] recentVErrors;
	
	protected static CLabel[] attributeLabels;
	protected static CLabel[] controlLabels;
	protected static Text[] bestValueLabels;
	
	protected static Text[][] recentValueLabels;
	protected static Text[]   restartValues;
	
	protected static short row = 0; // which row are we updating
	
	protected static short numColumns = 0;
	
	/**
	 * restart sim uses latest vals or best
	 */
	protected static boolean restartWithLatest= true;
	
	/**
	 * The dialog for the wizard
	 */
	//static WizardDialog wizardDialog;	
	
	//PropertySelector propertySelector;
	//List<ItemPropertyDescriptor> selectedProperties;

	/**
	 * 
	 * @param parent
	 */
	public AutoExpControl(final Composite parent) {
		super(parent, SWT.None);
		createContents();
	} // AutoExpControl
	
	

	/**
	 * Create the contents of the plotter
	 */
	void createContents() {
				
		// Set the image registry
		if (imageRegistry == null) {
			org.eclipse.stem.ui.Activator activator = org.eclipse.stem.ui.Activator.getDefault();
			imageRegistry = activator.getImageRegistry();
		}
		// Use form layout
		setLayout(new FormLayout());
		if(display==null) display = this.getDisplay();
		cyan = display.getSystemColor(SWT.COLOR_CYAN);
		cyanDark = new Color(display, 60, 220, 220);
		darkRed = display.getSystemColor(SWT.COLOR_DARK_RED);
		white = display.getSystemColor(SWT.COLOR_WHITE);
		lightGreen = new Color(display, 128, 255, 128);
		lightBlue = new Color(display, 128, 128, 255);
		
		
		identifiableTitle = new Label(this, SWT.NONE);
		identifiableTitle.setText(Messages.getString("AUTO.TITLELABEL"));
		
		
		int bottom = 5;
		final FormData titleFormData = new FormData();
		identifiableTitle.setLayoutData(titleFormData);
		titleFormData.top = new FormAttachment(0, 0);
		titleFormData.bottom = new FormAttachment(bottom, 0);
		titleFormData.left = new FormAttachment(0, 0);
		titleFormData.right = new FormAttachment(100, 0);
		
		bottom += 1;
		
		tabFolder = new CTabFolder(this, SWT.BORDER);
		// set up the values composite
		valuesComposite = new Composite(tabFolder, SWT.BORDER);
		
		final FormData tabFormData = new FormData();
		tabFormData.top = new FormAttachment(bottom, 0);
		tabFormData.bottom = new FormAttachment(100, 0);
		tabFormData.left = new FormAttachment(0, 0);
		tabFormData.right = new FormAttachment(100, 0);
		tabFolder.setLayoutData(tabFormData);
		tabFolder.setSimple(false);
		
		
		tabFolder.setSelectionBackground(new Color[]{
				cyan,
				white,
				lightBlue,
				lightBlue},
				new int[] {25, 50, 100}); 
		

		tabFolder.setSelectionForeground(display.getSystemColor(SWT.COLOR_BLACK)); 
		
		tabFolder.setBackground(cyanDark);
		tabFolder.setForeground(darkRed);
		tabFolder.setBorderVisible(true);
		
        /////////////
		// RUN HISTORY
		CTabItem item0 = new CTabItem(tabFolder, SWT.BORDER);
		item0.setText ("  "+Messages.getString("AUTO.HISTORY")+" ");
		runHistoryComposite = new Composite(tabFolder, SWT.BORDER);
		runHistoryComposite.setLayout(new FormLayout());
 		item0.setControl(runHistoryComposite);
 		// set up the four data time series inside the chartComposite
 		getRunHistoryChart(runHistoryComposite); 
 		
 		/////////////
		// AGGREGATE TIME SERIES
 		CTabItem item1 = new CTabItem(tabFolder, SWT.BORDER);
		item1.setText ("  "+Messages.getString("AUTO.AGGREGATESERIES")+" ");
		aggregateTimeSeriesComposite = new Composite(tabFolder, SWT.BORDER);
		aggregateTimeSeriesComposite.setLayout(new FormLayout());
 		item1.setControl(aggregateTimeSeriesComposite);
 		// set up the four data time series inside the chartComposite
 		getAggregateTimeSeriesChart(aggregateTimeSeriesComposite); 
 		
 		/////////////
		// ERROR TIME SERIES
 		CTabItem item2 = new CTabItem(tabFolder, SWT.BORDER);
		item2.setText ("  "+Messages.getString("AUTO.ERRORSERIES")+" ");
		errorTimeSeriesComposite = new Composite(tabFolder, SWT.BORDER);
		errorTimeSeriesComposite.setLayout(new FormLayout());
 		item2.setControl(errorTimeSeriesComposite);
 		// set up the four data time series inside the chartComposite
 		getErrorTimeSeriesChart(errorTimeSeriesComposite); 
 		
 		//////////////
 		// VALUES
		CTabItem item3 = new CTabItem(tabFolder, SWT.BORDER);
		item3.setText(Messages.getString("AUTO.VALUES"));
		item3.setControl(valuesComposite);
		
		//////////////
 		// Controls
		controlsComposite = new Composite(tabFolder, SWT.BORDER);
		getControls();
		CTabItem item4 = new CTabItem(tabFolder, SWT.BORDER);
		item4.setText(Messages.getString("AUTO.CONTROLS"));
		item4.setControl(controlsComposite);
		
		//////////////
 		// Settings
//		settingsComposite = new Composite(tabFolder, SWT.BORDER);
//		getSettings();
//		CTabItem item4 = new CTabItem(tabFolder, SWT.BORDER);
//		item4.setText(Messages.getString("AUTO.SETTINGS"));
//		item4.setControl(settingsComposite);
		
		
		
		tabFolder.setSelection(item0);
		if(manager==null) {
			manager = AutomaticExperimentManager.getInstance();
			manager.addListener(new AutomaticExperimentManagerListener() {
				
				public void eventReceived(AutomaticExperimentManagerEvent evt) {
					if(evt.status == MANAGER_STATUS.SCHEDULED) {
						ErrorAnalysisAlgorithm alg = evt.algorithm;
						display.syncExec(new Runnable() {
							public void run() {
								AutoExpControl.this.reset();
								AutoExpControl.this.stopButton.setEnabled(true);
								restartButton.setEnabled(false);
							}
						});
						alg.addListener(new ErrorAnalysisAlgorithmListener() {
							public void eventReceived(ErrorAnalysisAlgorithmEvent evt) {
																
								if(evt.status == ALGORITHM_STATUS.STARTING_SIMULATION) {
									// set the label info
									runParamNames = evt.parameterNames;
									if(recentParamValues == null) {
										numColumns = (short)runParamNames.length;
										recentParamValues = new double[NUMROWS][runParamNames.length+1];
										restartParamValues = new double[runParamNames.length];
										
										recentErrors = new double[NUMROWS];
										recentVErrors = new double[NUMROWS];
									} 
									
									if(row < NUMROWS) {
										recentParamValues[row] = copyDoubleArray(evt.parameterValues);
										recentErrors[row] = -1; // not known yet
										recentVErrors[row++] = -1; // not known yet
									} else {
										// We need to shift up
										for(int i=0;i<NUMROWS-1;++i) {
											for(int j=0;j<runParamNames.length;++j) recentParamValues[i][j] = recentParamValues[i+1][j];
											recentErrors[i]=recentErrors[i+1];
											recentVErrors[i]=recentVErrors[i+1];
											
										}
										recentParamValues[row-1] = copyDoubleArray(evt.parameterValues);
										recentErrors[row-1] = -1; // not known yet
										recentVErrors[row-1] = -1; // not known yet
									}
									
									// copy all but the error - it is not a parameter
									for(int i = 0; i < (restartParamValues.length); i ++) {
										if(restartWithLatest) {
											if(recentParamValues!=null) restartParamValues[i] = recentParamValues[row-1][i];
										} else {
											if(bestParamValues!=null) restartParamValues[i] = bestParamValues[i];
										}
										
									}
									
									// Add a Runnable to the UI thread's execution queue 
									final Display display = Display.getDefault();
									if (!display.isDisposed()) {
										// Yes
										try {
											display.asyncExec(new Runnable() {
												public void run() {
													if(!valuesInitialized) {
														initializeValueLabels(runParamNames);
														initializeControlLabels(runParamNames);
													}
													updateValueLabels();
												} // run
											}); // display.asyncExec
										} // try
										catch (final Exception e) {
											// Ignore there could be a race condition with the display being disposed
										} // catch Exception
									} // if (!display.isDisposed()) 
								//////////////////////////////////////
								} else if(evt.status == ALGORITHM_STATUS.FINISHED_ALGORITHM) {
									// The algorithm has finished. Smallest value in 
									//evt.result
									/////////////////
									display.asyncExec(new Runnable() {
										public void run() {
											restartButton.setEnabled(true);
											stopButton.setEnabled(false);
										}
									});
								} else if(evt.status == ALGORITHM_STATUS.FINISHED_SIMULATION) {
									// One simulation is done. The result is READY and stored in evt.result
									ErrorResult result = evt.result;
									final double plottableError = plottableError(result.getError());
									recentErrors[row-1] = evt.result.getError();
									recentVErrors[row-1] = evt.result.getValidationError();
									
									if(result != null) {
										// Plot 1 from result.getError() (keep appending)
										appendLatestErrorData(plottableError);
										// Plot 2 from result.getErrorByTimestep() (same as we show in scenario comparison view)
										setRecentTimeSeries(result.getError(), result.getValidationError(), result.getErrorByTimeStep(), result.getReferenceByTime(), result.getModelByTime() );
										
										if(bestParamValues == null) {
											bestParamValues = copyDoubleArray(recentParamValues[row-1]);
											bestError = result.getError();
											bestVError = result.getValidationError();
										}
										
										////////////////////////////////////////////////////////////////////////
										// Add a Runnable to the UI thread's execution queue 
										final Display display = Display.getDefault();
										if (!display.isDisposed()) {
											// Yes
											try {
												display.asyncExec(new Runnable() {
													public void run() {
														updateCharts();
														updateValueLabels();
													} // run
												}); // display.asyncExec
											} // try
											catch (final Exception e) {
												// Ignore there could be a race condition with the display being disposed
											} // catch Exception
										} // if (!display.isDisposed()) 
									}// if(result != null)
								} else if(evt.status == ALGORITHM_STATUS.RESTARTED_ALGORITHM) {
									// The algorithm has restarted. Smallest value in 
									// evt.result
								}
							}
						});
					}
				}
			});
			
		}// if(manager null)
		
		
		updateCharts();
		
	} // createContents
	
	/**
	 * filter +ve, -ve infinity, etc
	 * @param error
	 * @return
	 */
	static double plottableError(double error) {
		if((error==Double.POSITIVE_INFINITY)
											||(error==Double.NEGATIVE_INFINITY)
											||Double.isNaN(error)
											||(error==Double.MAX_VALUE)) {
			return 100.0;
		} else {
			return error;
		}
				
				
	}
	
	private void reset() {
		// Reset everything at the beginning of an automated experiment
		errorHistory = new double[1];
		errorHistory[0] = 0;
		
		newErrorTimeSeries = new double[1];
		newErrorTimeSeries[0] = 0;
		
		referenceIncidence = new double[1];
		referenceIncidence[0] = 0;
		
		modelIncidence = new double[1];
		modelIncidence[0] = 0;
		
		errorConvergenceByRun.resetData();
		currentErrorByTime.resetData();
		aggregateErrorByTime.resetData();
		//errorConvergenceByRun.clearData();
		//currentErrorByTime.clearData();
		errorHistoryList = new ArrayList<Double>();
		
		bestSeries = null;
		bestError = Double.MAX_VALUE;
		bestVError = Double.MAX_VALUE;
		
		runParamNames = null;
		bestParamValues = null;
		restartParamValues = null;
		recentParamValues = null;
		recentErrors = null;
		recentVErrors = null;
		
		if(attributeLabels != null)
			for(int i=0;i<attributeLabels.length;++i) {
			attributeLabels[i].dispose();
			attributeLabels[i] = null;
		}
		attributeLabels = null;
		if(bestValueLabels != null) 
			for(int i=0;i<bestValueLabels.length;++i) {
				bestValueLabels[i].dispose();
				bestValueLabels[i] = null;
			}
		bestValueLabels = null;
		
		if(recentValueLabels != null)
			for(int i=0;i<recentValueLabels.length;++i)
				for(int j=0;j<recentValueLabels[i].length;++j) {
					recentValueLabels[i][j].dispose();
					recentValueLabels[i][j] = null;
				}
		recentValueLabels = null;
		
		if(controlLabels != null)
			for(CLabel lab:controlLabels) lab.dispose(); 
		
		controlLabels = null;
		
		
		if(restartValues!=null)
			for(Text t:restartValues) t.dispose();
		
		row = 0; 
		numColumns = 0;
		valuesInitialized = false;
	}
	
	/**
	 * update the graphs
	 */
	public static void updateCharts() {
		errorConvergenceByRun.draw();
		currentErrorByTime.draw();
		aggregateErrorByTime.draw();
	}
	
	/**
	 * redraw the graphs
	 */
	public static void redrawCharts() {
		errorConvergenceByRun.redraw();
		currentErrorByTime.redraw();
		aggregateErrorByTime.redraw();
	}
	
	
	
	/**
	 * set up the time series chart
	 * @param dataComposite
	 */
	private void getErrorTimeSeriesChart(Composite dataComposite) {
				
		// currentErrorByTime
		currentErrorByTime = new ErrorTimeSeriesCanvas(this,dataComposite,
				Messages.getString("AUTO.TITLE2"),
				Messages.getString("AUTO.ERROR"),// y axis
				Messages.getString("AUTO.TIME"),// x axis
				Messages.getString("AUTO.TITLE2"), //first property (line series name)
				foreGround,
				backgroundGround,
				frameColor, CURRENT_ERROR_BY_TIME_ID, true);
		final FormData timeSeriesFormData = new FormData();
		currentErrorByTime.setLayoutData(timeSeriesFormData);
		timeSeriesFormData.top = new FormAttachment(dataComposite, 0);
		timeSeriesFormData.bottom = new FormAttachment(100, 0);
		timeSeriesFormData.left = new FormAttachment(0, 0);
		timeSeriesFormData.right = new FormAttachment(100, 0);
		
		currentErrorByTime.redraw();
		
	}// getErrorTimeSeries
	
	/**
	 * set up the time series chart
	 * @param dataComposite
	 */
	private void getAggregateTimeSeriesChart(Composite dataComposite) {
				
		// currentErrorByTime
		aggregateErrorByTime = new AggregateTimeSeriesCanvas(this,dataComposite,
				Messages.getString("AUTO.TITLE4"),
				Messages.getString("AUTO.INCIDENCE"),// y axis
				Messages.getString("AUTO.TIME"),// x axis
				Messages.getString("AUTO.TITLE4"), //first property (line series name)
				foreGround,
				backgroundGround,
				frameColor, AGGREGATE_BY_TIME_ID, true);
		final FormData timeSeriesFormData = new FormData();
		aggregateErrorByTime.setLayoutData(timeSeriesFormData);
		timeSeriesFormData.top = new FormAttachment(dataComposite, 0);
		timeSeriesFormData.bottom = new FormAttachment(100, 0);
		timeSeriesFormData.left = new FormAttachment(0, 0);
		timeSeriesFormData.right = new FormAttachment(100, 0);
		
		aggregateErrorByTime.redraw();
		
	}// getAggregateTimeSeries
	
	
	/**
	 * set up the run history charts
	 * @param dataComposite
	 */
	private void getRunHistoryChart(Composite dataComposite) {
		// errorConvergenceByRun
		errorConvergenceByRun = new RunHistoryCanvas(this,dataComposite,
				Messages.getString("AUTO.TITLE1"),
				Messages.getString("AUTO.ERROR"), // yaxis
				Messages.getString("AUTO.RUN"),// x axis
				Messages.getString("AUTO.TITLE1"), // first propery (line series name)
				foreGround,
				backgroundGround,
				frameColor, ERROR_CONVERGENCE_BY_RUN_ID, true);
		final FormData TimeSeries1FormData = new FormData();
		errorConvergenceByRun.setLayoutData(TimeSeries1FormData);
		TimeSeries1FormData.top = new FormAttachment(dataComposite, 0);
		TimeSeries1FormData.bottom = new FormAttachment(100, 0);
		TimeSeries1FormData.left = new FormAttachment(0, 0);
		TimeSeries1FormData.right = new FormAttachment(100, 0);
		
		errorConvergenceByRun.redraw();
	
	}// getEquationSeries
	
	
	/**
	 * set up the controls
	 * @param dataComposite
	 */
	private void getControls() {
		
		controlsComposite.setLayout(new FormLayout());
		
		final FormData controlTopFormData = new FormData();
		controlsActionComposite = new Composite(controlsComposite,SWT.BORDER);
		controlsActionComposite.setLayoutData(controlTopFormData);
		controlTopFormData.top = new FormAttachment(0, 0);
		controlTopFormData.bottom = new FormAttachment(20, 0);
		controlTopFormData.left = new FormAttachment(0, 0);
		controlTopFormData.right = new FormAttachment(100, 0);
		
		
		final FormData controlBottomFormData = new FormData();
		controlsValuesComposite = new Composite(controlsComposite,SWT.BORDER);
		controlsValuesComposite.setLayoutData(controlBottomFormData);
		controlBottomFormData.top = new FormAttachment(controlsActionComposite, 0);
		controlBottomFormData.bottom = new FormAttachment(100, 0);
		controlBottomFormData.left = new FormAttachment(0, 0);
		controlBottomFormData.right = new FormAttachment(100, 0);
		
		
		// Use form layout
		GridLayout gridLayout = new GridLayout();
		gridLayout.numColumns = 5;
		gridLayout.makeColumnsEqualWidth = true;
		controlsActionComposite.setLayout(gridLayout);
		
//		// row 0 PAUSE
//		// c1
//		CLabel pauseLabel = new CLabel(controlsActionComposite, SWT.NONE);
//		pauseLabel.setText(Messages.getString("AUTO.PAUSE"));
//		// c2
//		Button pauseButton = new Button(controlsActionComposite, SWT.TOGGLE);
//		pauseButton.setImage(imageRegistry.get(ISharedImages.PAUSE_ICON));
//		// c3
//		CLabel noLabela = new CLabel(controlsActionComposite, SWT.NONE);
//		noLabela.setText("");
//		///////////////////////
//		// c4
//		CLabel noLabelb = new CLabel(controlsActionComposite, SWT.NONE);
//		noLabelb.setText("");
//		// c5
//		CLabel noLabelc = new CLabel(controlsActionComposite, SWT.NONE);
//		noLabelc.setText("");
		
		// row 1
		// c1.
		CLabel stopLabel = new CLabel(controlsActionComposite, SWT.NONE);
		stopLabel.setText(Messages.getString("AUTO.STOP"));
		// c2
		stopButton = new Button(controlsActionComposite, SWT.PUSH);
		stopButton.setImage(imageRegistry.get(ISharedImages.STOP_ICON));
		stopButton.setEnabled(false); // we'll enable when an experiment is started
		// c3
		CLabel noLabel1 = new CLabel(controlsActionComposite, SWT.NONE);
		noLabel1.setText("");
		
		Button[] radios = new Button[2];

		radios[0] = new Button(controlsActionComposite, SWT.RADIO);
	    radios[0].setSelection(true);
	    radios[0].setText(Messages.getString("AUTO.LATEST"));
	    radios[0].setBounds(10, 5, 75, 30);

	    radios[1] = new Button(controlsActionComposite, SWT.RADIO);
	    radios[1].setText(Messages.getString("AUTO.BEST"));
	    radios[1].setBounds(10, 30, 75, 30);
	    radios[0].setSelection(true);
		
		
		
		// row 2
		// c1
		CLabel restartLabel = new CLabel(controlsActionComposite, SWT.NONE);
		restartLabel.setText(Messages.getString("AUTO.RESTART"));
		// c2
		restartButton = new Button(controlsActionComposite, SWT.PUSH);
		restartButton.setImage(imageRegistry.get(ISharedImages.RESTART_ICON));
		restartButton.setEnabled(false);
		// c3
		CLabel paramsLabel = new CLabel(controlsActionComposite, SWT.NONE);
		paramsLabel.setText(Messages.getString("AUTO.RESTART_HEADER"));
		///////////////////////
		// c4
		CLabel noLabel2 = new CLabel(controlsActionComposite, SWT.NONE);
		noLabel2.setText("");
		// c5
		CLabel noLabel3 = new CLabel(controlsActionComposite, SWT.NONE);
		noLabel3.setText("");
		
		
		
		
		// ACTIONS
//		pauseButton.addListener(SWT.Selection, new Listener() {
//			public void handleEvent(Event e) {
//				switch (e.type) {
//				case SWT.Selection:
//					// toggle
//					pauseTrigger = !pauseTrigger;
//					if(pauseTrigger) {
//						AutomaticExperimentManager.pause();
//					} else {
//						AutomaticExperimentManager.continueRun();
//					}
//					
//					break;
//				}
//			}
//		});
		
		stopButton.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				switch (e.type) {
				case SWT.Selection:
					stopButton.setEnabled(false);
					AutomaticExperimentManager.getInstance().quitNow();
					restartButton.setEnabled(true);
					break;
				}
			}
		});
		
		restartButton.addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				switch (e.type) {
				case SWT.Selection:
					AutomaticExperimentManager.getInstance().restartNow(restartParamValues);
					break;
				}
			}
		});
		
		radios[0].addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				switch (e.type) {
				case SWT.Selection:
					selectLatestAction();
					break;
				}
			}
		});
		radios[1].addListener(SWT.Selection, new Listener() {
			public void handleEvent(Event e) {
				switch (e.type) {
				case SWT.Selection:
					selectBestAction();
					break;
				}
			}
		});

		controlsComposite.pack();
		controlsComposite.layout();
		controlsComposite.setVisible(true);
		
	}// getControls
	
	
	/**
	 * set up the controls
	 * @param dataComposite
	 */
	private void getSettings() {
		
		settingsComposite.setLayout(new FormLayout());
		
		
		settingsComposite.pack();
		settingsComposite.layout();
		settingsComposite.setVisible(true);
		
	}// getSETTINGS
	
	
	
	
	
	
	/**
	 * 
	 */
	private static void selectLatestAction() {
		restartWithLatest = true;
		if(bestParamValues!=null) {
			for(int i = 0; i < (bestParamValues.length) -1; i ++) {
				if(recentParamValues!=null) restartParamValues[i] = recentParamValues[row-1][i];
			}
		}
		updateRestartLabels(white);
	} // select latest
	
	
	/**
	 * 
	 */
	private static void selectBestAction() {
		restartWithLatest = false;
		if(bestParamValues != null) {
			for(int i = 0; i < (bestParamValues.length) -1; i ++) {
				restartParamValues[i] = bestParamValues[i];
			}
		}
		updateRestartLabels(lightGreen);
	}// select best
	
	
	/**
	 * set up the four data time series charts
	 * @param dataComposite
	 */
	protected static void updateValueLabels() {
		if(bestParamValues != null) {
			for(int i=0;i<numColumns;++i)
				bestValueLabels[i].setText(bestParamValues[i]+"");
			
			bestValueLabels[numColumns].setText(bestError+"");
			bestValueLabels[numColumns+1].setText(bestVError+"");
		}
		for(int i = 0; i < NUMROWS; ++i) 
			for(int j=0;j<numColumns+1;++j) {
				if(j< numColumns)
					recentValueLabels[i][j].setText(recentParamValues[i][j]+"");
				else if(recentErrors[i]!=-1) { 
					recentValueLabels[i][j].setText(recentErrors[i]+"");
					recentValueLabels[i][j+1].setText(recentVErrors[i]+"");
				}
				else {
					recentValueLabels[i][j].setText("...");
					recentValueLabels[i][j+1].setText("...");
				}
		}
		
		valuesComposite.redraw();
		valuesComposite.update();
		
		if(restartParamValues!=null) {
			for(int j=0;j<numColumns;++j) {
				restartValues[j].setText(restartParamValues[j]+"");
				}
			controlsValuesComposite.redraw();
			controlsValuesComposite.update();
		}
	
	}// updateValueLabels
	
	/**
	 * called by radio button action
	 */
	protected static void updateRestartLabels(final Color bg) {
		try {
			display.asyncExec(new Runnable() {
				public void run() {
					if(restartParamValues!=null) {
						for(int j=0;j<numColumns;++j) {
							restartValues[j].setText(restartParamValues[j]+"");
							restartValues[j].setBackground(bg);
							}
						controlsValuesComposite.redraw();
						controlsValuesComposite.update();
					}
				} // run
			}); // display.asyncExec
		} // try
		catch (final Exception e) {
			// Ignore there could be a race condition with the display being disposed
		} // catch Exception
	}
	
	static boolean valuesInitialized = false;
	/**
	 * 
	 * @param attributes
	 * @param initialValues
	 */
	protected static void initializeValueLabels(String[] attributes) {
		
		int numAttrEntries = attributes.length;
		int numColumns = numAttrEntries;

		// Use form layout
		GridLayout gl = new GridLayout();
		gl.numColumns = numColumns+2; // error and validation error
		valuesComposite.setLayout(gl);
		controlsValuesComposite.setLayout(gl);
		int width = 800/numColumns;
		
		attributeLabels = new CLabel[numColumns+2];
		bestValueLabels = new Text[numColumns+2];
		recentValueLabels = new Text[NUMROWS][numColumns+2];
		
			for(int i = 0; i < numColumns; i ++) {
				attributeLabels[i] = new CLabel(valuesComposite, SWT.BORDER);
				attributeLabels[i].setText(attributes[i]);
				attributeLabels[i].setBackground(cyan);
				final GridData titleGridData = new GridData();
				attributeLabels[i].setLayoutData(titleGridData);
			    titleGridData.grabExcessHorizontalSpace=true;
			    titleGridData.minimumWidth=width;
			    titleGridData.horizontalAlignment = GridData.FILL;
			}
			attributeLabels[numColumns] = new CLabel(valuesComposite, SWT.BORDER);
			attributeLabels[numColumns].setText("Error");
			attributeLabels[numColumns].setBackground(cyan);
			attributeLabels[numColumns+1] = new CLabel(valuesComposite, SWT.BORDER);
			attributeLabels[numColumns+1].setText("VError");
			attributeLabels[numColumns+1].setBackground(cyan);
			
			final GridData titleGridData = new GridData();
			attributeLabels[numColumns].setLayoutData(titleGridData);
		    titleGridData.grabExcessHorizontalSpace=true;
		    titleGridData.minimumWidth=width;
		    titleGridData.horizontalAlignment = GridData.FILL;
			
		    final GridData titleGridData2 = new GridData();
			attributeLabels[numColumns+1].setLayoutData(titleGridData2);
		    titleGridData2.grabExcessHorizontalSpace=true;
		    titleGridData2.minimumWidth=width;
		    titleGridData2.horizontalAlignment = GridData.FILL;
		    
			for(int i = 0; i < numColumns+2; i ++) {
				bestValueLabels[i] = new Text(valuesComposite, SWT.BORDER);
				bestValueLabels[i].setText(""); // nothing yet
				bestValueLabels[i].setBackground(lightGreen); 
				final GridData textGridData = new GridData();
				bestValueLabels[i].setLayoutData(textGridData);
			    textGridData.grabExcessHorizontalSpace=true;
			    textGridData.minimumWidth=width;
			    textGridData.horizontalAlignment = GridData.FILL;
			}
			
			for(int i=0;i<NUMROWS;++i)
				for(int j=0;j<numColumns+2;++j) {
					recentValueLabels[i][j] = new Text(valuesComposite, SWT.BORDER);
					recentValueLabels[i][j].setText(""); // nothing yet
					recentValueLabels[i][j].setBackground(white);
					final GridData textGridData = new GridData();
					recentValueLabels[i][j].setLayoutData(textGridData);
				    textGridData.grabExcessHorizontalSpace=true;
				    textGridData.minimumWidth=width;
				    textGridData.horizontalAlignment = GridData.FILL;
				}	
		 
		valuesComposite.layout();
		//valuesComposite.pack();
		//valuesComposite.setVisible(true);
		valuesComposite.redraw();
		valuesInitialized = true;
	
	}// initializeValueLabels
	
	

	/**
	 * 
	 * @param attributes
	 * @param initialValues
	 */
	protected static void initializeControlLabels(String[] attributes) {
		
		int numAttrEntries = attributes.length;
		int numColumns = numAttrEntries;

		// Use form layout
		GridLayout gl = new GridLayout();
		gl.numColumns = numColumns;
		
		controlsValuesComposite.setLayout(gl);
		int width = 800/numColumns;
		
		controlLabels = new CLabel[numColumns];
		restartValues = new Text[numColumns];
		
			for(int i = 0; i < numColumns; i ++) {
				controlLabels[i] = new CLabel(controlsValuesComposite, SWT.BORDER);
				controlLabels[i].setText(attributes[i]);
				controlLabels[i].setBackground(cyan);
				final GridData titleGridData = new GridData();
				controlLabels[i].setLayoutData(titleGridData);
			    titleGridData.grabExcessHorizontalSpace=true;
			    titleGridData.minimumWidth=width;
			    titleGridData.horizontalAlignment = GridData.FILL;
			}
		
			final GridData titleGridData = new GridData();
			
		    titleGridData.grabExcessHorizontalSpace=true;
		    titleGridData.minimumWidth=width;
		    titleGridData.horizontalAlignment = GridData.FILL;
			
			for(int j=0;j<numColumns;++j) {
				restartValues[j] = new Text(controlsValuesComposite, SWT.BORDER);
				restartValues[j].setText(""); // nothing yet
				restartValues[j].setBackground(white);
				final GridData textGridData = new GridData();
				restartValues[j].setLayoutData(textGridData);
			    textGridData.grabExcessHorizontalSpace=true;
			    textGridData.minimumWidth=width;
			    textGridData.horizontalAlignment = GridData.FILL;
			    
			    final int ind = j;
			    restartValues[j].addModifyListener(new ModifyListener() {
					
					public void modifyText(ModifyEvent e) {
						try {
							String text = ((Text)e.getSource()).getText();
							restartParamValues[ind] = Double.parseDouble(text);
						} catch(Exception ex) {
							// The user entered an invalid double value. Ignore
						}
					}
				});
			}	
		 
		controlsValuesComposite.layout();
		controlsValuesComposite.redraw();
		valuesInitialized = true;
	
	}// initializeControlLabels
	
	
	
	
	

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

	
	/**
	 * not used
	 * @return null
	 */
	public Identifiable getIdentifiable() {
		return null;
	}

	

	/**
	 * get the value for plotting
	 * @see org.eclipse.stem.util.analysis.views.AnalysisControl#getValues(int, int)
	 */
	public double[] getValues(int chartIndex, int state) {
		
		if(chartIndex == 0) return errorHistory;
		if(chartIndex == 1) {
			if(state==0) return newErrorTimeSeries;
			if(state==1) return bestSeries;
		}
		if(chartIndex == 2) {
			if(state==0) return referenceIncidence;
			if(state==1) return modelIncidence;
		}
		// should never happen
		return null;
	}
	
	/**
	 * Not used
	 * @param chartIndex not used (only one chart)
	 * @param state
	 * @return property name
	 */
	public String getProperty(int chartIndex, int state) {
		if(chartIndex==0) return Messages.getString("AUTO.TITLE1");
		if(chartIndex==1) {
			if(state==0) return Messages.getString("AUTO.TITLE2");
			if(state==1) return Messages.getString("AUTO.TITLE3");
		}
		if(chartIndex==2) {
			if(state==0) return Messages.getString("AUTO.TITLE4");
			if(state==1) return Messages.getString("AUTO.TITLE5");
		}
		return  Messages.getString("AUTO.NOTFOUNDERROR");
	}
	
	
	
	
	
	/**
	 * Not used
	 * @param chartIndex not used (only one chart)
	 * @return the number of properties, only one
	 * @see org.eclipse.stem.util.analysis.views.AnalysisControl#getNumProperties(int chartIndex)
	 */
	public int getNumProperties(int chartIndex) {
		if(chartIndex==ERROR_CONVERGENCE_BY_RUN_ID) return 1; // one thing to chart
		if(chartIndex==CURRENT_ERROR_BY_TIME_ID) return 2; // two things to chart
		if(chartIndex==AGGREGATE_BY_TIME_ID) return 2; // two things to chart
		return 0; // should never happen
	}

	/**
	 * 
	 * @param error
	 */
	public static void appendLatestErrorData(double error) {
		errorHistoryList.add(new Double(error));
		errorHistory = new double[errorHistoryList.size()];
		for(int i = 0; i < errorHistoryList.size(); i ++) {
			errorHistory[i] = errorHistoryList.get(i).doubleValue();
		}
	}

	/**
	 * 
	 * @param error
	 * @param verror Validation error
	 * @param errorByTimeStep
	 * @param refIncidence
	 * @param bestIncidence
	 */
	public static void setRecentTimeSeries(double error, double verror, EList<Double> errorByTimeStep, EList<Double> refIncidence, EList<Double> incidence) {
		newErrorTimeSeries = new double[errorByTimeStep.size()];
		referenceIncidence = new double[refIncidence.size()];
		modelIncidence = new double[incidence.size()];
		for(int i = 0; i < errorByTimeStep.size(); i ++) { 
			newErrorTimeSeries[i] = errorByTimeStep.get(i).doubleValue();
			referenceIncidence[i] = refIncidence.get(i).doubleValue();
			modelIncidence[i] = incidence.get(i).doubleValue();
		}
		if(bestSeries==null) bestSeries = newErrorTimeSeries;
		if(error <= bestError) {
			bestError = error;
			bestVError = verror;
			bestSeries = newErrorTimeSeries;
			bestParamValues = copyDoubleArray(recentParamValues[row-1]);
		}
		
		
	}



	@Override
	protected void initializeHeader(String folderName) {
		// TODO Auto-generated method stub
		
	}



	@Override
	public void remove() {
		// TODO Auto-generated method stub
	}
		
	protected static double [] copyDoubleArray(double []s) {
		double []t = new double[s.length];
		int i=0;
		for(double d:s)t[i++]=d;
		return t;
	}
	
	

} // AutoExpControl
