/*******************************************************************************
 * Copyright (c) 2015, 2016 CNRS, IRIT, IRT AESE (IRT Saint Exupéry).
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the LGPL 3.0
 * which accompanies this distribution, and is available at
 * https://www.gnu.org/licenses/lgpl-3.0-standalone.html
 *
 * Contributors:
 *     Faiez Zalila - initial API and implementation and/or initial documentation
 *     Jorge Enrique Gutierrez Zuluaga
 *******************************************************************************/
package com.irtsaintexupery.fiacre.simulator.perspective;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

import org.apache.thrift.TException;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceDescription;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.text.Position;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.WorkbenchException;
import org.eclipse.ui.actions.ImportResourcesAction;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.texteditor.AbstractTextEditor;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.xtext.nodemodel.ICompositeNode;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.impl.CompositeNode;
import org.eclipse.xtext.nodemodel.impl.LeafNode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;

import com.irtsaintexupery.fiacre.instance.fiacreinstance.BlockInstance;
import com.irtsaintexupery.fiacre.instance.fiacreinstance.ComponentDeclarationInstance;
import com.irtsaintexupery.fiacre.instance.fiacreinstance.CompositionInstance;
import com.irtsaintexupery.fiacre.instance.fiacreinstance.DeclarationInstance;
import com.irtsaintexupery.fiacre.instance.fiacreinstance.EnabledStatementBlock;
import com.irtsaintexupery.fiacre.instance.fiacreinstance.ExecutableStatementBlock;
import com.irtsaintexupery.fiacre.instance.fiacreinstance.FireableStatementBlock;
import com.irtsaintexupery.fiacre.instance.fiacreinstance.InstanceModel;
import com.irtsaintexupery.fiacre.instance.fiacreinstance.InstanceStatementBlock;
import com.irtsaintexupery.fiacre.instance.fiacreinstance.ProcessDeclarationInstance;
import com.irtsaintexupery.fiacre.instance.fiacreinstance.StatementBlock;
import com.irtsaintexupery.fiacre.instance.fiacreinstance.VariableDeclarationInstance;
import com.irtsaintexupery.fiacre.simulator.core.FiacreSimulator;
import com.irtsaintexupery.fiacre.simulator.core.Utils;
import com.irtsaintexupery.fiacre.simulator.marking.MarkerFactory;
import com.irtsaintexupery.fiacre.simulator.marking.MarkingController;
import com.irtsaintexupery.fiacre.simulator.perspective.model.ActionState;
import com.irtsaintexupery.fiacre.simulator.perspective.model.TreeObject;
import com.irtsaintexupery.fiacre.simulator.perspective.model.TreeParent;
import com.irtsaintexupery.fiacre.simulator.perspective.model.ValuesData;
import com.irtsaintexupery.fiacre.simulator.perspective.model.ValuesDataProvider;
import com.irtsaintexupery.fiacre.simulator.perspective.views.*;
import com.irtsaintexupery.fiacre.simulator.staticjson.extractor.DynamicJsonExtractor;
import com.sun.javafx.css.Declaration;
import com.sun.xml.internal.ws.spi.db.FieldSetter;

import fr.irit.fiacre.xtext.fiacre.ArrayExpression;
import fr.irit.fiacre.xtext.fiacre.ConstructionExpression;
import fr.irit.fiacre.xtext.fiacre.Expression;
import fr.irit.fiacre.xtext.fiacre.ExpressionDeclarationUse;
import fr.irit.fiacre.xtext.fiacre.FalseLiteral;
import fr.irit.fiacre.xtext.fiacre.FiacrePackage;
import fr.irit.fiacre.xtext.fiacre.FieldExpression;
import fr.irit.fiacre.xtext.fiacre.IdentifierExpression;
import fr.irit.fiacre.xtext.fiacre.NaturalLiteral;
import fr.irit.fiacre.xtext.fiacre.ProcessDeclaration;
import fr.irit.fiacre.xtext.fiacre.QueueExpression;
import fr.irit.fiacre.xtext.fiacre.RecordExpression;
import fr.irit.fiacre.xtext.fiacre.RecordFieldDeclaration;
import fr.irit.fiacre.xtext.fiacre.RecordFieldDeclarationUse;
import fr.irit.fiacre.xtext.fiacre.Statement;
import fr.irit.fiacre.xtext.fiacre.TrueLiteral;
import fr.irit.fiacre.xtext.fiacre.UnionTagDeclaration;
import fr.irit.fiacre.xtext.fiacre.ValueExpression;
import fr.irit.fiacre.xtext.fiacre.VariableDeclaration;
import fr.laas.libtts.LibTTS;
import tts.Error;
import tts.NotFireable;
import tts.StateNotFound;
import tts.TTSState;
import tts.Transition;
import tts.TransitionNotFound;

