/*****************************************************************************
 * 
 * Copyright (c) 2016 CEA LIST.
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *  CEA LIST Initial API and implementation
 * 
 *****************************************************************************/
package org.eclipse.papyrus.moka.fmu.engine.debug;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.papyrus.moka.discreteevent.DEScheduler;
import org.eclipse.papyrus.moka.fmi.profile.util.FMIProfileUtil;
import org.eclipse.papyrus.moka.fmu.engine.control.EngineStatus;
import org.eclipse.papyrus.moka.fmu.engine.control.FMUControlService;
import org.eclipse.papyrus.moka.fmu.engine.semantics.FMUObject;
import org.eclipse.papyrus.moka.fmu.engine.utils.FMUEngineUtils;
import org.eclipse.papyrus.moka.utils.UMLPrimitiveTypesUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Control;
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.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.uml2.uml.Property;

public class FMUDebugDialog extends Dialog {

	protected FMUDebugDialog(Shell parentShell) {
		super(parentShell) ;
		setShellStyle(SWT.CLOSE | SWT.MODELESS | SWT.BORDER | SWT.TITLE);
	}

	@Override
	protected void handleShellCloseEvent() {
		super.handleShellCloseEvent();
		FMUEngineUtils.getFMUControlService().terminate();
	}

	@Override
	protected void okPressed() {
		super.okPressed();
		FMUEngineUtils.getFMUControlService().terminate();
	}

	@Override
	protected void cancelPressed() {

		super.cancelPressed();
		FMUEngineUtils.getFMUControlService().terminate();

	}

