Skip to content
Snippets Groups Projects
AvatarPanelDrawer.java 49.2 KiB
Newer Older
/* Copyright or (C) or Copr. GET / ENST, Telecom-Paris, Ludovic Apvrille
 * 
 * ludovic.apvrille AT enst.fr
 * 
 * This software is a computer program whose purpose is to allow the
 * edition of TURTLE analysis, design and deployment diagrams, to
 * allow the generation of RT-LOTOS or Java code from this diagram,
 * and at last to allow the analysis of formal validation traces
 * obtained from external tools, e.g. RTL from LAAS-CNRS and CADP
 * from INRIA Rhone-Alpes.
 * 
 * This software is governed by the CeCILL  license under French law and
 * abiding by the rules of distribution of free software.  You can  use,
 * modify and/ or redistribute the software under the terms of the CeCILL
 * license as circulated by CEA, CNRS and INRIA at the following URL
 * "http://www.cecill.info".
 * 
 * As a counterpart to the access to the source code and  rights to copy,
 * modify and redistribute granted by the license, users are provided only
 * with a limited warranty  and the software's author,  the holder of the
 * economic rights,  and the successive licensors  have only  limited
 * liability.
 * 
 * In this respect, the user's attention is drawn to the risks associated
 * with loading,  using,  modifying and/or developing or reproducing the
 * software by the user in light of its specific status of free software,
 * that may mean  that it is complicated to manipulate,  and  that  also
 * therefore means  that it is reserved for developers  and  experienced
 * professionals having in-depth computer knowledge. Users are therefore
 * encouraged to load and test the software's suitability as regards their
 * requirements in conditions enabling the security of their systems and/or
 * data to be ensured and,  more generally, to use and operate it in the
 * same conditions as regards security.
 * 
 * The fact that you are presently reading this means that you have had
 * knowledge of the CeCILL license and that you accept its terms.
 */



 
package ui;


import avatartranslator.*;
import common.CanBeTagged;
import common.Tag;
import myutil.TraceManager;
import ui.avatarbd.*;
import ui.avatarsmd.*;

import java.awt.*;
import java.util.List;

/**
 * Class AvatarPanelDrawer
 * Possible states of TGComponent
 * Creation: 12/06/2024
 * @author Ludovic APVRILLE
 * @see avatartranslator.AvatarSpecification
 */
public class AvatarPanelDrawer {

	private boolean hasCrypto = false;