/**
 * @author jorge.gutierrez
 * Class for control the views in the simulator
 * <p>
 * it makes the communication between simulator model and visual interface
 */
/**
 * @author jorge.gutierrez
 *
 */
/**
 * @author jorge.gutierrez
 *
 */
/**
 * @author jorge.gutierrez
 *
 */
public enum ViewsController {
	INSTANCE;

	//variables to make instance of active views and to call their functions
	private InstancesView instancesView;
	private TransitionsView transitionsView;
	private ValuesView valuesView;
	private ExecutedActionView executedActionView;
	private SavedStatesView savedStatesView;

	//variables to take control of Workbench
	private IWorkbench wb = PlatformUI.getWorkbench();
	private IWorkbenchWindow win = wb.getActiveWorkbenchWindow();
	private IWorkbenchPage page = win.getActivePage();

	//variable to store the current simulated file 
	private static IFile file = null;	

	//variable to store the current Json model
	private DynamicJsonExtractor djeViews;

	//HashMap to store the instances assigned to a TreeObject key
	// and to make mapping with 
	private HashMap<TreeObject, BlockInstance> instancesMap;
	
	//Jorge Gutierrez 05/08/2016
	//to store the transition assigned to a String key 
	private HashMap<String, StatementBlock> transitionExecutableMap;
	
	//Jorge Gutierrez 10/08/2016
	//Stack to store a copy of each new action.
	private Stack<ActionState> actionStack;
	
	//Jorge Gutierrez 26/08/2016
	//HasMap to store a state model from the simulation
	private HashMap<String, TTSState> stateMap;
	
	//HasMap to store a action stack linked to saved state tag 	
	private HashMap<String, StateStructure> activitiesStackMap;
	
	private class StateStructure{
		public Stack<ActionState> interfaceStack;
		public Stack<TTSState> modelStack;
		
		public StateStructure() {
			interfaceStack = new Stack<ActionState>();
			modelStack = new Stack<TTSState>();
		}
	}

	//Constructor
	ViewsController() {
		instancesMap = new HashMap<TreeObject, BlockInstance>();
		transitionExecutableMap = new HashMap<String, StatementBlock>();
		stateMap = new HashMap<String, TTSState>();
		actionStack = new Stack<ActionState>();
		activitiesStackMap = new HashMap<String, StateStructure>();
		page.getActivePart().getSite().getWorkbenchWindow().
			getPartService().addPartListener(partListener);
		djeViews = FiacreSimulator.sendDje();

	}

	private IPartListener partListener = new IPartListener() {
		public void partOpened(IWorkbenchPart part) {
		}

		@Override
		public void partActivated(IWorkbenchPart part) {

		}

		@Override
		public void partBroughtToTop(IWorkbenchPart part) {
			// TODO Auto-generated method stub

		}

		@Override
		public void partClosed(IWorkbenchPart part) {
			// TODO Auto-generated method stub

		}

		@Override
		public void partDeactivated(IWorkbenchPart part) {
			// TODO Auto-generated method stub

		}
	};
	
	public IFile getFile() {
		return file;
	}
	