	@Override
	protected Control createDialogArea(Composite dialogArea) {
		Composite parent = new Composite(dialogArea, SWT.NONE) ;
		parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
		GridLayout layout = new GridLayout(2, false);
		parent.setLayout(layout);

		final Label stepSizeLabel = new Label(parent, SWT.PUSH);
		stepSizeLabel.setText("Step size:");

		final Text stepText = new Text(parent, SWT.NONE | SWT.FILL);
		stepText.setText("0.1");

		final Label currentTimeLabel = new Label(parent, SWT.PUSH);
		currentTimeLabel.setText("Current time:");

		final Text currentTimeText = new Text(parent, SWT.FILL);
		currentTimeText.setText("");
		currentTimeText.setEditable(false);

		final Label inputsLabel = new Label(parent, SWT.PUSH);
		inputsLabel.setText("inputs:");
		final Table inputTable = new Table(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.PUSH);
		TableColumn inputColumnName = new TableColumn(inputTable, SWT.BORDER | SWT.FILL);
		inputColumnName.setWidth(100);
		inputColumnName.setResizable(true);
		inputColumnName.setText("Name");
		TableColumn inputColumnValue = new TableColumn(inputTable, SWT.BORDER | SWT.FILL);
		inputColumnValue.setWidth(100);
		inputColumnValue.setResizable(true);
		inputColumnValue.setText("Value");
		inputTable.setHeaderVisible(true);

		final TableEditor editor = new TableEditor(inputTable);
		editor.horizontalAlignment = SWT.LEFT;
		editor.grabHorizontal = true;
		editor.minimumWidth = 100;
		final int EDITABLECOLUMN = 1;

		final Label outputsLabel = new Label(parent, SWT.PUSH);
		outputsLabel.setText("outputs:");
		final Table outputTable = new Table(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.PUSH);

		final Button initButton = new Button(parent, SWT.NONE);
		initButton.setText("Init");

		final Button stepButton = new Button(parent, SWT.NONE);
		stepButton.setText("Step");
		stepButton.setEnabled(false);

		inputTable.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				// Clean up any previous editor control
				Control oldEditor = editor.getEditor();
				if (oldEditor != null)
					oldEditor.dispose();

				// Identify the selected row
				TableItem item = (TableItem) e.item;
				if (item == null)
					return;

				// The control that will be the editor must be a child of the
				// Table
				Text newEditor = new Text(inputTable, SWT.NONE);
				newEditor.setText(item.getText(EDITABLECOLUMN));
				newEditor.addModifyListener(me -> {
					Text text = (Text) editor.getEditor();
					editor.getItem().setText(EDITABLECOLUMN, text.getText());
				});
				newEditor.addKeyListener(new KeyListener() {
					@Override
					public void keyReleased(KeyEvent arg0) {
						boolean validEntry = isValidEntry(editor.getItem().getText(0), editor.getItem().getText(1));
						stepButton.setEnabled(validEntry);
						if (!validEntry) {
							editor.getItem().setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_RED));
						} else {
							editor.getItem().setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
						}
					}

					@Override
					public void keyPressed(KeyEvent arg0) {

					}
				});
				newEditor.selectAll();
				newEditor.setFocus();
				editor.setEditor(newEditor, item, EDITABLECOLUMN);
			}
		});

		TableColumn outputColumnName = new TableColumn(outputTable, SWT.BORDER | SWT.FILL);
		outputColumnName.setWidth(100);
		outputColumnName.setResizable(true);
		outputColumnName.setText("Name");
		TableColumn outputColumnValue = new TableColumn(outputTable, SWT.BORDER | SWT.FILL);
		outputColumnValue.setWidth(100);
		outputColumnValue.setResizable(true);
		outputColumnValue.setText("Value");
		outputTable.setHeaderVisible(true);
		createInputOutputTableItems(inputTable, true);
		createInputOutputTableItems(outputTable, false);

		initButton.addListener(SWT.MouseDown, new Listener() {
			@Override
			public void handleEvent(Event arg0) {
				FMUControlService fmuControlService = FMUEngineUtils.getFMUControlService();
				fmuControlService.setEngineStatus(EngineStatus.INIT);
				new Thread(new Runnable() {

					@Override
					public void run() {
						fmuControlService.init();
						Display.getDefault().asyncExec(new Runnable() {
							@Override
							public void run() {
								initButton.setEnabled(false);
								if (canParseDouble(stepText.getText())) {
									stepButton.setEnabled(true);
								}
								updateInputOutputTableItems(inputTable, true);
								updateInputOutputTableItems(outputTable, false);
								currentTimeText.setText("" + DEScheduler.getInstance().getCurrentTime());
							}
						});

					}
				}).start();

				// Display.getCurrent().syncExec(new Runnable() {
				// @Override
				// public void run() {
				// pseudoMasterShell.layout();
				// Display.getCurrent().update();
				// }
				// });
			}
		});

		stepButton.addListener(SWT.MouseDown, new Listener() {
			@Override
			public void handleEvent(Event arg0) {
				stepButton.setEnabled(false);
				final double stepSize = new Double(stepText.getText()).doubleValue();
				FMUControlService fmuControlService = FMUEngineUtils.getFMUControlService();
				fmuControlService.setEngineStatus(EngineStatus.STEPPING);
				setInputValues(inputTable);
				new Thread(new Runnable() {
					public void run() {
						FMUControlService fmuControlService = FMUEngineUtils.getFMUControlService();
						fmuControlService.doStep(DEScheduler.getInstance().getCurrentTime(), stepSize);
						Display.getDefault().asyncExec(new Runnable() {
							@Override
							public void run() {
								updateInputOutputTableItems(outputTable, false);
								currentTimeText.setText("" + DEScheduler.getInstance().getCurrentTime());
								stepButton.setEnabled(true);
							}
						});

					}
				}).start();
			}
		});

		stepText.addKeyListener(new KeyListener() {

			@Override
			public void keyReleased(KeyEvent arg0) {
				if (canParseDouble(stepText.getText())) {
					if (!initButton.getEnabled()) {
						stepButton.setEnabled(true);
					}
				} else {
					stepButton.setEnabled(false);
				}
			}

			@Override
			public void keyPressed(KeyEvent arg0) {

			}
		});

		return parent;
	}

	protected boolean isValidEntry(String propertyName, String value) {
		FMUObject fmuObject = FMUEngineUtils.getFMUControlService().getFmuObject();

		Integer index = fmuObject.getPropertyNameToIndexMap().get(propertyName);
		if (index != null) {
			Property property = fmuObject.getIndexToUMLPropertyMap().get(index);
			if (property != null) {
				if (UMLPrimitiveTypesUtils.getBoolean(property).equals(property.getType())) {
					return this.canParseBoolean(value);
				} else if (UMLPrimitiveTypesUtils.getInteger(property).equals(property.getType())) {
					return this.canParseInteger(value);
				}
				if (UMLPrimitiveTypesUtils.getReal(property).equals(property.getType())) {
					return this.canParseDouble(value);
				}
				if (UMLPrimitiveTypesUtils.getString(property).equals(property.getType())) {
					return true;
				}
			}
		}
		return false;
	}

	protected boolean canParseDouble(String s) {
		try {
			new Double(s);
		} catch (NumberFormatException e) {
			return false;
		}
		return true;
	}

	protected boolean canParseInteger(String s) {
		try {
			new Integer(s);
		} catch (NumberFormatException e) {
			return false;
		}
		return true;
	}

	protected boolean canParseBoolean(String s) {
		if (s != null) {
			return "true".equals(s.toLowerCase()) || "false".equals(s.toLowerCase());
		}
		return false;
	}

	protected void createInputOutputTableItems(Table table, boolean isInput) {
		FMUObject _object = FMUEngineUtils.getFMUControlService().getFmuObject();
		for (Integer k : _object.fmiGetBools().keySet()) {
			Property p = _object.getIndexToUMLPropertyMap().get(k);
			if ((!isInput && FMIProfileUtil.isOutputPort(p)) || (isInput && FMIProfileUtil.isInputPort(p))) {
				TableItem item = new TableItem(table, SWT.NONE);
				item.setText(new String[] { p.getName(), "" });
			}
		}
		for (Integer k : _object.fmiGetIntegers().keySet()) {
			Property p = _object.getIndexToUMLPropertyMap().get(k);
			if ((!isInput && FMIProfileUtil.isOutputPort(p)) || (isInput && FMIProfileUtil.isInputPort(p))) {
				TableItem item = new TableItem(table, SWT.NONE);
				item.setText(new String[] { p.getName(), "" });
			}
		}
		for (Integer k : _object.fmiGetReals().keySet()) {
			Property p = _object.getIndexToUMLPropertyMap().get(k);
			if ((!isInput && FMIProfileUtil.isOutputPort(p)) || (isInput && FMIProfileUtil.isInputPort(p))) {
				TableItem item = new TableItem(table, SWT.NONE);
				item.setText(new String[] { p.getName(), "" });
			}
		}
		for (Integer k : _object.fmiGetStrings().keySet()) {
			Property p = _object.getIndexToUMLPropertyMap().get(k);
			if ((!isInput && FMIProfileUtil.isOutputPort(p)) || (isInput && FMIProfileUtil.isInputPort(p))) {
				TableItem item = new TableItem(table, SWT.NONE);
				item.setText(new String[] { p.getName(), "" });
			}
		}
	}

	protected void updateInputOutputTableItems(Table table, boolean isInput) {
		FMUObject _object = FMUEngineUtils.getFMUControlService().getFmuObject();
		int i = 0;
		for (Integer k : _object.fmiGetBools().keySet()) {
			Property p = _object.getIndexToUMLPropertyMap().get(k);
			if ((!isInput && FMIProfileUtil.isOutputPort(p)) || (isInput && FMIProfileUtil.isInputPort(p))) {
				TableItem item = table.getItem(i);
				item.setText(new String[] { p.getName(), "" + _object.fmiGetBools().get(k) });
				i = i + 1;
			}
		}
		for (Integer k : _object.fmiGetIntegers().keySet()) {
			Property p = _object.getIndexToUMLPropertyMap().get(k);
			if ((!isInput && FMIProfileUtil.isOutputPort(p)) || (isInput && FMIProfileUtil.isInputPort(p))) {
				TableItem item = table.getItem(i);
				item.setText(new String[] { p.getName(), "" + _object.fmiGetIntegers().get(k) });
				i = i + 1;
			}
		}
		for (Integer k : _object.fmiGetReals().keySet()) {
			Property p = _object.getIndexToUMLPropertyMap().get(k);
			if ((!isInput && FMIProfileUtil.isOutputPort(p)) || (isInput && FMIProfileUtil.isInputPort(p))) {
				TableItem item = table.getItem(i);
				item.setText(new String[] { p.getName(), "" + _object.fmiGetReals().get(k) });
				i = i + 1;
			}
		}
		for (Integer k : _object.fmiGetStrings().keySet()) {
			Property p = _object.getIndexToUMLPropertyMap().get(k);
			if ((!isInput && FMIProfileUtil.isOutputPort(p)) || (isInput && FMIProfileUtil.isInputPort(p))) {
				TableItem item = table.getItem(i);
				item.setText(new String[] { p.getName(), "" + _object.fmiGetStrings().get(k) });
				i = i + 1;
			}
		}
		table.redraw();
	}

	protected void setInputValues(Table inputTable) {
		Map<Integer, Boolean> boolMap = new HashMap<>();
		Map<Integer, String> stringMap = new HashMap<>();
		Map<Integer, Integer> integerMap = new HashMap<>();
		Map<Integer, Double> realMap = new HashMap<>();
		FMUObject fmuObject = FMUEngineUtils.getFMUControlService().getFmuObject();
		for (TableItem t : inputTable.getItems()) {
			String inputName = t.getText(0);
			String value = t.getText(1);
			Integer propertyIndex = fmuObject.getPropertyNameToIndexMap().get(inputName);
			Property property = fmuObject.getIndexToUMLPropertyMap().get(propertyIndex);
			if (UMLPrimitiveTypesUtils.getBoolean(property).equals(property.getType())) {
				Boolean booleanValue = Boolean.parseBoolean(value);
				boolMap.put(propertyIndex, booleanValue);
			} else if (UMLPrimitiveTypesUtils.getInteger(property).equals(property.getType())) {
				Integer integerValue = Integer.parseInt(value);
				integerMap.put(propertyIndex, integerValue);
			} else if (UMLPrimitiveTypesUtils.getString(property).equals(property.getType())) {
				stringMap.put(propertyIndex, value);
			} else if (UMLPrimitiveTypesUtils.getReal(property).equals(property.getType())) {
				Double realValue = Double.parseDouble(value);
				realMap.put(propertyIndex, realValue);
			}
		}
		fmuObject.fmiSetBools(boolMap);
		fmuObject.fmiSetIntegers(integerMap);
		fmuObject.fmiSetReals(realMap);
		fmuObject.fmiSetStrings(stringMap);
	}

	@Override
	protected void createButtonsForButtonBar(Composite parent) {
		// Does nothing to avoid the creation of OK and CANCEL buttons
		// FIXME Should rather deal with the creation of init and step buttons
	}

	@Override
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		newShell.setText("FMU Controller");
	}

	
	
}