	public AvatarPanelDrawer() {
	}
	public void drawPanel(AvatarSpecification avspec, AvatarDesignPanel adp, boolean useOriginalValuesFirst, boolean useOriginalPositionSMD) {
		//
		// Check Errors in AVSPEC
		avspec.removeAnomalies();
		TraceManager.addDev("Checking syntax of avatar spec.");
		ArrayList<AvatarError> list = AvatarSyntaxChecker.checkSyntaxErrors(avspec);
		for (AvatarError error : list) {
			TraceManager.addDev("\n*********** Error: " + error.toString() + "\n\n");
		}
		//TraceManager.addDev("Check done. " + checkingErrors.size() + " errors found\nAvatar Spec:\n" + avspec.toString());

		TraceManager.addDev("Avspec to be drawn:" + avspec.toStringRecursive(false));


		// Go for drawing!
		hasCrypto = false;
		//Map<String, Set<String>> originDestMap = new HashMap<String, Set<String>>();
		Map<String, AvatarBDBlock> blockMap = new HashMap<String, AvatarBDBlock>();
		if (adp == null) {
			return;
		}
		if (avspec == null) {
			return;
		}
		AvatarBDPanel abd = adp.abdp;
		abd.getTdmm().setOn(false);
		// Application global code
		abd.setMainCode(avspec.getApplicationCode());

		//Find all blocks, create nested blocks starting from top left
		int xpos = 10;
		int ypos = 40;

		// Create blocks recursively, starting from top level ones with no father
		// Lowest level blocks should be 100x100, next should be 100x(number of children*100+50)...etc,
		// Find level #, 0 refers to no father, etc
		Map<AvatarBlock, Integer> blockLevelMap = new HashMap<AvatarBlock, Integer>();
		Map<AvatarBlock, Integer> blockSizeMap = new HashMap<AvatarBlock, Integer>();
		Map<AvatarBlock, Integer> blockIncMap = new HashMap<AvatarBlock, Integer>();
		int maxLevel = 0;
		for (AvatarBlock ab : avspec.getListOfBlocks()) {
			int level = 0;
			AvatarBlock block = ab;
			while (block.getFather() != null) {
				if (blockSizeMap.containsKey(block.getFather())) {
					blockSizeMap.put(block.getFather(), blockSizeMap.get(block.getFather()) + 1);
				} else {
					blockSizeMap.put(block.getFather(), 1);
					blockIncMap.put(block.getFather(), 10);
				}
				level++;
				block = block.getFather();
			}
			if (level > maxLevel) {
				maxLevel = level;
			}
			if (!blockSizeMap.containsKey(block)) {
				blockSizeMap.put(block, 0);
				blockIncMap.put(block, 10);
			}
			blockLevelMap.put(ab, level);
		}


		for (int level = 0; level < maxLevel + 1; level++) {
			for (AvatarBlock ab : avspec.getListOfBlocks()) {
				if (blockLevelMap.get(ab) == level) {
					if (level == 0) {
						TraceManager.addDev("New block at level 0");
						AvatarBDBlock bl = new AvatarBDBlock(xpos, ypos, abd.getMinX(), abd.getMaxX(), abd.getMinY(), abd.getMaxY(), false,
								null, abd);
						if ((ab.getReferenceObject() != null) && (ab.getReferenceObject() instanceof CDElement)) {
							CDElement cd = (CDElement) ab.getReferenceObject();
							bl.setUserResize(cd.getX(), cd.getY(), cd.getWidth(), cd.getHeight());
							addComponent(ab, abd, bl, cd.getX(), cd.getY(), false, true);
							addComponent(ab, abd, bl, xpos, ypos, false, true);
							bl.resize(100 * blockSizeMap.get(ab) + 100, 100 + (maxLevel - level) * 50);
						}
						drawBlockProperties(avspec, ab, bl, useOriginalValuesFirst);
						AvatarSMDPanel smp = adp.getAvatarSMDPanel(bl.getValue());
						smp.getTdmm().setOn(false);
						//TraceManager.addDev("\nBuilding state machine of block " + ab.getName() + " smd:" + ab.getStateMachine().toString() + "\n" +
						//       "\n");
						buildStateMachine(ab, bl, smp, useOriginalValuesFirst, useOriginalPositionSMD);
						smp.getTdmm().setOn(true);
						//TraceManager.addDev("Putting in block")
						blockMap.put(bl.getValue().split("__")[bl.getValue().split("__").length - 1], bl);
						xpos += 100 * blockSizeMap.get(ab) + 200;
					} else {
						TraceManager.addDev("New block at level " + level);
						AvatarBDBlock father =
								blockMap.get(ab.getFather().getName().split("__")[ab.getFather().getName().split("__").length - 1]);
						TraceManager.addDev("Father name: " + father.getBlockName());
						if (father == null) {
							//
							continue;
						}
						AvatarBDBlock bl = new AvatarBDBlock(father.getX() + blockIncMap.get(ab.getFather()), father.getY() + 10,
								abd.getMinX(), abd.getMaxX(), abd.getMinY(), abd.getMaxY(), false, father, abd);
                        /*if ((ab.getReferenceObject() != null) && (ab.getReferenceObject() instanceof CDElement)) {
                            CDElement cd = (CDElement) ab.getReferenceObject();
                            bl.setUserResize(cd.getX(), cd.getY(), cd.getWidth(), cd.getHeight());
                            abd.addComponent(bl, cd.getX(), cd.getY(), false, true);
                        } else {*/
						//abd.addComponent(bl, xpos, ypos, false, true);
						//bl.resize(100 * blockSizeMap.get(ab) + 100, 100 + (maxLevel - level) * 50);
						//}
						addComponent(ab, abd, bl, father.getX() + blockIncMap.get(ab.getFather()), father.getY() + 10, false, true);
						if ((ab.getReferenceObject() != null) && (ab.getReferenceObject() instanceof CDElement)) {
							CDElement cd = (CDElement) ab.getReferenceObject();
							bl.setUserResize(cd.getX(), cd.getY(), cd.getWidth(), cd.getHeight());
						} else {

							if (blockSizeMap.containsKey(ab)) {
								size = 100 * blockSizeMap.get(ab) + 50;
							}
							bl.resize(size, 100 + (maxLevel - level) * 50);
						}
						drawBlockProperties(avspec, ab, bl, useOriginalValuesFirst);
						abd.attach(bl);
						AvatarSMDPanel smp = adp.getAvatarSMDPanel(bl.getValue());
						buildStateMachine(ab, bl, smp, useOriginalValuesFirst, useOriginalPositionSMD);
						blockMap.put(bl.getValue().split("__")[bl.getValue().split("__").length - 1], bl);
						blockIncMap.put(ab.getFather(), blockIncMap.get(ab.getFather()) + size + 10);
					}
				}
			}
		}

		// Data types
		// Put them on the lower part


		for (AvatarRelation ar : avspec.getRelations()) {
			String bl1 = ar.block1.getName();
			String bl2 = ar.block2.getName();

			bl1 = getLastKeyword(bl1);
			bl2 = getLastKeyword(bl2);

			Vector<Point> points = new Vector<Point>();

			//TraceManager.addDev("bl1:" + bl1 + " bl2:" + bl2);

			// Printing blockMap
            /*for(String s: blockMap.keySet()) {
                AvatarBDBlock block = blockMap.get(s);
                TraceManager.addDev("String s:" + s + " / Block : " + block.getBlockName());
            }*/

			if ((blockMap.get(bl1) != null) && (blockMap.get(bl2) != null)) {
				//TraceManager.addDev("Handling blocks");
				AvatarBDBlock b1 = blockMap.get(bl1);
				AvatarBDBlock b2 = blockMap.get(bl2);
				//TGConnectingPoint p1 = blockMap.get(bl1).findFirstFreeTGConnectingPoint(true, true);
				//TGConnectingPoint p2 = blockMap.get(bl2).findFirstFreeTGConnectingPoint(true, true);


				TGConnectingPoint p1 = null, p2 = null;

				if (ar.getOtherReferenceObjects() != null) {
					if ((ar.getReferenceObject() instanceof AvatarBDPortConnector) && (ar.getOtherReferenceObjects().size() > 1)) {
						//TraceManager.addDev("*----* Found reference objects before / after port connector");
						AvatarBDPortConnector connOld = (AvatarBDPortConnector) (ar.getReferenceObject());
						if ((ar.getOtherReferenceObjects().get(0) instanceof TGComponent) && (ar.getOtherReferenceObjects().get(1) instanceof TGComponent)) {
							TGComponent tgc1 = (TGComponent) (ar.getOtherReferenceObjects().get(0));
							TGComponent tgc2 = (TGComponent) (ar.getOtherReferenceObjects().get(1));

							int index1 = tgc1.getIndexOfTGConnectingPoint(connOld.getTGConnectingPointP1());
							int index2 = tgc2.getIndexOfTGConnectingPoint(connOld.getTGConnectingPointP2());

							if ((index1 != -1) && (index2 != -1)) {
								p1 = b1.getFreeTGConnectingPoint(index1);
								p2 = b2.getFreeTGConnectingPoint(index2);
							}
					p1 = b1.closerFreeTGConnectingPointNoOverlay(b2.getX(), b2.getY(), false, true);
					p2 = b2.closerFreeTGConnectingPointNoOverlay(b1.getX(), b1.getY(), true, false);
				if (p1 != null && p2 != null) {
					p1.setFree(false);
					p2.setFree(false);

                    /*if (bl2.equals(bl1)) {
                        // Add 2 point so the connection looks square
                        Point p = new Point(p1.getX(), p1.getY() - 10);
                        points.add(p);
                        p = new Point(p2.getX(), p2.getY() - 10);
                        points.add(p);
                    }*/

					if (ar.getOtherReferenceObjects() != null) {
						for (int i = 0; i < ar.getOtherReferenceObjects().size(); i++) {
							Object o = ar.getOtherReferenceObjects().get(i);
							if (o instanceof TGCPointOfConnector) {
								TGCPointOfConnector op = (TGCPointOfConnector) o;
								points.add(new Point(op.getX(), op.getY()));
							}
						}
					}

					AvatarBDPortConnector conn = new AvatarBDPortConnector(0, 0, 0, 0, 0, 0, true, null,
							abd, p1, p2, points);
					addComponent(ar, abd, conn, 0, 0, false, true);
					conn.setAsynchronous(ar.isAsynchronous());
					conn.setSynchronous(!ar.isAsynchronous());
					conn.setAMS(false);
					conn.setBlocking(ar.isBlocking());
					conn.setPrivate(ar.isPrivate());
					conn.setSizeOfFIFO(ar.getSizeOfFIFO());

					for (int indexSig = 0; indexSig < ar.getSignals1().size(); indexSig++) {

						//TraceManager.addDev("Adding signal 1: " + ar.getSignal1(i).toString() + " of block " + ar.block1.getName());
						conn.addSignal(ar.getSignal1(indexSig).toString(), ar.getSignal1(indexSig).getInOut() == 0, ar.block1.getName().contains(bl1));
						//TraceManager.addDev("Adding signal 2:" + ar.getSignal2(i).toString() + " of block " + ar.block2.getName());
						conn.addSignal(ar.getSignal2(indexSig).toString(), ar.getSignal2(indexSig).getInOut() == 0, !ar.block2.getName().contains(bl2));

						conn.updateAllSignals();
					}


					conn.updateAllSignals();
				}
			}
		}

		xpos = 50;
		ypos = 500;

		for (AvatarDataType adt : avspec.getDataTypes()) {
			AvatarBDDataType abdType = new AvatarBDDataType(xpos, ypos, abd.getMinX(), abd.getMaxX(), abd.getMinY(), abd.getMaxY(), false,
					null, abd);
			abdType.setDataTypeName(adt.getName());
			// Adding attributes
			for (AvatarAttribute attr : adt.getAttributes()) {
				if (attr.getType() == AvatarType.UNDEFINED) {
					abdType.addAttribute(new TAttribute(attr.isConstant() ? TAttribute.CONSTANT : TAttribute.VARIABLE, attr.getName(),
							attr.getType().getDefaultInitialValue(), attr.getDataType().getName()));
				else {
					int type = 4;
					if (attr.getType() == AvatarType.INTEGER) {
						type = 0;
					}
					String initialValue = (attr.getProvidedInitialValue() == null ? "" : attr.getProvidedInitialValue());
					abdType.addAttribute(new TAttribute(attr.isConstant() ? TAttribute.CONSTANT : TAttribute.VARIABLE, 0, attr.getName(),
							initialValue, type));
				}
			}


			// Drawing
			if ((adt.getReferenceObject() != null) && (adt.getReferenceObject() instanceof CDElement)) {
				CDElement cd = ((CDElement) (adt.getReferenceObject()));
				abdType.setUserResize(cd.getX(), cd.getY(), cd.getWidth(), cd.getHeight());
				addComponent(adt, abd, abdType, cd.getX(), cd.getY(), false, true);
				addComponent(adt, abd, abdType, xpos, ypos, false, true);


		//Add message and key datatype if there is a cryptoblock

		xpos = 50;
		ypos += 200;
		if (hasCrypto) {
			AvatarBDDataType message = new AvatarBDDataType(xpos, ypos, xpos, xpos * 2, ypos, ypos * 2, false, null, abd);
			message.setValue("Message");

			abd.addComponent(message, xpos, ypos, false, true);
			message.resize(200, 100);
			xpos += 400;

			AvatarBDDataType key = new AvatarBDDataType(xpos, ypos, xpos, xpos * 2, ypos, ypos * 2, false, null, abd);
			key.setValue("Key");
			TAttribute attr = new TAttribute(0, 2, "data", "0", 8);
			message.addAttribute(attr);
			key.addAttribute(attr);
			key.resize(200, 100);
			abd.addComponent(key, xpos, ypos, false, true);
		}

		adp.getAvatarBDPanel().connectSignals();
		// Safety and performance pragmas
		makeSafetyPragmas(avspec, adp);
		makePerformancePragmas(avspec, adp);

		// Notes
		makeNotes(avspec, adp);
		abd.getTdmm().setOn(true);
		adp.getAvatarBDPanel().repaint();

	}

	public void buildStateMachine(AvatarBlock ab, AvatarBDBlock bl, AvatarSMDPanel smp, boolean useOriginalValuesFirst,
								  boolean useOriginalPositionSMD) {

		//TraceManager.addDev("Building state machine of " + ab.getName());

		Map<AvatarTransition, TGComponent> tranSourceMap = new HashMap<AvatarTransition, TGComponent>();
		Map<AvatarTransition, AvatarStateMachineElement> tranDestMap = new HashMap<>();
		Map<AvatarStateMachineElement, TGComponent> locMap = new HashMap<>();
		Map<AvatarStateMachineElement, TGComponent> SMDMap = new HashMap<>();
		Map<TGComponent, TGComponent> newTGCtoOldOne = new HashMap<>();
		Map<TGComponent, AvatarStateMachineElement> newTGCToAvatarElement = new HashMap<>();

		Map<Object, TGComponent> refMap = new HashMap<>();

		//Build the state machine
		int smx = 400;
		int smy = 40;

		if (smp == null) {
			return;
		}

		smp.removeAll();
		AvatarStateMachine asm = ab.getStateMachine();

		//TraceManager.addDev("\nState machine: " + asm.toString() + "\n\n");
		//TraceManager.addDev("\nRecursive state machine: " + asm.toStringRecursive() + "\n\n");

		//Remove the empty check states

		AvatarStartState start = asm.getStartState();

		addStates(start, ab, smx, smy, smp, bl, SMDMap, newTGCtoOldOne, newTGCToAvatarElement, locMap, tranDestMap, tranSourceMap, refMap,
				useOriginalValuesFirst,
				useOriginalPositionSMD);

		//TraceManager.addDev("\nState machine: " + asm.toString() + "\n\n");

		// Handling components to be swallowed
		LinkedList<TGComponent> toBeRemoved = new LinkedList<>();
		for(AvatarStateMachineElement lowAsme: ab.getStateMachine().getListOfElements()) {
			AvatarStateMachineElement upState = lowAsme.getState();

			if (upState != null) {
				TGComponent tgcLow = SMDMap.get(lowAsme);
				TGComponent tgcUp = SMDMap.get(upState);

				if (tgcUp instanceof AvatarSMDState) {
					if (tgcLow != null) {
						toBeRemoved.add(tgcLow);

					}
					((AvatarSMDState) tgcUp).addSwallowedTGComponent(tgcLow, tgcLow.getX(), tgcLow.getY());
				}

			}

		}

		for(TGComponent toRemoveTGC: toBeRemoved) {
			smp.removeComponent(toRemoveTGC);
		}

		//Add transitions
		for (AvatarTransition t : tranSourceMap.keySet()) {
			if (tranSourceMap.get(t) == null || tranDestMap.get(t) == null || locMap.get(tranDestMap.get(t)) == null) {
				continue;
			}

			int x = tranSourceMap.get(t).getX() + tranSourceMap.get(t).getWidth() / 2;
			int y = tranSourceMap.get(t).getY() + tranSourceMap.get(t).getHeight();

			//    TGConnectingPoint p1 = tranSourceMap.get(t).findFirstFreeTGConnectingPoint(true,false);


            /*for(Object o: t.getReferenceObject()) {

            }*/

			TGConnectingPoint p1 = null, p2 = null;

			if ((t.getOtherReferenceObjects() != null) && (t.getOtherReferenceObjects().size() > 4)) {
				try {
					Point p = (Point) (t.getOtherReferenceObjects().get(4));
					TGComponent newTGC1 = refMap.get(t.getOtherReferenceObjects().get(2));
					if (newTGC1 != null) {
						p1 = newTGC1.getFreeTGConnectingPoint(p.x);
					}
					TGComponent newTGC2 = refMap.get(t.getOtherReferenceObjects().get(3));
					if (newTGC2 != null) {
						p2 = newTGC2.getFreeTGConnectingPoint(p.y);
					}

				} catch (Exception e) {
					TraceManager.addDev("**** EXCEPTION: " + e.getMessage());
				}
			}



			if ((p1 == null) || (p2 == null)) {
				if (p1 == null) {
					p1 = tranSourceMap.get(t).closerFreeTGConnectingPointNoOverlay(x, y, true, false);
					//p1 = tranSourceMap.get(t).closerFreeTGConnectingPoint(x, y, false, true);
					if (p1 == null) {
						TraceManager.addDev("NULL P1 in " + tranSourceMap.get(t).getName() + "/" + tranSourceMap.get(t).getValue());
						p1 = tranSourceMap.get(t).findFirstFreeTGConnectingPoint(true, false);
						if (p1 == null) {
							TraceManager.addDev("\tstill NULL P1");
						}
						//p1=tranSourceMap.get(t).closerFreeTGConnectingPoint(x,y,true, true);
					}
					x = locMap.get(tranDestMap.get(t)).getX() + locMap.get(tranDestMap.get(t)).getWidth() / 2;
					y = locMap.get(tranDestMap.get(t)).getY();
					if (tranSourceMap.get(t).getY() > locMap.get(tranDestMap.get(t)).getY()) {
						y = locMap.get(tranDestMap.get(t)).getY() + locMap.get(tranDestMap.get(t)).getHeight() / 2;
						if (tranSourceMap.get(t).getX() < locMap.get(tranDestMap.get(t)).getX()) {
							x = locMap.get(tranDestMap.get(t)).getX();
						} else {
							x = locMap.get(tranDestMap.get(t)).getX() + locMap.get(tranDestMap.get(t)).getWidth();
						}
					}
				}
				if (p2 == null) {
					p2 = locMap.get(tranDestMap.get(t)).closerFreeTGConnectingPointNoOverlay(x, y, false, true);
					//p2 = locMap.get(tranDestMap.get(t)).closerFreeTGConnectingPoint(x, y, true, false);
					if (p2 == null) {
						TraceManager.addDev("NULL P2 in " + locMap.get(tranDestMap.get(t)).getName() + "/" + locMap.get(tranDestMap.get(t)).getValue());
						p2 = locMap.get(tranDestMap.get(t)).findFirstFreeTGConnectingPoint(false, true);
						if (p2 == null) {
							TraceManager.addDev("\tstill NULL P2");
						}
					}
				}
			} else {
				//TraceManager.addDev("Using original connecting points");
			}
			Vector<Point> points = new Vector<Point>();
			if (p1 == null || p2 == null) {
				TraceManager.addDev("Null P1 and P2");

				return;
			}
			if (t.getOtherReferenceObjects() != null) {
				for (int i = 0; i < t.getOtherReferenceObjects().size(); i++) {
					Object o = t.getOtherReferenceObjects().get(i);
					if (o instanceof TGCPointOfConnector) {
						TGCPointOfConnector op = (TGCPointOfConnector) o;
						points.add(new Point(op.getX(), op.getY()));
					}
				}
			}
			AvatarSMDConnector SMDCon = new AvatarSMDConnector(p1.getX(), p1.getY(), p1.getX(), p1.getY(), p1.getX(), p1.getY(), true, null, smp,
					p1, p2, points);
			//
			///
			p1.setFree(false);
			p2.setFree(false);
			String action = "";
			if (t.getActions().size() == 0) {
				action = "";
			} else {
				action = t.getAction(0, useOriginalValuesFirst).toString().replaceAll(" ", "");
			}
			// Delays
			SMDCon.setTransitionTime(t.getMinDelay(useOriginalValuesFirst), t.getMaxDelay(useOriginalValuesFirst), t.getMinCompute(), t.getMaxCompute());

			// Guard
			SMDCon.setTransitionInfo(t.getGuard(useOriginalValuesFirst), action);

Sophie Coudert's avatar
Sophie Coudert committed
			// Probability
			if (t.getProbability() != t.DEFAULT_PROBABILITY) SMDCon.setTransitionProbability("" + (t.getProbability()));
			// Action
			for (int i = 1; i < t.getActions().size(); i++) {
				SMDCon.setTransitionInfo("", t.getAction(i, useOriginalValuesFirst).replaceAll(" ", ""));
			}

Sophie Coudert's avatar
Sophie Coudert committed
			// Transition Law
			SMDCon.setTransitionProbability(t.getDelayDistributionLaw(), t.getDelayExtra1(), t.getDelayExtra2());

			addComponent(t, smp, SMDCon, p1.getX(), p1.getY(), false, true);

			if (t.getOtherReferenceObjects() != null) {
				for (int i = 0; i < t.getOtherReferenceObjects().size(); i++) {
					Object o = t.getOtherReferenceObjects().get(i);
					if (o instanceof AvatarSMDTransitionInfo) {
						//TraceManager.addDev(" ----- Position transition x y width height");
						AvatarSMDTransitionInfo tInfo = (AvatarSMDTransitionInfo) o;
						SMDCon.getAvatarSMDTransitionInfo().setMoveCd(tInfo.getX(), tInfo.getY(), true);
						SMDCon.getAvatarSMDTransitionInfo().resize(tInfo.getWidth(), tInfo.getHeight());
						break;
					}
				}
			}
		}

		// Handling extra attributes (colors, ...)
		for(TGComponent newOne: newTGCtoOldOne.keySet()) {
			TGComponent oldOne = newTGCtoOldOne.get(newOne);
			if (newOne != null) {
				newOne.copyCharacteristicsFrom(oldOne);
			}
		// Setting characteristics from Avatar element
		for(TGComponent newOne: newTGCToAvatarElement.keySet()) {
			AvatarStateMachineElement asme = newTGCToAvatarElement.get(newOne);

			String colorValue = asme.getCharacteristic("color");
			if (colorValue != null) {
				Color color = new Color(Integer.parseInt(colorValue));
				newOne.setCurrentColor(color);
			}
		}

	public void addStates(AvatarStateMachineElement asme, AvatarBlock ab, int x, int y, AvatarSMDPanel smp, AvatarBDBlock bl,
						  Map<AvatarStateMachineElement, TGComponent> SMDMap, Map<TGComponent, TGComponent> newTGCToOldOne,
						  Map<TGComponent, AvatarStateMachineElement> newTGCToAvatarElement,
						  Map<AvatarStateMachineElement, TGComponent> locMap,
						  Map<AvatarTransition, AvatarStateMachineElement> tranDestMap, Map<AvatarTransition, TGComponent> tranSourceMap,
						  Map<Object, TGComponent> refMap,
						  boolean useOriginalValuesFirst, boolean useOriginalPositionSMD) {
		// TGConnectingPoint tp = new TGConnectingPoint(null, x, y, false, false);
		//Create dummy tgcomponent

		if (asme == null) {
			return;
		}

		//TGComponent tgcomp = new AvatarSMDStartState(x, y, smp.getMinX(), smp.getMaxX(), smp.getMinY(), smp.getMaxY(), false, null, smp);
		TGComponent tgcomp = null;
		//TraceManager.addDev("Block " + bl.getName() + " / " + bl.getValue() + " Found: " + asme.getExtendedName());
		int newX = x;
		int newY = y;
		int width = 0;
		int height = 0;

		TGComponent tgc = null;

		if ((asme.getReferenceObject() instanceof TGComponent) && useOriginalPositionSMD) {
			tgc = (TGComponent) (asme.getReferenceObject());
			newX = tgc.getX();
			newY = tgc.getY();
			width = tgc.getWidth();
			height = tgc.getHeight();
		} else {
			newX = x;
			newY = y;
		}

		if (asme instanceof AvatarStartState) {
			//TraceManager.addDev("**** Found Avatar start state in block " + bl.getBlockName());
			AvatarSMDStartState smdss = new AvatarSMDStartState(newX, newY, smp.getMinX(), smp.getMaxX(), smp.getMinY(), smp.getMaxY(), false, null,
					smp);
			tgcomp = smdss;
			addComponent(asme, smp, smdss, newX, newY, false, true);
			if (tgc != null) smdss.resize(width, height);
			SMDMap.put(asme, smdss);
			newTGCToAvatarElement.put(smdss, asme);
			if (tgc != null) {
				newTGCToOldOne.put(smdss, tgc);
			}
			//   tp = smdss.tgconnectingPointAtIndex(0);
			locMap.put(asme, smdss);
			refMap.put(asme.getReferenceObject(), smdss);
		}
		if (asme instanceof AvatarTransition) {
			//
		}
		if (asme instanceof AvatarRandom) {
			AvatarSMDRandom smdr = new AvatarSMDRandom(newX, newY, smp.getMinX(), smp.getMaxX(), smp.getMinY(), smp.getMaxY(), false, null, smp);
			AvatarRandom ar = (AvatarRandom) asme;
			smdr.setVariable(ar.getVariable());
			if (useOriginalValuesFirst && (ar.getOriginalMinValue() != null) && (ar.getOriginalMinValue().length() > 0)) {
				smdr.setMinValue(ar.getOriginalMinValue());
			} else {
				smdr.setMinValue(ar.getMinValue());
			}
			if (useOriginalValuesFirst && (ar.getOriginalMaxValue() != null) && (ar.getOriginalMaxValue().length() > 0)) {
				smdr.setMaxValue(ar.getOriginalMaxValue());
			} else {
				smdr.setMaxValue(ar.getMaxValue());
			}
			addComponent(asme, smp, smdr, newX, newY, false, true);
			if (tgc != null) smdr.resize(width, height);
			tgcomp = smdr;
			SMDMap.put(asme, smdr);
			newTGCToAvatarElement.put(smdr, asme);
			if (tgc != null) {
				newTGCToOldOne.put(smdr, tgc);
			}
			locMap.put(asme, smdr);
			refMap.put(asme.getReferenceObject(), smdr);
		}

		if (asme instanceof AvatarQueryOnSignal) {
			AvatarSMDQueryReceiveSignal smdqrs = new AvatarSMDQueryReceiveSignal(newX, newY, smp.getMinX(), smp.getMaxX(), smp.getMinY(),
					smp.getMaxY(),
					false, null,
					smp);
			smdqrs.setNames(((AvatarQueryOnSignal) asme).getAttribute().getName(), ((AvatarQueryOnSignal) asme).getSignal().getName());
			addComponent(asme, smp, smdqrs, newX, newY, false, true);
			if (tgc != null) smdqrs.resize(width, height);
			tgcomp = smdqrs;
			SMDMap.put(asme, smdqrs);
			newTGCToAvatarElement.put(smdqrs, asme);
			if (tgc != null) {
				newTGCToOldOne.put(smdqrs, tgc);
			}
			locMap.put(asme, smdqrs);
			refMap.put(asme.getReferenceObject(), smdqrs);
		}

		if (asme instanceof AvatarActionOnSignal) {
			//TraceManager.addDev("Block " + bl.getName() + " / " + bl.getValue() + " Found AvatarActionOnSignal: " + asme.getExtendedName());
			avatartranslator.AvatarSignal sig = ((AvatarActionOnSignal) asme).getSignal();
			if (sig.isIn()) {
				AvatarSMDReceiveSignal smdrs = new AvatarSMDReceiveSignal(newX, newY, smp.getMinX(), smp.getMaxX(), smp.getMinY(), smp.getMaxY(),
						false,
						null, smp);
				tgcomp = smdrs;
				smdrs.setCheckLatency(((AvatarActionOnSignal) asme).getCheckLatency());
				if (asme.isCheckable() && asme.isChecked()) {
					smdrs.setCheckableAccessibility(asme.isChecked());
				}
				addComponent(asme, smp, smdrs, newX, newY, false, true);
				//                              String name=sig.minString();
				//
				if (tgc != null) smdrs.resize(width, height);
				AvatarActionOnSignal aaos = (AvatarActionOnSignal) asme;

				String parameters = aaos.getAllOriginalVals();
				//TraceManager.addDev("1. Parameters=" + parameters);
				String parametersA = aaos.getAllVals();


				if (parameters.length() == 0 && parametersA.length() > parameters.length()) {
					parameters = parametersA;
				} else if (!useOriginalValuesFirst) {
					parameters = parametersA;
				}

				//TraceManager.addDev("2. Parameters=" + parameters);

                /*if (((AvatarActionOnSignal) asme).getValues().size() > 0) {
                    parameters += ((AvatarActionOnSignal) asme).getValues().get(0);
                    for (int i = 1; i < ((AvatarActionOnSignal) asme).getValues().size(); i++) {
                        parameters = parameters + "," + ((AvatarActionOnSignal) asme).getValues().get(i);



                }*/
				String name = sig.getName() + "(" + parameters + ")";
				smdrs.setValue(name);
				// sig.setName(name);
				smdrs.recalculateSize();
				SMDMap.put(asme, smdrs);
				newTGCToAvatarElement.put(smdrs, asme);
				if (tgc != null) {
					newTGCToOldOne.put(smdrs, tgc);
				}
				//   tp = smdrs.getFreeTGConnectingPoint(x+smdrs.getWidth()/2,y+smdrs.getHeight());
				//  TGConnectingPoint tp2 = smdrs.getFreeTGConnectingPoint(x+smdrs.getWidth()/2,y);
				locMap.put(asme, smdrs);
				refMap.put(asme.getReferenceObject(), smdrs);

				if (bl.getAvatarSignalFromName(name) == null) {
					//bl.addSignal(new ui.AvatarSignal(0, name, new String[0], new String[0]));
				}

			} else {
				AvatarSMDSendSignal smdss = new AvatarSMDSendSignal(newX, newY, smp.getMinX(), smp.getMaxX(), smp.getMinY(), smp.getMaxY(), false,
						null,
						smp);
				if (asme.isCheckable() && asme.isChecked()) {
					smdss.setCheckableAccessibility(asme.isChecked());
				}
				smdss.setCheckLatency(((AvatarActionOnSignal) asme).getCheckLatency());
				addComponent(asme, smp, smdss, newX, newY, false, true);
				if (tgc != null) smdss.resize(width, height);
				AvatarActionOnSignal aaos = (AvatarActionOnSignal) asme;
				String parameters = aaos.getAllOriginalVals();
				//TraceManager.addDev("1. Parameters=" + parameters);
				String parametersA = aaos.getAllVals();
				if (parameters.length() == 0 && parametersA.length() > parameters.length()) {
					parameters = parametersA;
				} else if (!useOriginalValuesFirst) {
					parameters = parametersA;
				}

				//TraceManager.addDev("2. Parameters=" + parameters);
                /*String parameters = "";
                if (((AvatarActionOnSignal) asme).getValues().size() > 0) {
                    parameters += ((AvatarActionOnSignal) asme).getValues().get(0);
                    for (int i = 1; i < ((AvatarActionOnSignal) asme).getValues().size(); i++) {
                        parameters = parameters + "," + ((AvatarActionOnSignal) asme).getValues().get(i);
                    }
                }*/
				String name = sig.getName() + "(" + parameters + ")";
				//String name=sig.minString();
				smdss.setValue(name);
				smdss.recalculateSize();
				SMDMap.put(asme, smdss);
				newTGCToAvatarElement.put(smdss, asme);
				if (tgc != null) {
					newTGCToOldOne.put(smdss, tgc);
				}
				//  tp = smdss.getFreeTGConnectingPoint(x+smdss.getWidth()/2,y+smdss.getHeight());
				//      TGConnectingPoint tp2 = smdss.getFreeTGConnectingPoint(x+smdss.getWidth()/2,y);
				locMap.put(asme, smdss);
				refMap.put(asme.getReferenceObject(), smdss);
				if (bl.getAvatarSignalFromName(name) == null) {
					// bl.addSignal(new ui.AvatarSignal(1, name, new String[0], new String[0]));
				}
			}

		}
		if (asme instanceof AvatarStopState) {
			AvatarSMDStopState smdstop = new AvatarSMDStopState(newX, newY, smp.getMinX(), smp.getMaxX(), smp.getMinY(), smp.getMaxY(), false, null,
					smp);
			tgcomp = smdstop;
			SMDMap.put(asme, smdstop);
			newTGCToAvatarElement.put(smdstop, asme);
			if (tgc != null) {
				newTGCToOldOne.put(smdstop, tgc);
			}
			addComponent(asme, smp, smdstop, newX, newY, false, true);
			if (tgc != null) smdstop.resize(width, height);
			//  tp = smdstop.tgconnectingPointAtIndex(0);
			locMap.put(asme, smdstop);
			refMap.put(asme.getReferenceObject(), smdstop);
		}

		if (asme instanceof AvatarSetTimer) {
			AvatarSMDSetTimer timerSet = new AvatarSMDSetTimer(newX, newY, smp.getMinX(), smp.getMaxX(), smp.getMinY(), smp.getMaxY(), false, null,
					smp);
			AvatarSetTimer ast = (AvatarSetTimer) asme;
			String timerValue = ast.getTimerValue();
			if (useOriginalValuesFirst) {
				if ((ast.getTimerOriginalValue() != null) && (ast.getTimerOriginalValue().length() > 0)) {
					timerValue = ast.getTimerOriginalValue();
				}
			}
			timerSet.setComplexValue(ast.getTimer().getName(), timerValue);
			tgcomp = timerSet;
			SMDMap.put(asme, timerSet);
			newTGCToAvatarElement.put(timerSet, asme);
			if (tgc != null) {
				newTGCToOldOne.put(timerSet, tgc);
			}
			addComponent(asme, smp, timerSet, newX, newY, false, true);
			if (tgc != null) timerSet.resize(width, height);
			//  tp = smdstop.tgconnectingPointAtIndex(0);
			locMap.put(asme, timerSet);
			refMap.put(asme.getReferenceObject(), timerSet);
		}

		if (asme instanceof AvatarExpireTimer) {
			AvatarSMDExpireTimer timerExpire = new AvatarSMDExpireTimer(newX, newY, smp.getMinX(), smp.getMaxX(), smp.getMinY(), smp.getMaxY(), false,
					null,
					smp);
			timerExpire.setComplexValue(((AvatarExpireTimer) asme).getTimer().getName());
			tgcomp = timerExpire;

			SMDMap.put(asme, timerExpire);
			newTGCToAvatarElement.put(timerExpire, asme);
			if (tgc != null) {
				newTGCToOldOne.put(timerExpire, tgc);
			}
			addComponent(asme, smp, timerExpire, newX, newY, false, true);
			if (tgc != null) timerExpire.resize(width, height);
			//  tp = smdstop.tgconnectingPointAtIndex(0);
			locMap.put(asme, timerExpire);
			refMap.put(asme.getReferenceObject(), timerExpire);
		}

		if (asme instanceof AvatarResetTimer) {
			AvatarSMDResetTimer timerReset = new AvatarSMDResetTimer(newX, newY, smp.getMinX(), smp.getMaxX(), smp.getMinY(), smp.getMaxY(), false,
					null,
					smp);
			timerReset.setComplexValue(((AvatarResetTimer) asme).getTimer().getName());
			tgcomp = timerReset;
			SMDMap.put(asme, timerReset);
			newTGCToAvatarElement.put(timerReset, asme);
			if (tgc != null) {
				newTGCToOldOne.put(timerReset, tgc);
			}
			addComponent(asme, smp, timerReset, newX, newY, false, true);
			if (tgc != null) timerReset.resize(width, height);
			//  tp = smdstop.tgconnectingPointAtIndex(0);
			locMap.put(asme, timerReset);
			refMap.put(asme.getReferenceObject(), timerReset);
		}

		if (asme instanceof AvatarState) {
			//check if empty checker state
			/* if (asme.getName().contains("signalstate_")) {
			//don't add the state, ignore next transition,
			if (asme.getNexts().size()==1) {
			AvatarStateMachineElement next = asme.getNext(0).getNext(0);
			//Reroute transition
			for (AvatarTransition at: tranDestMap.keySet()) {
			if (tranDestMap.get(at) == asme) {
			tranDestMap.put(at, next);
			}
			}
			addStates(next, x, y, smp,bl, SMDMap, locMap, tranDestMap, tranSourceMap);
			return;
			}
			}*/
			AvatarSMDState smdstate = new AvatarSMDState(newX, newY, smp.getMinX(), smp.getMaxX(), smp.getMinY(), smp.getMaxY(), false, null, smp);
			if (asme.isCheckable() && asme.isChecked()) {
				smdstate.setCheckableAccessibility(asme.isChecked());
			}
			if (asme.isTrueCharacteristic("invariant")) {
				smdstate.setCheckableInvariant(true);
			}
			if (((AvatarState) asme).getEntryCode() != null) {
				smdstate.setEntryCode(((AvatarState) asme).getEntryCode());
			}
			smdstate.setCheckLatency(((AvatarState) asme).getCheckLatency());
			tgcomp = smdstate;
			addComponent(asme, smp, smdstate, newX, newY, false, true);
			if (tgc != null) smdstate.resize(width, height);
			smdstate.setValue(asme.getName());
			//smdstate.recalculateSize();
			SMDMap.put(asme, smdstate);
			newTGCToAvatarElement.put(smdstate, asme);
			if (tgc != null) {
				newTGCToOldOne.put(smdstate, tgc);
			}
			//   tp = smdstate.getFreeTGConnectingPoint(x+smdstate.getWidth()/2,y+smdstate.getHeight());
			//  TGConnectingPoint tp2 = smdstate.getFreeTGConnectingPoint(x+smdstate.getWidth()/2,y);
			locMap.put(asme, smdstate);
			refMap.put(asme.getReferenceObject(), smdstate);

			if (asme.getReferenceObjects() != null) {
				for (Object o : asme.getReferenceObjects()) {
					if ((o != asme.getReferenceObject()) && (o instanceof TGComponent)) {
						TGComponent tmpT = (TGComponent) o;
						//TraceManager.addDev("Drawing second state called " + asme.getName());
						AvatarSMDState smdstateBis = new AvatarSMDState(tmpT.getX(), tmpT.getY(), smp.getMinX(), smp.getMaxX(), smp.getMinY(),
								smp.getMaxY(), false, null, smp);
						//tgcomp = smdstate;
						smdstateBis.setCheckableAccessibility(((AvatarState) asme).getCheckLatency());
						if (asme.isTrueCharacteristic("invariant")) {
							smdstateBis.setCheckableInvariant(true);
						}
						newTGCToAvatarElement.put(smdstateBis, asme);
						newTGCToOldOne.put(smdstateBis, tmpT);
						addComponent(asme, smp, smdstateBis, tmpT.getX(), tmpT.getY(), false, true);
						smdstateBis.resize(tmpT.getWidth(), tmpT.getHeight());
						smdstateBis.setValue(asme.getName());
						refMap.put(o, smdstateBis);
					}
				}
			}
		}

		int i = 0;
		int diff = 300;
		int ydiff = 50;
		//int num = asme.nbOfNexts();
        /*if (!(asme instanceof AvatarTransition)) {
            //TraceManager.addDev("element asme: " + asme.toString());
            if (asme.getNexts() != null) {
                for (AvatarStateMachineElement el : asme.getNexts()) {
                    if (!(el instanceof AvatarTransition)) {
                        if ((asme.getReferenceObject() != null) && (asme.getReferenceObject() instanceof CDElement)) {
                            CDElement cd = (CDElement) asme.getReferenceObject();
                            tgcomp.setCd(cd.getX(), cd.getY());
                        }
                    }
                }
            }
        }*/
		if (asme.getNexts() != null) {
			for (AvatarStateMachineElement el : asme.getNexts()) {
                /*TraceManager.addDev("Block " + bl.getName() + " / " + bl.getValue() +
                        " Handling next of " + asme.getExtendedName() + ": " + el.getExtendedName());*/
				if (el instanceof AvatarTransition) {
					tranSourceMap.put((AvatarTransition) el, tgcomp);
				} else {
					if (asme instanceof AvatarTransition) {
						AvatarTransition t = (AvatarTransition) asme;
						tranDestMap.put(t, el);
					}
				}
				if (!SMDMap.containsKey(el)) {
                    /*TraceManager.addDev("not in map: Block " + bl.getName() + " / " + bl.getValue() +
                            " Handling next of " + asme.getExtendedName() + ": " + el.getExtendedName());*/
					addStates(el, ab, x + diff * i, y + ydiff, smp, bl, SMDMap, newTGCToOldOne, newTGCToAvatarElement,
							locMap, tranDestMap,
							tranSourceMap, refMap,
							useOriginalValuesFirst, useOriginalPositionSMD);
			//return;
		}

		// Considering internal elements
		AvatarStartState avatarStartState = ab.getStateMachine().getStartStateOf(asme);

		if (avatarStartState != null) {
			TraceManager.addDev("\t-> Found composite state in block " + ab.getName());
			if (!SMDMap.containsKey(avatarStartState)) {
				addStates(avatarStartState, ab, x + diff * i, y + ydiff, smp, bl, SMDMap, newTGCToOldOne, newTGCToAvatarElement,
						locMap, tranDestMap
						, tranSourceMap, refMap,
						useOriginalValuesFirst, useOriginalPositionSMD);