	// Jorge Gutierrez 20/07/2016
	/**
	 * displays the Fiacre Simulator perspective 
	 * <p>
	 * displays perspective by its id, calls every view updates and resets the marking
	 * and data values.
	 *  
	 * Takes the current simulation model and looks for the InstanceView instance to call an update
	 * Takes the current simulation model and looks for the transitionView instance to call an update
	 * Takes the current simulation model and looks for the ExecutedActionView instance to call an update
	 * Looks for the ExecutedActionView instance to call an update
	 */
	public void openPespective() {
		//displays perspective by its corresponding id 
		try {
			PlatformUI.getWorkbench().showPerspective("com.irtsaintexupery"
					+ ".fiacre.simulator.perspective.fiacreSimulator",
					PlatformUI.getWorkbench().getActiveWorkbenchWindow());
		} catch (WorkbenchException e) {
			e.printStackTrace();
		}

		//Takes the simulated model
		djeViews = FiacreSimulator.sendDje();

		//looks for a active ValuesViews instance.
		ViewPart valuesPart = (ViewPart) wb.getActiveWorkbenchWindow()
				.getActivePage().findView("com.irtsaintexupery.fiacre.simulator"
						+ ".perspective.valuesView");
		if (valuesPart instanceof ValuesView) {
			valuesView = (ValuesView) valuesPart;
		}

		////looks for a active InstancesView instance
		ViewPart instancesPart = (ViewPart) wb.getActiveWorkbenchWindow()
				.getActivePage().findView("com.irtsaintexupery.fiacre.simulator"
						+ ".perspective.instancesView");
		if (instancesPart instanceof InstancesView) {			
			instancesView = (InstancesView) instancesPart;
		}

		//looks for a active TransitionView instance and call update.
		ViewPart transitionsPart = (ViewPart) wb.getActiveWorkbenchWindow().
				getActivePage().findView("com.irtsaintexupery.fiacre.simulator"
						+ ".perspective.transitionsView");
		if (transitionsPart instanceof TransitionsView) {
			transitionsView = (TransitionsView) transitionsPart;
			//calls update by passing a list of transitions names as parameter.
			transitionsView.update(returnTransitions());
		}

		//looks for a active ExecutedActionView instance.
		ViewPart executedActionPart = (ViewPart) wb.getActiveWorkbenchWindow().
				getActivePage().findView("com.irtsaintexupery.fiacre.simulator"
						+ ".perspective.executedActionView");
		if (executedActionPart instanceof ExecutedActionView) {
			executedActionView = (ExecutedActionView) executedActionPart;
			//calls update by passing a list of Executed Action as parameter.
			executedActionView.update(returnActions());
		}

		//looks for a active SavedStatesView instance.
		ViewPart savedStatesPart = (ViewPart) wb.getActiveWorkbenchWindow().
				getActivePage().findView("com.irtsaintexupery.fiacre.simulator"
						+ ".perspective.savedStatesView");
		if (savedStatesPart instanceof SavedStatesView) {
			savedStatesView = (SavedStatesView) savedStatesPart;
		}

		//resets values and updates views
		ValuesDataProvider.removeData();
		reinitializeValuesView();
		updateInstanceView();
		updateTransitionView();
		updateExecutedActionView();
		updateSavedStatesView();
		//resets marking
		MarkingController.file = file;
		MarkingController.deleteMarkers(file);
		//refreshes Project Explorer part  
		refresh();

	}

	
	/**
	 * Makes an update to show the currents transitions on transition window (views part). 
	 * <p>
	 * Calls an update by giving the transitions instances names.
	 */
	public void updateTransitionView() {
		//updates current model.
		djeViews = FiacreSimulator.sendDje();
		//calls update by passing a list of transitions names as parameter.
		transitionsView.update(returnTransitions());
	}

	/**
	 * Shows the values data from a selected Instance(TreeObject) on the ValuesView.
	 * <p>
	 * Takes the current simulation model, uses a Instance converted into TreeObject 
	 * to found their values, looks for the ValuesView instance to call an update.
	 * @param object The object of the Instance-set converted into a TreeObject.
	 */
	public void showValuesView(TreeObject object) {
		//updates current model.
		djeViews = FiacreSimulator.sendDje();////////////////////////////////////////////////////////////!!!!!!!!!!!!!!
		//search with the TreeObject key the mapped DeclarationInstance and give a list of contained variables.
		if(instancesMap.get(object) instanceof DeclarationInstance){
		DeclarationInstance declarationInstance = (DeclarationInstance) instancesMap.get(object);
		EList<VariableDeclarationInstance> variableList = declarationInstance.
				getVariableDeclarationInstances();
		//reinitializes ValuesTable
		ValuesDataProvider.removeData();
		//sets ValuesTable with the list of variables
		for (VariableDeclarationInstance value : variableList) {
			ValuesData v = new ValuesData();
			//set nomenclature value
			v.setCurrent(getStringValue(value.getCurrentValue()));			
			v.setName(value.getVariableDeclaration().getName());			
			ValuesDataProvider.addValues(v);
		}
		//looks for a active ValuesView instance and call update.
		ViewPart valuesPart = (ViewPart) wb.getActiveWorkbenchWindow().
				getActivePage().findView("com.irtsaintexupery.fiacre.simulator"
						+ ".perspective.valuesView");
		if (valuesPart instanceof ValuesView) {
			valuesView = (ValuesView) valuesPart;
			valuesView.update();
		}
		}
	}
	
	//Jorge Gutierrez 25/08/2016
	/**
	 * Treats variable value and returns the corresponding nomenclature value.
	 * <p>
	 * Recursive function that returns a character String by following the next rules.
	 * @param ve the valuesExpression given by Fiacre Model.
	 * @return the character String according to the embedded type.
	 */
	public static String getStringValue(ValueExpression ve){
		//returns false when ValueExpression is of type FalseLiteral
		if(ve instanceof FalseLiteral){
			return "False";
		}
		//returns true when ValueExpression is of type TrueLiteral
		else if (ve instanceof TrueLiteral) {
			return "True";
		//returns number when ValueExpression is of type NaturaLiteral
		}else if (ve instanceof NaturalLiteral) {
			return ((NaturalLiteral) ve).getValue()+"";
		//returns the ValueExpression * contained by [*] when is of type ArrayExpresion
		}else if (ve instanceof ArrayExpression) {
			ArrayExpression ae = (ArrayExpression)ve;	
			String text = "[";
			for (int i = 0; i < ae.getValues().size(); i++) {
				Expression e = ae.getValues().get(i);
				if (i == ae.getValues().size() - 1) {
					text = text + getStringValue((ValueExpression)e);
				}else {
					text = text + getStringValue((ValueExpression)e) + ", ";
				}
			}
			return text + "]";	
		//returns the ValueExpression * contained by {*} when is of type RecordExpression
		}else if (ve instanceof RecordExpression) {
			RecordExpression re = (RecordExpression)ve;
			String text = "{";
			for (int i = 0; i < re.getFields().size(); i++) {
				FieldExpression fe = re.getFields().get(i);
				RecordFieldDeclaration rfd = (RecordFieldDeclaration)fe.getField();
				//if it is the last element, does not add the separator ", "
				if (i == re.getFields().size() - 1) {
					text = text + rfd.getName() + " = " +getStringValue((ValueExpression)fe.getValue());
				}else {
					text = text + rfd.getName() + " = " +getStringValue((ValueExpression)fe.getValue()) + ", ";
				}
			}
			return text + "}";
		//returns the ValueExpression * contained by {|*|} when is of type QueueExpression	
		}else if (ve instanceof QueueExpression) {
			QueueExpression qe = (QueueExpression)ve;
			String text = "{|";
			for (int i = 0; i < qe.getValues().size(); i++) {
				Expression e = qe.getValues().get(i);
				//if it is the last element, does not add the separator ", "
				if (i == qe.getValues().size() - 1) {
					text = text + getStringValue((ValueExpression)e);
				}else {
					text = text + getStringValue((ValueExpression)e) + ", ";
				}
			}
			return text + "|}";
		}else if(ve instanceof IdentifierExpression) {
			//returns a ValueExpression contained by TagDeclaration name (*) when is of type ConstructionExpression
			if (ve instanceof ConstructionExpression) {
				ConstructionExpression ce = (ConstructionExpression)ve;
				String text = "";
				for (int i = 0; i < ce.getParameters().size(); i++) {
					Expression e = ce.getParameters().get(i);
					//if it is the last element, does not add the separator ", "
					if (i == ce.getParameters().size() - 1) {
						text = text + ((UnionTagDeclaration)ce.getDeclaration()).getName() + "(" + getStringValue((ValueExpression)e) + ")";
					}else {
						text = text + ((UnionTagDeclaration)ce.getDeclaration()).getName() + "(" + getStringValue((ValueExpression)e) + "), ";
					}
				}
				return text;
			//returns the TagDeclaration name when is of type IdentifierExpression
			} else {
				IdentifierExpression ie = (IdentifierExpression)ve;
				ExpressionDeclarationUse edu = ie.getDeclaration();
				UnionTagDeclaration utd = (UnionTagDeclaration)ie.getDeclaration();
				return utd.getName();
			}
		}
		return "";
		
	}

	
	/**
	 * Cleans the Values Table.
	 * <p>
	 * Removes data from ValuesDataProvider and looks for the ValuesView instance to 
	 * call an update. Show an empty table in the updating
	 */
	public void reinitializeValuesView() {
		ValuesDataProvider.removeData();
		valuesView.update();
	}

	/**
	 * Makes an update to show the currents instances on instance window (views part). 
	 * <p>
	 * Calls an update by giving the Tree head (TreeObject) which contains the instances name in the root and 
	 * their children from the Fiacre Model.
	 */
	public void updateInstanceView() {
		//updates current model.
		djeViews = FiacreSimulator.sendDje();
		//call update by passing a TreeObject.
		instancesView.update(returnInstances());
	}
	
	//Jorge Gutierrez 17/08/2016
	/**
	 * Adds a delay element (ActionState) in the actionStack when the DelayAction is launched
	 * @param dl The value about the delay given by the user
	 */
	public void addDelayToAction (String dl){
		ActionState obj = new ActionState("DELAY: " + dl, true);
		actionStack.add(obj);
	}
	
	/**
	 * Adds a fire element (ActionState) in the actionStack when the FireAction is launched
	 * @param dl The value about the delay given by the user
	 */
	public void addFireToAction (String tr_name){
		//Jorge Gutierrez 16/08/2016
		ActionState actionFire = new ActionState(tr_name, false);
		actionStack.add(actionFire);
	}

	/**
	 * executes a transition selected by the user in the Fiacre Model
	 * <p>
	 * Adds the action to the stackAction, search in the Map the StatementBlock
	 * to get the fireable Transition in the Fiacre Model, fires the transition
	 * and updates every view.
	 * @param tr_name the transition name taken from transition table, it will
	 * be used as key in transitionExecutableMap.
	 */
	public void fireTransition(String tr_name) {
		try {
			
			//stores the fire action in the stakeAction
			addFireToAction(tr_name);
			//Maps the StatementBlock by transition name key
			StatementBlock transition = transitionExecutableMap.get(tr_name);
			LibTTS libtts = FiacreSimulator.getLibTTS();
			long tr_long = -1;
			djeViews = FiacreSimulator.sendDje();
			//gets simulated transition 
			for (Map.Entry<Long, Transition> tr : libtts.getTTSSimulator()
					.getAllTransitions().entrySet()) {
				if (tr.getValue().getName().equals(transition.getName())) {
					tr_long = tr.getKey();
				}
			}
			//fires transition
			libtts.getTTSSimulator().fireTransition(tr_long);
			
			updateAll();
			
			djeViews.extractExecutedStatements(libtts.getTTSSimulator()
					.getAllTransitions().get(tr_long).name);/////////////////////////////////////
			//update all views to show a consistent feedback.
			//updateAll();
		} catch (Error e) {
			Utils.showException("Error", e);
			// e.printStackTrace();
		} catch (StateNotFound e) {
			Utils.showException("StateNotFound", e);
			// e.printStackTrace();
		} catch (TransitionNotFound e) {
			Utils.showException("TransitionNotFound", e);
			// e.printStackTrace();
		} catch (NotFireable e) {
			Utils.showException("NotFireable", e);
			// e.printStackTrace();
		} catch (TException e) {
			Utils.showException("TException", e);
			// e.printStackTrace();
		} catch (NullPointerException e) {
			Utils.showException("NullPointerException", e);
			// e.printStackTrace();
		}

	}

	
	
	// Jorge Gutierrez 05/08/2016
	/**
	 * Returns a list of executable transitions names given by executed model 
	 * <p>
	 * Takes a list of StatementsBlocks from the model and looks for the executable
	 * StatementsBlocks to put in a transition map and to put its name in a List of String
	 * @return List of character String according to executable transition name and date.
	 */
	private ArrayList<String> returnTransitions() {
		//Takes all statement blocks by the instance model
		EList<StatementBlock> statementList = djeViews.getInstanceModel()
				.getStatementBlocks();
		ArrayList<String> statementListString = new ArrayList<String>();
		transitionExecutableMap.clear();
		//Puts the executable statements in a List
		for (StatementBlock s : statementList) {
			if (s instanceof ExecutableStatementBlock) {
				String statementAndDate = "";
//				if (s instanceof EnabledStatementBlock) {
					statementAndDate = s.getName() + " - " + ((ExecutableStatementBlock)s).getDate();
//				}else {
//					statementAndDate = s.getName();
//				}
				statementListString.add(statementAndDate);
				//Maps the statements by the String key. this key is defined by statements name and time needed to execute it 
				transitionExecutableMap.put(statementAndDate, s);				
			}
		}
		return statementListString;
	}
	
	// Jorge Gutierrez 05/08/2016
	/**
	 * Indicates if statementBlock mapped by the given string key is Fireable
	 * <p>
	 * Function used by TransitionViews to know if a transition is fireable or not
	 * @return <code>true</code> if this transition is fireable or <code>false</code>, is not fireable.
	 */
	public Boolean isFireable(String s) {
		if (transitionExecutableMap.get(s) instanceof FireableStatementBlock){
			return true;
		}else {
			return false;
		}
	}
	
	// Jorge Gutierrez 22072016
	/**
	 * Returns a TreeObject that has the model Instance root and it is connected
	 * with their children
	 * <p>
	 * A TreeObject is a Node with a Tree structure performance that contains a instance name.
	 * When a TreeObject has children it is of type TreeParent that has a Array of TreeObject instances.
	 * The function takes all instances which are on the root and makes depth iteration for each one.
	 * @return Root with all instances as children
	 */
	public TreeObject returnInstances() {
		//Takes a Declaration Instance list from the simulated model.
		EList<DeclarationInstance> instanceListDeclaretion = djeViews
				.getInstanceModel().getInstance();
		int i = 0; 
		TreeParent rootParent = new TreeParent("");
		//clears the map that store instances objects.
		instancesMap.clear();
		//iterate each instances content.
		while (i < instanceListDeclaretion.size()) {
			iterateInstances(instanceListDeclaretion.get(i), rootParent);
			i++;
		}
		return rootParent;
	}

	/**	
	 * Build a Tree of block Instances and maps them to instanceMap until there are not
	 * more embedded Instances
	 * <p>
	 * Checks if Instance is a Process then adds to Parent else checks if it is Component to
	 * iterate recursively its instances and in the same way when it is a Composition.
	 * The instance is mapped by TreeObject key containing its instance name.
	 * @param blockInstance The BlockInstance given as point reference to read through its children.
	 * @param instanceTreeParent The TreeParent given as a reference point to add its children.
	 */
	private void iterateInstances(BlockInstance blockInstance, 
			TreeParent instanceTreeParent) {
		//Checks if instance is a Process then adds to Parent reference and instance map.
		if (blockInstance instanceof ProcessDeclarationInstance) {
			String nameProcess = ((ProcessDeclarationInstance) 
					blockInstance).getProcess().getName();
			String currentStateProcess = ((ProcessDeclarationInstance) 
					blockInstance).getCurrentState().getName();
			TreeObject processNodeObject = new TreeObject(nameProcess + " - " 
					+ currentStateProcess);
			instanceTreeParent.addChild(processNodeObject);
			// Jorge Gutierrez 01/08/2016			//
			instancesMap.put(processNodeObject, blockInstance);
		//Checks if instance is a Component then adds to Parent reference and instance map, and iterate its instances contained.
		} else if (blockInstance instanceof ComponentDeclarationInstance) {
			ComponentDeclarationInstance component = ((ComponentDeclarationInstance) 
					blockInstance);
			String nameComponent = component.getComponent().getName();
			TreeParent componentNodeParent = new TreeParent(nameComponent);
			instanceTreeParent.addChild(componentNodeParent);
			// Jorge Gutierrez 01/08/2016
			instancesMap.put(componentNodeParent, component);
			for (int i = 0; i < component.getBlockInstances().size(); i++) {
				iterateInstances(component.getBlockInstances().get(i), componentNodeParent);
			}
		//Checks if instance is a Composition then adds to Parent reference and instance map, and iterate its instances contained.
		}else {
			CompositionInstance composition = ((CompositionInstance) blockInstance);
			String namecomposition = new String("");
			TreeParent compositionNodeParent = new TreeParent(namecomposition);
			instanceTreeParent.addChild(compositionNodeParent);
			instancesMap.put(compositionNodeParent, composition);
			for (int i = 0; i < composition.getBlockInstances().size(); i++) {
				iterateInstances(composition.getBlockInstances().get(i), compositionNodeParent);
			}
		}
	}

	// Jorge Gutierrez 05/08/2016
	/**
	 * Updates the simulated file.
	 * <p>
	 * the function is called by FiacreSimulator class
	 * @param newFile the File selected to be executed.
	 */
	public void setFile(IFile newFile) {
		file = newFile;
	}

	// Jorge Gutierrez 05/08/2016
	/**
	 * Highlights on editor part the corresponding statement block by selected Transition.
	 * <p>
	 * Finds a Transition Statement Block from the simulated model and marks it on code editor
	 * Selects on Instance view, the instance involved in transition statements code.
	 * @param tr_name The string allocated for a transition.
	 */
	public void showSelectedTransition(String tr_name) {
		//takes a Statement Transition block by its name and find stamentBlock on the simulated model.
		StatementBlock transition = transitionExecutableMap.get(tr_name);
		InstanceModel instanceModel = djeViews.getInstanceModel();
		StatementBlock statementblock = null;
		for (StatementBlock stb : instanceModel.getStatementBlocks()) {
			if (stb.getName().equals(transition.getName())) {
				statementblock = stb;
			}
		}
		//reinitializes the marking and highlights the code fragment which are attached to statement block. 
		MarkingController.deleteMarkers(file);
		MarkingController.highlightCode(statementblock);
		//selects on the Instance view table, the Transitions elements which has a statement transition in common.
		instancesView.selectInstanceObject(returnInstanceContent(statementblock));
	}
	
	//Jorge Gutierrez 11/08/2016
	/**
	 * Returns the instances that contains the Statement block given
	 * <p>
	 * Browses in all Instances Statement Blocks to find the Statements Blocks which have the same reference to 
	 * Statement Block given.
	 * @param statementblock The Transition Statement Block selected by user.
	 * @return a list of Instance(TreeObject) to be selected by showSelected function
	 */
	public ArrayList<TreeObject> returnInstanceContent(StatementBlock 
			statementblock) {
		ArrayList<TreeObject> instanceList =  new ArrayList<TreeObject>();
		for (Map.Entry<TreeObject, BlockInstance> iterator : instancesMap
				.entrySet()) {
			if (iterator.getValue() instanceof ProcessDeclarationInstance ){
				EList<InstanceStatementBlock> listISB = (
						(ProcessDeclarationInstance)iterator.getValue())
						.getInstanceStatementBlocks();
				int i = 0;
				boolean b = true;
				do {
					if (listISB.size() != 0) {
						for (InstanceStatementBlock isb : listISB) {
							if (statementblock.getInstanceStatementBlocks()
									.get(i) == isb) {
								if (!instanceList.contains(iterator.getKey())) {
									instanceList.add(iterator.getKey());
									b = false;
								}								
							}							
						}						
					}
					i++;
				} while (i < statementblock.getInstanceStatementBlocks().size() 
						&& b);
				
			}
		}
		return instanceList;
	}
	
	//Jorge Gutierrez 08/08/2016
	/**
	 * Removes highlighted text from editor part.
	 */
	public void deleteMarkers (){
		try {
			MarkingController.deleteMarkers(file);
		} catch (Exception e) {
			// TODO: handle exception
		}		
	}
	
	//Jorge Gutierrez 08/08/2016
	/**
	 * Deletes data and content from every view
	 * <p>
	 * clearAllViews function is called by QuitSimulator class when the simulator 
	 * is stopped by user.
	 */
	public void clearAllViews (){
		file = null;
		
		instancesView.update(new TreeParent(""));
		
		transitionExecutableMap.clear();
		transitionsView.clearContent();
		
		ValuesDataProvider.removeData();
		valuesView.update();
		
		actionStack.clear();
		executedActionView.update(returnActions());
				
		stateMap.clear();
		activitiesStackMap.clear();
		savedStatesView.update(returnSavedStates());
		refresh();
	}
	
	//Jorge Gutierrez 12/08/2016 /////////////////TOCHANGE
	/**
	 * 
	 */
	public void launchFeedBack() throws InvocationTargetException, InterruptedException {
    }
	
	//Jorge Gutierrez 16/08/2016
	/**
	 * Makes an update to show the currents executed actions on ExecutedAction window (view part). 
	 * <p>
	 * Calls an update by giving a list of actions implemented during execution.
	 */
	public void updateExecutedActionView() {
		//updates current model.
		djeViews = FiacreSimulator.sendDje();
		//calls update by passing a list of Executed Action as parameter.
		executedActionView.update(returnActions());
	}

	/**
	 * Creates and returns a list from the stack reserved for executed action.
	 * @return list of actions names.
	 */
	private ArrayList<String> returnActions() {
		ArrayList<String> list = new ArrayList<String>();
		for (ActionState t : actionStack) {
			list.add(t.getAction());
		}
		Collections.reverse(list);
		return list;
	}
	
	//Jorge Gutierrez 17/08/2016
	/**
	 * Indicates if a executed action is a Delay 
	 * <p>
	 * Function used by ExecutedActionViews to know if a action searched by its name, is a delay or not
	 * @param obj the obj is the Action name given by ExecutedActionViews
	 * @return <code>true</code> if this action state is a delay or <code>false</code>, is not a delay or it does not exist.
	 */
	public boolean isDelay (String obj){
		for (ActionState t : actionStack ) {
			if (t.getAction().equals(obj)) {
				return t.getDelay();
			}
		}		
		return false;
	}
	
	//Jorge Gutierrez 17/08/2016
	/**
	 * Undoes the last executed action
	 * <p>
	 * Takes the last element from the actionStack and undoes the action in the simulated model, 
	 * then makes a Feedback about all views (updateAll). 
	 */
	public void undoAction() {
		try {
			ActionState undo_action = actionStack.pop();
			FiacreSimulator.getLibTTS().getTTSSimulator().undo();
			updateAll();
			if(undo_action.getAction().contains(" ")){
				String tr_name= undo_action.getAction().substring(0, undo_action.getAction().indexOf(" ")); 
				if(!tr_name.contentEquals("DELAY:")){
					if(djeViews.gettr_gl_tr_ins().get(tr_name).size() == 1){
						djeViews.getMSCModel().getSteps().remove(djeViews.getMSCModel().getSteps().size()-1);
						
					}
					else{
						djeViews.getMSCModel().getSteps().remove(djeViews.getMSCModel().getSteps().size()-1);
						djeViews.getMSCModel().getSteps().remove(djeViews.getMSCModel().getSteps().size()-1);
					}
					djeViews.saveMscResource();
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
		}		
	}
	
	/**
	 * Refreshes every view and reinitialize selections, values and markings.
	 */
	private void updateAll() {
		//djeViews.extractExecutedStatements(libtts.getTTSSimulator().getAllTransitions().get(tr_long).name);
		djeViews.extractStates();
		djeViews.extractExecutableStatements();
		djeViews.extractValues();
		//updates all views
		updateInstanceView();
		updateTransitionView();
		updateExecutedActionView();
		reinitializeValuesView();
		MarkingController.deleteMarkers(file);
		djeViews.saveInstanceResource();
	}
	
	/**
	 * Refreshes Project Explorer Part to display the launched file.
	 */
	private void refresh(){
		for(IProject project : ResourcesPlugin.getWorkspace().getRoot().getProjects()){
		    try {
				project.refreshLocal(IResource.DEPTH_INFINITE, new NullProgressMonitor());
				
			} catch (CoreException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	/**
	 * Selects on editor code the Instances declarations selected in the instances table by the user/
	 * <p>
	 * Gets editor instance to use the Select Service, takes a TreeObject key to get a corresponding block Instance,
	 * then checks if the block Instance is the type of Declaration, Component or Composition, to select it in the code.
	 * @param obj the TreeObject is given by InstanceView to search the Instance form the model.
	 */
	public void showInstanceSelected(TreeObject obj) {

		IEditorPart part = page.getActiveEditor();
		   if (!(part instanceof AbstractTextEditor))
		      return;
		ITextEditor editor = (ITextEditor)part;
		
	
		BlockInstance bi = instancesMap.get(obj);
		EObject element = null ;
		if (bi instanceof DeclarationInstance){
			if(((DeclarationInstance)bi).getInstance() != null){
				element = ((DeclarationInstance)bi).getInstance();
				LeafNode tr_source_cn = (LeafNode) NodeModelUtils.findNodesForFeature(element, FiacrePackage.eINSTANCE.getComponentInstance_Component()).get(0);
				editor.selectAndReveal(tr_source_cn.getOffset(), tr_source_cn.getLength());
			}
			else{
				if(bi instanceof ComponentDeclarationInstance)
				{
					element = ((ComponentDeclarationInstance)bi).getComponent();
					LeafNode tr_source_cn = (LeafNode) NodeModelUtils.findNodesForFeature(element, FiacrePackage.eINSTANCE.getNamedElement_Name()).get(0);
					editor.selectAndReveal(tr_source_cn.getOffset(), tr_source_cn.getLength());
				}
				else
					element = ((ProcessDeclarationInstance)bi).getProcess();
					LeafNode tr_source_cn = (LeafNode) NodeModelUtils.findNodesForFeature(element, FiacrePackage.eINSTANCE.getNamedElement_Name()).get(0);
					editor.selectAndReveal(tr_source_cn.getOffset(), tr_source_cn.getLength());
			}
		}
		else{
			element = ((CompositionInstance)bi).getComposition();
			ICompositeNode tr_source_cn =  NodeModelUtils.findActualNodeFor(element);
			for (INode i: tr_source_cn.getChildren()){
				if(i instanceof LeafNode && i.getText().equals("par"))
					editor.selectAndReveal(i.getOffset(), i.getLength());
			}
			
		}
		
		
	}
	
	
	/**
	 * Maps a Executed Model State with Tag key and maps its activities Stack associated with the same key
	 * @param tag The Tag is a character string given by the user.
	 */
	public void addStateToMap(String tag) { ////////////////not enough necessary
		stateMap.put(tag, FiacreSimulator.getLibTTS().getTTSSimulator().getState());
		Stack<ActionState> tagActionStack = (Stack<ActionState>) actionStack.clone();
//		Stack<ActionState> tagActionStack=new Stack<ActionState>();
//		for (ActionState a : actionStack) {
//			tagActionStack.push(a);
//		}
		StateStructure ss = new StateStructure();
		ss.interfaceStack = tagActionStack;
		ss.modelStack = (Stack<TTSState>) FiacreSimulator.getLibTTS().getTTSSimulator().getPrevious_states().clone();
		activitiesStackMap.put(tag, ss);
		updateSavedStatesView();
	}
	
	/**
	 * Makes an update to show the saved States on SavedStates window (view part). 
	 * <p>
	 * Calls an update by giving a list of saved states during execution.
	 */
	public void updateSavedStatesView() {
		//calls update by passing a list of SavedStates as parameter.
		savedStatesView.update(returnSavedStates());
	}

	/**
	 * Takes each element from the state map and puts it in a list
	 * @return list of Tag character string contained by stateMap
	 */
	private ArrayList<String> returnSavedStates() {
		ArrayList<String> list = new ArrayList<String>();
		for (Map.Entry<String, TTSState> iterator : stateMap.entrySet()){
			list.add(iterator.getKey());
		}
		return list;
	}

	/**
	 * Removes a saved state chosen by user on the SavedStateView and its activities stack associated.
	 * @param tag The state that will be removed from stateMap
	 */
	public void deleteState(String tag) {
		stateMap.remove(tag);
		activitiesStackMap.remove(tag);
		updateSavedStatesView();
		
	}
	
	/**
	 * Returns the simulation to saved state selected and updates all views.
	 * @param tag The state that will be updated in simulator 
	 */
	public void goToState(String tag) {
        FiacreSimulator.getLibTTS().getTTSSimulator().setState(stateMap.get(tag));
        actionStack = (Stack<ActionState>) activitiesStackMap.get(tag).interfaceStack.clone();
        FiacreSimulator.getLibTTS().getTTSSimulator().setPrevious_states((Stack<TTSState>) activitiesStackMap.get(tag).modelStack.clone());
        updateAll();
	}
	
	/**
	 * Display a temporary label attached to the Instance Flat name.
	 * @param obj The treeObject representative of the instance selected.
	 */
	public String returnFlatName(TreeObject obj) {
		BlockInstance bI = instancesMap.get(obj);
		if (bI instanceof DeclarationInstance)
			return ((DeclarationInstance) bI).getFlatname();
		return "Composition";
	}
}
