Tom Troppmann 5 years ago
parent
commit
9a6dfaddee

BIN
res/Images/Thumbs.db


BIN
res/Images/arrowUp.png


+ 2 - 2
src/classes/CpsEdge.java

@@ -286,8 +286,8 @@ public class CpsEdge {
     }
     @Override
     public String toString(){
-    	String A = (a == null) ? "null" : a.getName();
-    	String B = (b == null) ? "null" : b.getName();
+    	String A = (a == null) ? "null" : a.getName() + "[" + a.getId()+ "]";
+    	String B = (b == null) ? "null" : b.getName() + "[" + b.getId()+ "]";
     	return "CpsEdge: " + A + " to " + B;
     }
 

+ 2 - 0
src/classes/CpsUpperNode.java

@@ -204,4 +204,6 @@ public class CpsUpperNode extends AbstractCpsObject {
 	public void setLeftBorder(int leftBorder) {
 		this.leftBorder = leftBorder;
 	}
+
+
 }

+ 46 - 0
src/classes/ExitCable.java

@@ -0,0 +1,46 @@
+package classes;
+
+import ui.model.DecoratedCable;
+
+/**
+ * A VisualRepresentation to represent a connection from a UpperNode to a AbstactCpsObject, but actually the UpperNode is not connected.
+ * @author Tom
+ *
+ */
+public class ExitCable {
+	private AbstractCpsObject outsideObject;
+	private AbstractCpsObject insideObject;
+	private CpsUpperNode getInsideUpperNode;
+	private CpsUpperNode getOutsideUpperNode;
+	private DecoratedCable cable;
+	public ExitCable(DecoratedCable cable, CpsUpperNode getInsideUpperNode,CpsUpperNode getOutsideUpperNode, AbstractCpsObject insideObject, AbstractCpsObject outsideObject){
+		this.cable = cable;
+		this.getInsideUpperNode = getInsideUpperNode;
+		this.getOutsideUpperNode = getOutsideUpperNode;
+		this.insideObject = insideObject;
+		this.outsideObject = outsideObject;
+	}
+	public AbstractCpsObject getOusideObject() {
+		return outsideObject;
+	}
+	public AbstractCpsObject getInsideObject() {
+		return insideObject;
+	}
+	public CpsUpperNode getInsideUpperNode() {
+		return getInsideUpperNode;
+	}
+	public DecoratedCable getCable() {
+		return cable;
+	}
+	public CpsEdge getModel() {
+		return cable.getModel();
+	}
+	public CpsUpperNode getOutsideUpperNode() {
+		return getOutsideUpperNode;
+	}
+	public String toString() {
+		return getModel().toString();
+		
+	}
+
+}

+ 40 - 0
src/classes/ExitCableV2.java

@@ -0,0 +1,40 @@
+package classes;
+
+import ui.model.DecoratedCable;
+/**
+ * For the Visual State.
+ * @author Tom
+ *
+ */
+public class ExitCableV2 {
+	//Classification 
+	public enum ExitCableState {
+		UP, DOWN, DOWNUP, DOWNDOWN
+	}
+	private ExitCableState state;
+	//GroupNode or AbstractCpsObject
+	private AbstractCpsObject start;
+	private AbstractCpsObject finish;
+	private DecoratedCable cable;
+	
+	public ExitCableV2(ExitCableState state, AbstractCpsObject start, AbstractCpsObject finish, DecoratedCable cable) {
+		this.state = state;
+		this.start = start;
+		this.finish = finish;
+		this.cable = cable;
+	}
+
+	public ExitCableState getState() {
+		return state;
+	}
+	public AbstractCpsObject getStart() {
+		return start;
+	}
+	public AbstractCpsObject getFinish() {
+		return finish;
+	}
+	public DecoratedCable getCable() {
+		return cable;
+	}
+
+}

+ 0 - 99
src/ui/controller/CalculataModel.java

@@ -1,99 +0,0 @@
-package ui.controller;
-
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.ListIterator;
-
-import classes.AbstractCpsObject;
-import classes.HolonObject;
-import classes.HolonSwitch;
-import ui.model.CableWithState;
-import ui.model.DecoratedCable.CableState;
-import ui.model.DecoratedSwitch;
-import ui.model.DecoratedSwitch.SwitchState;
-import ui.model.MinimumModel;
-import ui.model.MinimumNetwork;
-
-public class CalculataModel {
-	public static ArrayList<DecoratedSwitch> decorateSwitches(MinimumModel minModel, int iteration) {
-		ArrayList<DecoratedSwitch> aListOfDecoratedSwitches = new ArrayList<DecoratedSwitch>(); 
-		for(HolonSwitch hSwitch: minModel.getSwitchList()) {
-			aListOfDecoratedSwitches.add(new DecoratedSwitch(hSwitch, hSwitch.getState(iteration) ? SwitchState.Closed : SwitchState.Open));
-		}
-		return aListOfDecoratedSwitches;
-	}
-	public static ArrayList<MinimumNetwork> calculateNetworks(MinimumModel minModel, int Iteration, ArrayList<CableWithState> leftOver){
-		//Copy minModel ObjectList
-		ArrayList<HolonObject> holonObjectList = new ArrayList<HolonObject>();
-		for(HolonObject holonObject: minModel.getHolonObjectList()) {
-			holonObjectList.add(holonObject);
-		}
-		//Copy minModelEdgeList
-		ArrayList<CableWithState> edgeList = new ArrayList<CableWithState>();
-		for(CableWithState cable: minModel.getEdgeList()) {
-			edgeList.add(cable);
-		}
-		
-		ArrayList<MinimumNetwork> listOfNetworks = new ArrayList<MinimumNetwork>();
-		while(!holonObjectList.isEmpty()) {
-			//lookAt the first holonObject and find his neighbors
-			HolonObject lookAtObject = holonObjectList.get(0);
-			//delete out of list
-			holonObjectList.remove(0);
-			//create a new Network
-			MinimumNetwork actualNetwork = new MinimumNetwork(new ArrayList<HolonObject>(), new ArrayList<CableWithState>());
-			actualNetwork.getHolonObjectList().add(lookAtObject);
-			//create List of neighbors
-			LinkedList<AbstractCpsObject> neighbors = new LinkedList<AbstractCpsObject>();
-			populateListOfNeighbors(edgeList, lookAtObject, actualNetwork, neighbors);
-			while(!neighbors.isEmpty()) {
-				AbstractCpsObject lookAtNeighbor = neighbors.getFirst();
-				if(lookAtNeighbor instanceof HolonObject) {
-					actualNetwork.getHolonObjectList().add((HolonObject) lookAtNeighbor);
-					holonObjectList.remove(lookAtNeighbor);
-				}
-				//When HolonSwitch Check if closed
-				if(!(lookAtNeighbor instanceof HolonSwitch) || ((HolonSwitch)lookAtNeighbor).getState(Iteration)) {
-					populateListOfNeighbors(edgeList, lookAtNeighbor, actualNetwork, neighbors);
-				}
-				
-				neighbors.removeFirst();
-			}
-			listOfNetworks.add(actualNetwork);
-		}	
-		if(leftOver!= null) {
-			leftOver.clear();
-			for(CableWithState cable: edgeList) {
-				leftOver.add(cable);
-			}
-		}
-		return listOfNetworks;
-	}
-
-	private static void populateListOfNeighbors(ArrayList<CableWithState> edgeList, AbstractCpsObject lookAtObject,
-			MinimumNetwork actualNetwork, LinkedList<AbstractCpsObject> neighbors) {
-		ListIterator<CableWithState> iter = edgeList.listIterator();
-		while(iter.hasNext())
-		{
-			CableWithState lookAtEdge = iter.next();
-			if(lookAtEdge.getState() == CableState.Working && lookAtEdge.getModel().isConnectedTo(lookAtObject)) {
-				iter.remove();
-				actualNetwork.getEdgeList().add(lookAtEdge);
-				
-				//Add neighbar
-				AbstractCpsObject edgeNeighbor;
-				if(lookAtEdge.getModel().getA().equals(lookAtObject)) {
-					edgeNeighbor = lookAtEdge.getModel().getB();
-					
-				}else {
-					edgeNeighbor = lookAtEdge.getModel().getA();
-				}
-				if(!neighbors.contains(edgeNeighbor)) {
-					neighbors.add(edgeNeighbor);
-				}
-			}
-		}
-	}
-	
-
-}

+ 22 - 30
src/ui/controller/NodeController.java

@@ -5,6 +5,7 @@ import classes.CpsEdge;
 import classes.CpsNode;
 import classes.CpsUpperNode;
 import classes.Position;
+import classes.ExitCable;
 import ui.model.Model;
 
 import java.awt.*;
@@ -29,7 +30,6 @@ class NodeController {
 	 * Add a CpsUpperNode into Canvas
 	 */
     void doUpperNode(String nodeName, CpsUpperNode upperNode, ArrayList<AbstractCpsObject> toGroup) {
-
 		CpsUpperNode node = new CpsUpperNode(nodeName);
 		node.setPosition(calculatePos(toGroup));
 		makeAdjacent(node, upperNode, toGroup);
@@ -179,16 +179,7 @@ class NodeController {
 		}
 
 		(upperNode == null ? model.getEdgesOnCanvas() : upperNode.getNodeEdges()).removeAll(toDelete);
-
-		// für alle objekte in adjazenzliste mach
-		for (AbstractCpsObject cps : adj) {
-			CpsEdge newEdge = new CpsEdge(cps, node, maxCapacity.get(adj.indexOf(cps)));
-			if (upperNode == null)
-				cvs.addEdgeOnCanvas(newEdge);
-			else
-				upperNode.getNodeEdges().add(newEdge);
-
-		}
+		
 	}
 
 	/**
@@ -241,6 +232,7 @@ class NodeController {
 			// wenn der zu suchende ein CpsUpperNode war
 			if (toSearch instanceof CpsUpperNode) {
 
+				System.out.println("UpperNode!");
 				// guck einfach in den Connections des Verlorenen nach Edges die
 				// auf der Canvas sind.
 				for (CpsEdge e : lost.getConnections()) {
@@ -320,25 +312,25 @@ class NodeController {
 			node.getOldEdges().addAll(backup);
 
 			// neue adjazent muss hergestellt werden in den alten oldEdges
-			for (CpsEdge edge : upperNode.getOldEdges()) {
-
-				if (node.getNodes().contains(edge.getA()))
-					if (!adj.contains(edge.getB())) {
-						adj.add(edge.getB());
-						maxCapacity.add(edge.getCapacity());
-					} else if (maxCapacity.get(adj.indexOf(edge.getB())) < edge.getCapacity()) {
-						maxCapacity.set(adj.indexOf(edge.getB()), edge.getCapacity());
-
-					}
-				if (node.getNodes().contains(edge.getB()))
-					if (!adj.contains(edge.getA())) {
-						adj.add(edge.getA());
-						maxCapacity.add(edge.getCapacity());
-					} else if (maxCapacity.get(adj.indexOf(edge.getA())) < edge.getCapacity()) {
-						maxCapacity.set(adj.indexOf(edge.getA()), edge.getCapacity());
-
-					}
-			}
+//			for (CpsEdge edge : upperNode.getOldEdges()) {
+//
+//				if (node.getNodes().contains(edge.getA()))
+//					if (!adj.contains(edge.getB())) {
+//						adj.add(edge.getB());
+//						maxCapacity.add(edge.getCapacity());
+//					} else if (maxCapacity.get(adj.indexOf(edge.getB())) < edge.getCapacity()) {
+//						maxCapacity.set(adj.indexOf(edge.getB()), edge.getCapacity());
+//
+//					}
+//				if (node.getNodes().contains(edge.getB()))
+//					if (!adj.contains(edge.getA())) {
+//						adj.add(edge.getA());
+//						maxCapacity.add(edge.getCapacity());
+//					} else if (maxCapacity.get(adj.indexOf(edge.getA())) < edge.getCapacity()) {
+//						maxCapacity.set(adj.indexOf(edge.getA()), edge.getCapacity());
+//
+//					}
+//			}
 			// alle übertragenen Edges werden gelöscht
 			upperNode.getOldEdges().removeAll(backup);
 			// neue edges werden erzeugt

+ 118 - 284
src/ui/controller/SimulationManager.java

@@ -7,12 +7,14 @@ import classes.comparator.WeakestBattery;
 import ui.model.CableWithState;
 import ui.model.DecoratedCable;
 import ui.model.DecoratedCable.CableState;
+import ui.model.DecoratedSwitch.SwitchState;
 import ui.model.DecoratedNetwork;
 import ui.model.DecoratedState;
 import ui.model.DecoratedSwitch;
 import ui.model.MinimumModel;
 import ui.model.MinimumNetwork;
 import ui.model.Model;
+import ui.model.VisualRepresentationalState;
 import ui.view.FlexiblePane;
 import ui.view.GUI;
 import ui.view.MyCanvas;
@@ -21,6 +23,8 @@ import ui.view.Outliner;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.ListIterator;
 
 import javax.swing.JPanel;
 
@@ -37,6 +41,7 @@ public class SimulationManager {
 	private ArrayList<SubNet> subNets;
 	private ArrayList<CpsEdge> brokenEdges;
 	private HashMap<Integer, DecoratedState> saves = new HashMap<Integer, DecoratedState>();
+	private HashMap<Integer, VisualRepresentationalState> savesVisual = new HashMap<Integer, VisualRepresentationalState>();
 	private MyCanvas canvas;
 	private int timeStep;
 	private HashMap<Integer, Float> tagTable = new HashMap<>();
@@ -70,17 +75,16 @@ public class SimulationManager {
 	}
 
 	/**
-	 * calculates the flow of the edges and the supply for objects.
+	 * calculates the flow of the edges and the supply for objects and consider old timesteps for burned cables.
 	 *
 	 * @param timestep
 	 *            current Iteration
 	 */
 	void calculateStateForTimeStep(int timestep) {
-		boolean theStateBeforeExist= (timestep > 0 && saves.containsKey(timestep-1));
 		
-		System.out.println("Calculate Timestep: " + timestep + (theStateBeforeExist ? "  StateBeforeExist": ""));
+		
 		HashMap<CpsEdge, CableState> map = new HashMap<CpsEdge, CableState>();
-		if(theStateBeforeExist)
+		if(timestep > 0 && saves.containsKey(timestep-1)) //if the state before exist
 		{
 			//make cable hastmap
 			DecoratedState theStateBefore = saves.get(timestep-1);
@@ -100,7 +104,7 @@ public class SimulationManager {
 		boolean doAnotherLoop = true;
 		while(doAnotherLoop) {
 			doAnotherLoop = false;
-			list = CalculataModel.calculateNetworks(minimumModel, timestep, leftOver);
+			list = calculateNetworks(minimumModel, timestep, leftOver);
 			for(MinimumNetwork net : list) {
 				float energyOnCables = net.getHolonObjectList().stream().filter(object -> object.getEnergyAtTimeStep(timestep) > 0.0f).map(object -> object.getEnergyAtTimeStep(timestep)).reduce(0.0f, ((a,b) -> a + b));
 				//find the cable with the energy supplied from his two connected objects are the biggest, from all cables that the network give more energy than the cablecapacity. 
@@ -120,288 +124,112 @@ public class SimulationManager {
 		for(CableWithState cable: leftOver) {
 			leftOverDecoratedCables.add(new DecoratedCable(cable.getModel(), cable.getState(), 0.0f));
 		}
-		ArrayList<DecoratedSwitch> listOfDecoratedSwitches = CalculataModel.decorateSwitches(minimumModel, timestep);
-		saves.put(timestep, new DecoratedState(decorNetworks, leftOverDecoratedCables, listOfDecoratedSwitches, minimumModel.getNodeList() , timestep));
+		ArrayList<DecoratedSwitch> listOfDecoratedSwitches = decorateSwitches(minimumModel, timestep);
+		DecoratedState stateFromThisTimestep = new DecoratedState(decorNetworks, leftOverDecoratedCables, listOfDecoratedSwitches, timestep);
+		saves.put(timestep, stateFromThisTimestep);
+		savesVisual.put(timestep, new VisualRepresentationalState(stateFromThisTimestep, minimumModel));
 		canvas.repaint();
 		gui.updateOutliners(getActualDecorState());//saves.getOrDefault(timestep, null);
 		
-//		for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
-//		    System.out.println(ste);
-////		}
-//		reset();
-//		timeStep = x;
-//		searchForSubNets();
-//		for (SubNet singleSubNet : subNets) {
-//			if(singleSubNet.getObjects().size() == 0)
-//			{
-//				resetConnections(singleSubNet.getBatteries().get(0),
-//						new ArrayList<>(), new ArrayList<>());
-//			}else
-//			{
-//				resetConnections(singleSubNet.getObjects().get(0),
-//					new ArrayList<>(), new ArrayList<>());
-//			}
-//			
-//		}
-//		for (SubNet singleSubNet : subNets) {
-//			float production = calculateEnergyWithoutFlexDevices("prod",
-//					singleSubNet, timeStep);
-//			float consumption = calculateEnergyWithoutFlexDevices("cons",
-//					singleSubNet, timeStep);
-//			// surplus of energy is computed by sum, since consumption is a
-//			// negative value
-//			float energySurplus = production + consumption;
-//			
-//			
-//			//float minConsumption = calculateMinimumEnergy(singleSubNet, timeStep);
-//
-//			// --------------- use flexible devices ---------------
-//			if (energySurplus != 0 && model.useFlexibleDevices()) {
-//				turnOnFlexibleDevices(singleSubNet, energySurplus, x);
-//
-//				// if (!flexDevicesTurnedOnThisTurn.isEmpty()) {
-//				// System.out.println("The following devices were turned on in this turn: ");
-//				// System.out.println(flexDevicesTurnedOnThisTurn.toString());
-//				// }
-//
-//				// recompute after having examined/turned on all flexible
-//				// devices
-//				production = calculateEnergyWithFlexDevices("prod",
-//						singleSubNet, timeStep);
-//				consumption = calculateEnergyWithFlexDevices("cons",
-//						singleSubNet, timeStep);
-//				energySurplus = production + consumption;
-//			}
-//
-//			// --------------- set flow simulation ---------------
-//			setFlowSimulation(singleSubNet);
-//
-//			// --------------- visualise graph ---------------
-//
-//			/**
-//			 * production of subnets, that might be partially turned on/off
-//			 */
-//			float currentProduction = production;
-//			/**
-//			 * HolonObjects that can be partially Supplied but might be fully
-//			 * Supplied
-//			 */
-//			/*
-//			ArrayList<HolonObject> partiallySuppliedList = new ArrayList<HolonObject>();
-//			/**
-//			 * HolonObjects that can get the spare energy
-//			 */
-////			
-////			ArrayList<HolonObject> notSuppliedList = new ArrayList<HolonObject>();
-//			/**
-//			 * Number of HolonObjects that need to be supplied
-//			 */
-////			long numberOfConsumers = singleSubNet.getObjects().stream()
-////			.filter(hl -> (hl.getState() != HolonObject.NO_ENERGY
-////					&& hl.getState() != HolonObject.PRODUCER && hl
-////					.getConnectedTo().stream()
-////					.filter(e -> (e.getFlow() > 0)).count() > 0))
-////			.count();
-//			/**
-//			 * energy each HolonObject receives in AlleEqualModus
-//			 */
-//			
-//			if(energySurplus >= 0)
-//			{
-//				//Supply all consumer
-//				for(HolonObject hO : singleSubNet.getObjects())
-//				{
-//					float neededEnergy = hO.getCurrentEnergyAtTimeStep(x);
-//					if(neededEnergy < 0)
-//					{
-//						hO.setCurrentSupply(-neededEnergy);
-//						currentProduction -= -neededEnergy; //Subtract the Energy from the Production
-//					}
-//				}
-//				//Supply all Batterys with the left currentProduction
-//				singleSubNet.getBatteries().sort(new WeakestBattery(x));//Sort all batteries by the Value of ther StateOfCharge/Capasity
-//				for(HolonBattery hB : singleSubNet.getBatteries())
-//				{
-//					float energyToCollect = hB.getInAtTimeStep(x-1);
-//					if(currentProduction >= energyToCollect)
-//					{
-//						//change StateofCharge soc = soc + energyToCollect
-//						hB.setStateOfChargeAtTimeStep(hB.getStateOfChargeAtTimeStep(x-1) + energyToCollect, x);
-//						currentProduction -= energyToCollect;
-//					}else
-//					{
-//						//change StateofCharge soc = soc + currentProduction
-//						hB.setStateOfChargeAtTimeStep(hB.getStateOfChargeAtTimeStep(x-1) + currentProduction, x);
-//						currentProduction = 0;
-//						//no break must be calculatet for all break; //because no more energy
-//					}
-//				}
-//				//Over_Supply all consumer equal
-//				long nOConsumer = singleSubNet.getObjects().stream().filter(hl -> (hl.getCurrentEnergyAtTimeStep(x) < 0)).count();			
-//				if(nOConsumer != 0)
-//				{
-//					//energy to seperated equal 
-//					float EnergyOverSupplyPerHolonObject = currentProduction / nOConsumer;
-//					for(HolonObject hO : singleSubNet.getObjects())
-//					{
-//						float neededEnergy = hO.getCurrentEnergyAtTimeStep(x);
-//						if(neededEnergy < 0)
-//						{
-//							hO.setCurrentSupply(hO.getCurrentSupply() + EnergyOverSupplyPerHolonObject);
-//						}
-//					}
-//					currentProduction = 0;
-//				}
-//			}
-//			else
-//			{
-//				//Check all Battries what they can provide
-//				if(energySurplus + GetOutAllBatteries(singleSubNet.getBatteries(), x) >= 0)
-//				{
-//					singleSubNet.getBatteries().sort(new WeakestBattery(x));//.reverse();
-//					Collections.reverse(singleSubNet.getBatteries()); //most supplyed first
-//					//Get the NEEDED energy
-//					for(HolonBattery hB : singleSubNet.getBatteries())
-//					{
-//						float neededEnergyFromBattery = currentProduction + consumption; //Energy is negativ
-//						float maxEnergyAvailable = hB.getOutAtTimeStep(x-1); //energy is positiv
-//						if(maxEnergyAvailable >= -neededEnergyFromBattery)
-//						{
-//							//change StateofCharge soc = soc - -neededEnergyFromBattery
-//							hB.setStateOfChargeAtTimeStep(hB.getStateOfChargeAtTimeStep(x-1) - -neededEnergyFromBattery, x);
-//							currentProduction += -neededEnergyFromBattery;
-//							//no break must be calculatet for all beabreak; //When a energy can supply the last needed energy break;
-//						}
-//						else
-//						{
-//							//change StateofCharge soc = soc - maxEnergyAvailable
-//							hB.setStateOfChargeAtTimeStep(hB.getStateOfChargeAtTimeStep(x-1) - maxEnergyAvailable, x);
-//							currentProduction += maxEnergyAvailable;
-//						}
-//					}
-//					//Supply all consumer all ar in state Supplied no one is oversupplied because 
-//					//	just the energy that is needed is gained from the batteries
-//					for(HolonObject hO : singleSubNet.getObjects())
-//					{
-//						float neededEnergy = hO.getCurrentEnergyAtTimeStep(x);
-//						if(neededEnergy < 0)
-//						{
-//							hO.setCurrentSupply(-neededEnergy);
-//							currentProduction -= -neededEnergy; //Subtract the Energy from the Production
-//						}
-//					}
-//				}
-//				else //Objects have to be partially supplied
-//				{
-//					//Get all Energy out of battries as possible
-//					for(HolonBattery hB : singleSubNet.getBatteries())
-//					{
-//						float maxEnergyAvailable = hB.getOutAtTimeStep(x-1); //energy is positiv
-//						//change StateofCharge soc = soc - maxEnergyAvailable
-//						hB.setStateOfChargeAtTimeStep(hB.getStateOfChargeAtTimeStep(x-1) - maxEnergyAvailable, x);
-//						currentProduction += maxEnergyAvailable;
-//					}
-//					//Calc
-//					singleSubNet.getObjects().stream().forEach(hl -> hl.setCurrentSupply(0));
-//					if(model.getFairnessModel() == fairnessAllEqual)
-//					{
-//						long nOConsumer = singleSubNet.getObjects().stream().filter(hl -> (hl.getCurrentEnergyAtTimeStep(x) < 0)).count();
-//						float energyPerHolonObject = 0;
-//						if (nOConsumer != 0)
-//							energyPerHolonObject = currentProduction / nOConsumer;
-//						for(HolonObject hO : singleSubNet.getObjects())
-//						{
-//							if(hO.getCurrentEnergyAtTimeStep(x) < 0) //Just Consumer need Energy 
-//							{
-//								hO.setCurrentSupply(energyPerHolonObject);
-//								currentProduction -= energyPerHolonObject; //Subtract the Energy from the Production
-//							}
-//						}
-//					}
-//					else //(model.getFairnessModel() == fairnessMininumDemandFirst)
-//					{
-//						singleSubNet.getObjects().sort(new MinEnergyComparator(x));
-//						//SupplyAllMinimumEnergy
-//						for(HolonObject hO : singleSubNet.getObjects())
-//						{
-//							if(hO.checkIfPartiallySupplied(x))continue;
-//							if(hO.getCurrentEnergyAtTimeStep(x) > 0)continue;
-//							float minEnergy = -hO.getMinEnergy(x); //Energy from getMinEnergy is negative -> convert to positive
-//							if(minEnergy <= currentProduction)
-//							{
-//								hO.setCurrentSupply(minEnergy);
-//								currentProduction -= minEnergy;
-//							}else
-//							{
-//								hO.setCurrentSupply(currentProduction);
-//								currentProduction = 0;
-//								break;
-//							}
-//						}
-//						singleSubNet.getObjects().sort(new EnergyMinToMaxComparator(x));
-//						//supplyFullytillEnd ... because its cant be fully supplied 
-//						for(HolonObject hO : singleSubNet.getObjects())
-//						{
-//							
-//							float actualSupplyEnergy = hO.getCurrentSupply();
-//							float neededEnergy = -hO.getCurrentEnergyAtTimeStep(x) - actualSupplyEnergy;
-//							if(neededEnergy <= 0)continue; //Producer or No EnergyNeeded
-//							if(neededEnergy <= currentProduction)
-//							{
-//								hO.setCurrentSupply(neededEnergy+actualSupplyEnergy);
-//								currentProduction -= neededEnergy;
-//							}else
-//							{
-//								hO.setCurrentSupply(currentProduction+actualSupplyEnergy);
-//								currentProduction = 0;
-//								break;
-//							}
-//						}
-//						
-//						
-//					}
-//				}
-//				
-//			}
-//			//Visualize the Color
-//			for(HolonObject hO : singleSubNet.getObjects())
-//			{
-//				float neededEnergy = -hO.getCurrentEnergyAtTimeStep(x); // convert negative energy in positive for calculations
-//				if(neededEnergy < 0)
-//				{
-//					hO.setState(HolonObject.PRODUCER);
-//				}
-//				else if(neededEnergy > 0)
-//				{
-//					float currentSupply = hO.getCurrentSupply() ;
-//					if(currentSupply > neededEnergy)
-//					{
-//						hO.setState(HolonObject.OVER_SUPPLIED);
-//					}else if (currentSupply ==  neededEnergy)
-//					{
-//						hO.setState(HolonObject.SUPPLIED);
-//					}else if (currentSupply <  neededEnergy)
-//					{
-//						float minEnergy = -hO.getMinEnergy(x);
-//						if(currentSupply >= minEnergy || hO.getSelfMadeEnergy(x)  >= minEnergy )
-//						{
-//							hO.setState(HolonObject.PARTIALLY_SUPPLIED);
-//						}else
-//						{
-//							hO.setState(HolonObject.NOT_SUPPLIED);
-//						}
-//					}
-//				}
-//				else if(neededEnergy == 0)
-//				{
-//					hO.setState(HolonObject.NO_ENERGY);
-//				}
-//			}
-//		}
-//		canvas.repaint();
-//		flexPane.recalculate();
 	}
-
+	/** 
+	 * Decorate a switch
+	 * @param minModel
+	 * @param iteration
+	 * @return
+	 */
+	public static ArrayList<DecoratedSwitch> decorateSwitches(MinimumModel minModel, int iteration) {
+		ArrayList<DecoratedSwitch> aListOfDecoratedSwitches = new ArrayList<DecoratedSwitch>(); 
+		for(HolonSwitch hSwitch: minModel.getSwitchList()) {
+			aListOfDecoratedSwitches.add(new DecoratedSwitch(hSwitch, hSwitch.getState(iteration) ? SwitchState.Closed : SwitchState.Open));
+		}
+		return aListOfDecoratedSwitches;
+	}
+	/**
+	 * SubFunction to calculate the Networks from the model.
+	 * @param minModel
+	 * @param Iteration
+	 * @param leftOver
+	 * @return
+	 */
+	ArrayList<MinimumNetwork> calculateNetworks(MinimumModel minModel, int Iteration, ArrayList<CableWithState> leftOver){
+		//Copy minModel ObjectList
+		ArrayList<HolonObject> holonObjectList = new ArrayList<HolonObject>();
+		for(HolonObject holonObject: minModel.getHolonObjectList()) {
+			holonObjectList.add(holonObject);
+		}
+		//Copy minModelEdgeList
+		ArrayList<CableWithState> edgeList = new ArrayList<CableWithState>();
+		for(CableWithState cable: minModel.getEdgeList()) {
+			edgeList.add(cable);
+		}
+		
+		ArrayList<MinimumNetwork> listOfNetworks = new ArrayList<MinimumNetwork>();
+		while(!holonObjectList.isEmpty()) {
+			//lookAt the first holonObject and find his neighbors
+			HolonObject lookAtObject = holonObjectList.get(0);
+			//delete out of list
+			holonObjectList.remove(0);
+			//create a new Network
+			MinimumNetwork actualNetwork = new MinimumNetwork(new ArrayList<HolonObject>(), new ArrayList<CableWithState>());
+			actualNetwork.getHolonObjectList().add(lookAtObject);
+			//create List of neighbors
+			LinkedList<AbstractCpsObject> neighbors = new LinkedList<AbstractCpsObject>();
+			populateListOfNeighbors(edgeList, lookAtObject, actualNetwork, neighbors);
+			while(!neighbors.isEmpty()) {
+				AbstractCpsObject lookAtNeighbor = neighbors.getFirst();
+				if(lookAtNeighbor instanceof HolonObject) {
+					actualNetwork.getHolonObjectList().add((HolonObject) lookAtNeighbor);
+					holonObjectList.remove(lookAtNeighbor);
+				}
+				//When HolonSwitch Check if closed
+				if(!(lookAtNeighbor instanceof HolonSwitch) || ((HolonSwitch)lookAtNeighbor).getState(Iteration)) {
+					populateListOfNeighbors(edgeList, lookAtNeighbor, actualNetwork, neighbors);
+				}
+				
+				neighbors.removeFirst();
+			}
+			listOfNetworks.add(actualNetwork);
+		}	
+		if(leftOver!= null) {
+			leftOver.clear();
+			for(CableWithState cable: edgeList) {
+				leftOver.add(cable);
+			}
+		}
+		return listOfNetworks;
+	}
+	/**
+	 * Adds the neighbors.
+	 * @param edgeList
+	 * @param lookAtObject
+	 * @param actualNetwork
+	 * @param neighbors
+	 */
+	void populateListOfNeighbors(ArrayList<CableWithState> edgeList, AbstractCpsObject lookAtObject,
+			MinimumNetwork actualNetwork, LinkedList<AbstractCpsObject> neighbors) {
+		ListIterator<CableWithState> iter = edgeList.listIterator();
+		while(iter.hasNext())
+		{
+			CableWithState lookAtEdge = iter.next();
+			if(lookAtEdge.getState() == CableState.Working && lookAtEdge.getModel().isConnectedTo(lookAtObject)) {
+				iter.remove();
+				actualNetwork.getEdgeList().add(lookAtEdge);
+				
+				//Add neighbar
+				AbstractCpsObject edgeNeighbor;
+				if(lookAtEdge.getModel().getA().equals(lookAtObject)) {
+					edgeNeighbor = lookAtEdge.getModel().getB();
+					
+				}else {
+					edgeNeighbor = lookAtEdge.getModel().getA();
+				}
+				if(!neighbors.contains(edgeNeighbor)) {
+					neighbors.add(edgeNeighbor);
+				}
+			}
+		}
+	}
 	/**
 	 * add all battries.getOut() from a list of battries and return them
 	 * @param aL a List of HolonBattries likely from subnet.getBatteries()
@@ -1046,7 +874,9 @@ public class SimulationManager {
 	public DecoratedState getActualDecorState() {
 		return getDecorState(timeStep);
 	}
-	
+	public VisualRepresentationalState getActualVisualRepresentationalState(){
+		return savesVisual.getOrDefault(timeStep, null);
+	}
 	public DecoratedState getDecorState(int timestep) {
 		return saves.getOrDefault(timestep, null);
 	}
@@ -1055,4 +885,8 @@ public class SimulationManager {
 		this.gui = gui;
 	}
 
+	public HashMap<Integer, VisualRepresentationalState> getSavesVisual() {
+		return savesVisual;
+	}
+
 }

+ 86 - 0
src/ui/model/DecoratedGroupNode.java

@@ -0,0 +1,86 @@
+package ui.model;
+
+import java.util.ArrayList;
+
+import classes.CpsNode;
+import classes.CpsUpperNode;
+import classes.ExitCable;
+import classes.ExitCableV2;
+/**
+ * For the @VisualRepresentationalState only.
+ * @author Tom
+ *
+ */
+public class DecoratedGroupNode {
+	private CpsUpperNode model;
+	private ArrayList<Supplier> supplierList;
+	private ArrayList<Passiv> passivList;
+	private ArrayList<Consumer> consumerList;
+	private ArrayList<CpsNode> nodeList;
+	/**
+	 * Cables that only exist on that group node. From a object in that group node to a object in that group Node.
+	 * Not exit the group node (a layer down).
+	 */
+	private ArrayList<DecoratedCable> internCableList;
+	/**
+	 * Cables that exit this group node (a Layer Up). From a object in this group node to a object in a upper layer.
+	 */
+	private ArrayList<ExitCableV2> exitCableList;	
+	private ArrayList<DecoratedSwitch> switchList;
+	private ArrayList<DecoratedGroupNode> groupNodeList;
+
+
+	public DecoratedGroupNode(CpsUpperNode model, ArrayList<Supplier> supplierList, ArrayList<Passiv> passivList,
+			ArrayList<Consumer> consumerList, ArrayList<CpsNode> nodeList, ArrayList<DecoratedCable> internCableList,
+			ArrayList<ExitCableV2> exitCableList, ArrayList<DecoratedSwitch> switchList,
+			ArrayList<DecoratedGroupNode> groupNodeList) {
+		this.model = model;
+		this.supplierList = supplierList;
+		this.passivList = passivList;
+		this.consumerList = consumerList;
+		this.nodeList = nodeList;
+		this.internCableList = internCableList;
+		this.exitCableList = exitCableList;
+		this.switchList = switchList;
+		this.groupNodeList = groupNodeList;
+	}
+	public DecoratedGroupNode(CpsUpperNode model) {
+		this.model = model;
+		this.supplierList = new ArrayList<Supplier>();
+		this.passivList = new ArrayList<Passiv>();
+		this.consumerList = new ArrayList<Consumer>();
+		this.nodeList = new ArrayList<CpsNode>();
+		this.internCableList = new ArrayList<DecoratedCable>();
+		this.exitCableList = new ArrayList<ExitCableV2>();
+		this.switchList = new ArrayList<DecoratedSwitch>();
+		this.groupNodeList = new ArrayList<DecoratedGroupNode>();
+	}
+	public CpsUpperNode getModel() {
+		return model;
+	}
+	public ArrayList<Supplier> getSupplierList() {
+		return supplierList;
+	}
+	public ArrayList<Passiv> getPassivList() {
+		return passivList;
+	}
+	public ArrayList<Consumer> getConsumerList() {
+		return consumerList;
+	}
+	public ArrayList<CpsNode> getNodeList() {
+		return nodeList;
+	}
+	public ArrayList<DecoratedCable> getInternCableList() {
+		return internCableList;
+	}
+	public ArrayList<ExitCableV2> getExitCableList() {
+		return exitCableList;
+	}
+	public ArrayList<DecoratedSwitch> getSwitchList() {
+		return switchList;
+	}
+	public ArrayList<DecoratedGroupNode> getGroupNodeList() {
+		return groupNodeList;
+	}
+	
+}

+ 100 - 93
src/ui/model/DecoratedNetwork.java

@@ -2,7 +2,6 @@ package ui.model;
 
 import java.util.ArrayList;
 
-import classes.CpsEdge;
 import classes.HolonObject;
 import ui.model.DecoratedCable.CableState;
 import ui.model.DecoratedHolonObject.HolonObjectState;
@@ -13,14 +12,43 @@ public class DecoratedNetwork {
 	private ArrayList<Consumer> consumerSelfSuppliedList = new ArrayList<Consumer>();
 	private ArrayList<Passiv> passivNoEnergyList = new ArrayList<Passiv>();
 	private ArrayList<DecoratedCable> decoratedCableList = new ArrayList<DecoratedCable>();
+
 	public DecoratedNetwork(MinimumNetwork minimumNetwork, int Iteration){	
+		calculateMinimumDemandFirstNetwork(minimumNetwork, Iteration);
+	}
+
+	//Getter:
+	public ArrayList<Supplier> getSupplierList() {
+		return supplierList;
+	}
+
+
+	public ArrayList<Consumer> getConsumerList() {
+		return consumerList;
+	}
+
+
+	public ArrayList<Consumer> getConsumerSelfSuppliedList() {
+		return consumerSelfSuppliedList;
+	}
+
+
+	public ArrayList<Passiv> getPassivNoEnergyList() {
+		return passivNoEnergyList;
+	}
+	public ArrayList<DecoratedCable> getDecoratedCableList(){
+		return decoratedCableList;
+	}
+	
+	
+	//Calculations:
+	private void calculateMinimumDemandFirstNetwork(MinimumNetwork minimumNetwork, int Iteration) {
 		//Categorize
 		for(HolonObject hObject: minimumNetwork.getHolonObjectList()) {
 			float energyNeeded = hObject.getEnergyNeededFromConsumingElements(Iteration);
 			float energySelfProducing = hObject.getEnergySelfProducingFromProducingElements(Iteration);
 			if(energyNeeded < energySelfProducing) {
-				Supplier sup = new Supplier(hObject);
-				sup.setEnergyToSupplyNetwork(energySelfProducing - energyNeeded);
+				Supplier sup = new Supplier(hObject, energySelfProducing - energyNeeded);
 				supplierList.add(sup);
 			} else if (energyNeeded > energySelfProducing) {
 				Consumer con = new Consumer(hObject);
@@ -61,102 +89,102 @@ public class DecoratedNetwork {
 		}
 		
 		outerLoop:
-		for(Consumer con : consumerList)
-		{
-			//gehe Supplier list durch wer ihn supplien kann.
-			for(Supplier sup : supplierList) {
-				float  energyRdyToSupply = sup.getEnergyToSupplyNetwork() - sup.getEnergySupplied();
-				if(energyRdyToSupply == 0.0f) continue;
-				float energyNeededForMinimumConsumingElement=con.getMinimumConsumingElementEnergy()-con.getEnergyFromNetwork();
-				if(energyNeededForMinimumConsumingElement>energyToSupplyInTheNetwork) {
-					//Dont supply a minimumElement when you cant supply it fully
-					break outerLoop;
-				}
-				if(energyRdyToSupply>=energyNeededForMinimumConsumingElement) {
-					energyToSupplyInTheNetwork -= energyNeededForMinimumConsumingElement;
-					supply(con, sup, energyNeededForMinimumConsumingElement);
-					continue outerLoop;
-				}else
-				{
-					energyToSupplyInTheNetwork -= energyRdyToSupply;
-					supply(con, sup, energyRdyToSupply);
-				}
-			}
-			//No more Energy in the network
-			break;
-		}
-		//consumerList.forEach((con) -> System.out.println("AfterSuppliing MinimumDemand " + con));
-		
-		//Sort ConsumerList according to the EnergyNeeded to supply fully after minimum Demand First.
-		consumerList.sort((Consumer lhs,Consumer rhs) -> Float.compare(lhs.getEnergyNeededFromNetwork()-lhs.getEnergyFromNetwork() , rhs.getEnergyNeededFromNetwork()-rhs.getEnergyFromNetwork() ));
-		//Supply consumer fully 
-		outerLoop:
-		for(Consumer con : consumerList)
-		{
-			//gehe Supplier list durch wer ihn supplien kann.
-			for(Supplier sup : supplierList) {
-				float  energyRdyToSupply = sup.getEnergyToSupplyNetwork() - sup.getEnergySupplied();
-				if(energyRdyToSupply == 0.0f) continue;
-				float energyNeededForFullySupply = con.getEnergyNeededFromNetwork() - con.getEnergyFromNetwork();
-				if(energyNeededForFullySupply == 0.0f) continue outerLoop;
-				if(energyRdyToSupply>=energyNeededForFullySupply) {
-					supply(con, sup, energyNeededForFullySupply);
-					continue outerLoop;
-				}else
-				{
-					supply(con, sup, energyRdyToSupply);
-				}
-			}
-			//No more Energy in the network
-			break;
-		}
-		//consumerList.forEach((con) -> System.out.println("AfterFullySuplieing" + con));
-		//If Energy Left Supply all equal
-		//Count EnergyLeft
-		float energyLeft = supplierList.stream().map(supplier -> supplier.getEnergyToSupplyNetwork() - supplier.getEnergySupplied()).reduce( 0.0f, (a, b) -> a + b);
-		//System.out.println("EnergyLeft: " +  energyLeft);
-		if(energyLeft > 0.0f && (consumerList.size() + consumerSelfSuppliedList.size() != 0))
-		{
-			float equalAmountOfEnergyToSupply = energyLeft / ((float)(consumerList.size() + consumerSelfSuppliedList.size()));
-			outerLoop:
 			for(Consumer con : consumerList)
 			{
 				//gehe Supplier list durch wer ihn supplien kann.
 				for(Supplier sup : supplierList) {
 					float  energyRdyToSupply = sup.getEnergyToSupplyNetwork() - sup.getEnergySupplied();
 					if(energyRdyToSupply == 0.0f) continue;
-					float energyNeededToSupplyConsumerTheEqualAmount = equalAmountOfEnergyToSupply +con.getEnergyNeededFromNetwork()- con.getEnergyFromNetwork();
-					if(energyRdyToSupply>=energyNeededToSupplyConsumerTheEqualAmount) {
-						supply(con, sup, energyNeededToSupplyConsumerTheEqualAmount);
+					float energyNeededForMinimumConsumingElement=con.getMinimumConsumingElementEnergy()-con.getEnergyFromNetwork();
+					if(energyNeededForMinimumConsumingElement>energyToSupplyInTheNetwork) {
+						//Dont supply a minimumElement when you cant supply it fully
+						break outerLoop;
+					}
+					if(energyRdyToSupply>=energyNeededForMinimumConsumingElement) {
+						energyToSupplyInTheNetwork -= energyNeededForMinimumConsumingElement;
+						supply(con, sup, energyNeededForMinimumConsumingElement);
 						continue outerLoop;
 					}else
 					{
+						energyToSupplyInTheNetwork -= energyRdyToSupply;
 						supply(con, sup, energyRdyToSupply);
 					}
 				}
 				//No more Energy in the network
 				break;
 			}
-			outerLoop:
-			for(Consumer con : consumerSelfSuppliedList)
+		//consumerList.forEach((con) -> System.out.println("AfterSuppliing MinimumDemand " + con));
+		
+		//Sort ConsumerList according to the EnergyNeeded to supply fully after minimum Demand First.
+		consumerList.sort((Consumer lhs,Consumer rhs) -> Float.compare(lhs.getEnergyNeededFromNetwork()-lhs.getEnergyFromNetwork() , rhs.getEnergyNeededFromNetwork()-rhs.getEnergyFromNetwork() ));
+		//Supply consumer fully 
+		outerLoop:
+			for(Consumer con : consumerList)
 			{
 				//gehe Supplier list durch wer ihn supplien kann.
 				for(Supplier sup : supplierList) {
 					float  energyRdyToSupply = sup.getEnergyToSupplyNetwork() - sup.getEnergySupplied();
 					if(energyRdyToSupply == 0.0f) continue;
-					float energyNeededToSupplyConsumerTheEqualAmount = equalAmountOfEnergyToSupply +con.getEnergyNeededFromNetwork()- con.getEnergyFromNetwork();
-					if(energyRdyToSupply>=energyNeededToSupplyConsumerTheEqualAmount) {
-						supply(con, sup, energyNeededToSupplyConsumerTheEqualAmount);
+					float energyNeededForFullySupply = con.getEnergyNeededFromNetwork() - con.getEnergyFromNetwork();
+					if(energyNeededForFullySupply == 0.0f) continue outerLoop;
+					if(energyRdyToSupply>=energyNeededForFullySupply) {
+						supply(con, sup, energyNeededForFullySupply);
 						continue outerLoop;
 					}else
 					{
 						supply(con, sup, energyRdyToSupply);
 					}
-					
 				}
 				//No more Energy in the network
 				break;
 			}
+		//consumerList.forEach((con) -> System.out.println("AfterFullySuplieing" + con));
+		//If Energy Left Supply all equal
+		//Count EnergyLeft
+		float energyLeft = supplierList.stream().map(supplier -> supplier.getEnergyToSupplyNetwork() - supplier.getEnergySupplied()).reduce( 0.0f, (a, b) -> a + b);
+		//System.out.println("EnergyLeft: " +  energyLeft);
+		if(energyLeft > 0.0f && (consumerList.size() + consumerSelfSuppliedList.size() != 0))
+		{
+			float equalAmountOfEnergyToSupply = energyLeft / ((float)(consumerList.size() + consumerSelfSuppliedList.size()));
+			outerLoop:
+				for(Consumer con : consumerList)
+				{
+					//gehe Supplier list durch wer ihn supplien kann.
+					for(Supplier sup : supplierList) {
+						float  energyRdyToSupply = sup.getEnergyToSupplyNetwork() - sup.getEnergySupplied();
+						if(energyRdyToSupply == 0.0f) continue;
+						float energyNeededToSupplyConsumerTheEqualAmount = equalAmountOfEnergyToSupply +con.getEnergyNeededFromNetwork()- con.getEnergyFromNetwork();
+						if(energyRdyToSupply>=energyNeededToSupplyConsumerTheEqualAmount) {
+							supply(con, sup, energyNeededToSupplyConsumerTheEqualAmount);
+							continue outerLoop;
+						}else
+						{
+							supply(con, sup, energyRdyToSupply);
+						}
+					}
+					//No more Energy in the network
+					break;
+				}
+			outerLoop:
+				for(Consumer con : consumerSelfSuppliedList)
+				{
+					//gehe Supplier list durch wer ihn supplien kann.
+					for(Supplier sup : supplierList) {
+						float  energyRdyToSupply = sup.getEnergyToSupplyNetwork() - sup.getEnergySupplied();
+						if(energyRdyToSupply == 0.0f) continue;
+						float energyNeededToSupplyConsumerTheEqualAmount = equalAmountOfEnergyToSupply +con.getEnergyNeededFromNetwork()- con.getEnergyFromNetwork();
+						if(energyRdyToSupply>=energyNeededToSupplyConsumerTheEqualAmount) {
+							supply(con, sup, energyNeededToSupplyConsumerTheEqualAmount);
+							continue outerLoop;
+						}else
+						{
+							supply(con, sup, energyRdyToSupply);
+						}
+						
+					}
+					//No more Energy in the network
+					break;
+				}
 		}
 		//consumerList.forEach((con) -> System.out.println("AfterOverSuppleiing" + con));
 		
@@ -174,8 +202,8 @@ public class DecoratedNetwork {
 			setConsumerState(con);
 		}
 	}
-
-
+	
+	
 	private void setConsumerState(Consumer con) {
 		if(con.getEnergySelfSupplied() + con.getEnergyFromNetwork() > con.getEnergyFromConsumingElemnets()) {
 			con.setState(HolonObjectState.OVER_SUPPLIED);
@@ -201,25 +229,4 @@ public class DecoratedNetwork {
 		con.getSupplierList().add(con.new SupplierListEntry(sup, energy));
 		con.setEnergyFromNetwork(con.getEnergyFromNetwork() + energy);
 	}
-	public ArrayList<Supplier> getSupplierList() {
-		return supplierList;
-	}
-
-
-	public ArrayList<Consumer> getConsumerList() {
-		return consumerList;
-	}
-
-
-	public ArrayList<Consumer> getConsumerSelfSuppliedList() {
-		return consumerSelfSuppliedList;
-	}
-
-
-	public ArrayList<Passiv> getPassivNoEnergyList() {
-		return passivNoEnergyList;
-	}
-	public ArrayList<DecoratedCable> getDecoratedCableList(){
-		return decoratedCableList;
-	}
 }

+ 4 - 11
src/ui/model/DecoratedState.java

@@ -2,19 +2,16 @@ package ui.model;
 
 import java.util.ArrayList;
 
-import classes.CpsNode;
 
 public class DecoratedState {
 	int timestepOfState;
-	ArrayList<DecoratedNetwork> networkList = new ArrayList<DecoratedNetwork>();
-	ArrayList<DecoratedCable> leftOverEdges = new ArrayList<DecoratedCable>();
-	ArrayList<DecoratedSwitch> decoratedSwitches = new ArrayList<DecoratedSwitch>();
-	ArrayList<CpsNode> nodes = new ArrayList<CpsNode>();
-	public DecoratedState(ArrayList<DecoratedNetwork> networkList, ArrayList<DecoratedCable> leftOverEdges, ArrayList<DecoratedSwitch> decoratedSwitches,ArrayList<CpsNode> nodes, int timestepOfState){
+	ArrayList<DecoratedNetwork> networkList;
+	ArrayList<DecoratedCable> leftOverEdges;
+	ArrayList<DecoratedSwitch> decoratedSwitches;
+	public DecoratedState(ArrayList<DecoratedNetwork> networkList, ArrayList<DecoratedCable> leftOverEdges, ArrayList<DecoratedSwitch> decoratedSwitches , int timestepOfState){
 		this.networkList = networkList;
 		this.leftOverEdges = leftOverEdges;
 		this.decoratedSwitches = decoratedSwitches;
-		this.nodes = nodes;
 		this.timestepOfState = timestepOfState;
 	}
 	public ArrayList<DecoratedNetwork> getNetworkList() {
@@ -29,8 +26,4 @@ public class DecoratedState {
 	public int getTimestepOfState() {
 		return timestepOfState;
 	}
-	public ArrayList<CpsNode> getNodeList() {
-		return nodes;
-	}
-
 }

+ 52 - 2
src/ui/model/MinimumModel.java

@@ -1,31 +1,69 @@
 package ui.model;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 
 import classes.AbstractCpsObject;
 import classes.CpsEdge;
 import classes.CpsNode;
+import classes.CpsUpperNode;
 import classes.HolonObject;
 import classes.HolonSwitch;
 import ui.model.DecoratedCable.CableState;
 
-
+/**
+ * For DecoratedState And VisualRepresentationalState
+ * @author Tom
+ *
+ */
 public class MinimumModel {
+	
 	private ArrayList<HolonObject> holonObjectList = new ArrayList<HolonObject>();
 	private ArrayList<CableWithState> cableList = new ArrayList<CableWithState>();
 	private ArrayList<CpsNode> nodeList = new ArrayList<CpsNode>();
 	private ArrayList<HolonSwitch> switchList = new ArrayList<HolonSwitch>();
 	
-	public MinimumModel(ArrayList<AbstractCpsObject> abstractObjectList, ArrayList<CpsEdge> edgeList) {// Contructor because of old Model TODO:Replace the whole Program
+	//-->Only for Visual:
+	private ArrayList<CpsUpperNode> uppderNodeList = new ArrayList<CpsUpperNode>();
+	private HashMap<AbstractCpsObject, CpsUpperNode> inGroupObjects = new HashMap<>();
+	private HashMap<CpsEdge, CpsUpperNode> inGroupEdges = new HashMap<>();
+	//<--
+	
+	public MinimumModel(ArrayList<AbstractCpsObject> abstractObjectList, ArrayList<CpsEdge> edgeList) {// Constructor because of old Model
 		for (AbstractCpsObject aCps : abstractObjectList) {
 			if (aCps instanceof HolonObject) holonObjectList.add((HolonObject) aCps);
 			else if (aCps instanceof CpsNode) nodeList.add((CpsNode) aCps);
 			else if (aCps instanceof HolonSwitch) switchList.add((HolonSwitch) aCps);
+			else if(aCps instanceof CpsUpperNode) {
+				addUpperObjects((CpsUpperNode)aCps);
+				uppderNodeList.add((CpsUpperNode)aCps);
+			}
 		}
 		for (CpsEdge edge : edgeList) {
 			this.cableList.add(new CableWithState(edge, CableState.Working));
 		}
 	}
+
+	private void addUpperObjects(CpsUpperNode aUpperNode) {
+		for(AbstractCpsObject aCps : aUpperNode.getNodes()) {
+			if (aCps instanceof HolonObject) holonObjectList.add((HolonObject) aCps);
+			else if (aCps instanceof CpsNode) nodeList.add((CpsNode) aCps);
+			else if (aCps instanceof HolonSwitch) switchList.add((HolonSwitch) aCps);
+			else if(aCps instanceof CpsUpperNode) {
+				addUpperObjects((CpsUpperNode)aCps);
+				uppderNodeList.add((CpsUpperNode)aCps);
+			}
+			inGroupObjects.put(aCps, aUpperNode);
+		}
+		for (CpsEdge edge : aUpperNode.getNodeEdges()) {
+			this.cableList.add(new CableWithState(edge, CableState.Working));
+			inGroupEdges.put(edge, aUpperNode);
+		}
+		for (CpsEdge edge : aUpperNode.getOldEdges()) {
+			this.cableList.add(new CableWithState(edge, CableState.Working));
+			inGroupEdges.put(edge, aUpperNode);
+		}
+	}
 	
 	public ArrayList<HolonObject> getHolonObjectList() {
 		return holonObjectList;
@@ -51,5 +89,17 @@ public class MinimumModel {
 	public void setSwitchList(ArrayList<HolonSwitch> switchList) {
 		this.switchList = switchList;
 	}
+
+	public ArrayList<CpsUpperNode> getUppderNodeList() {
+		return uppderNodeList;
+	}
+
+	public HashMap<AbstractCpsObject, CpsUpperNode> getInGroupObjects() {
+		return inGroupObjects;
+	}
+
+	public HashMap<CpsEdge, CpsUpperNode> getInGroupEdges() {
+		return inGroupEdges;
+	}
 	
 }

+ 0 - 2
src/ui/model/MinimumNetwork.java

@@ -1,8 +1,6 @@
 package ui.model;
 
 import java.util.ArrayList;
-
-import classes.CpsEdge;
 import classes.HolonObject;
 
 public class MinimumNetwork {

+ 1 - 2
src/ui/model/Model.java

@@ -51,7 +51,6 @@ public class Model {
     private CpsEdge selectedEdge;
     private ArrayList<AbstractCpsObject> selectedObjects = new ArrayList<>();
     private ArrayList<AbstractCpsObject> clipboardObjects = new ArrayList<>();
-    private Console console;
     private HashMap<Integer, ArrayList<HolonElement>> eleToDelete;
     // Capacity for Edge
     private float maxCapacity;
@@ -60,7 +59,7 @@ public class Model {
     /** Table for the properties of HolonObjects, Edges etc */
     private JTable propertyTable;
     
-    private ArrayList<GraphListener> graphListeners = new ArrayList();
+    private ArrayList<GraphListener> graphListeners = new ArrayList<GraphListener>();
     // Iteration Speed
     private int timerSpeed = 1000;
     private int selectedID = 0;

+ 2 - 4
src/ui/model/Supplier.java

@@ -9,8 +9,9 @@ public class Supplier extends DecoratedHolonObject {
 	private ArrayList<ConsumerListEntry> consumerList = new ArrayList<ConsumerListEntry>();
 	private float energyToSupplyNetwork;
 	private float energySupplied;
-	public Supplier(HolonObject objectToLookAt) {
+	public Supplier(HolonObject objectToLookAt, float energyToSupplyNetwork) {
 		super(objectToLookAt);
+		this.energyToSupplyNetwork = energyToSupplyNetwork;
 		energySupplied = 0.0f;
 	}
 
@@ -31,9 +32,6 @@ public class Supplier extends DecoratedHolonObject {
 		return energyToSupplyNetwork;
 	}
 
-	public void setEnergyToSupplyNetwork(float energyToSupplyNetwork) {
-		this.energyToSupplyNetwork = energyToSupplyNetwork;
-	}
 	public float getEnergySupplied() {
 		return energySupplied;
 	}

+ 359 - 0
src/ui/model/VisualRepresentationalState.java

@@ -0,0 +1,359 @@
+package ui.model;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.stream.Collectors;
+
+import classes.AbstractCpsObject;
+import classes.CpsEdge;
+import classes.CpsNode;
+import classes.CpsUpperNode;
+import classes.ExitCable;
+import classes.ExitCableV2;
+import classes.ExitCableV2.ExitCableState;
+
+public class VisualRepresentationalState {
+	private ArrayList<Supplier> supplierList = new ArrayList<Supplier>();
+	private ArrayList<Passiv> passivList= new ArrayList<Passiv>();
+	private ArrayList<Consumer> consumerList= new ArrayList<Consumer>();
+	private ArrayList<CpsNode> nodeList= new ArrayList<CpsNode>();
+	private ArrayList<DecoratedCable> cableList= new ArrayList<DecoratedCable>();
+	private ArrayList<DecoratedSwitch> switchList= new ArrayList<DecoratedSwitch>();
+	private ArrayList<DecoratedGroupNode> groupNodeList= new ArrayList<DecoratedGroupNode>();
+	private ArrayList<ExitCableV2> exitCableList= new ArrayList<ExitCableV2>();
+	
+	//ForFastAccessIndividualGroupNodes:
+	private HashMap<CpsUpperNode, DecoratedGroupNode> createdGroupNodes;
+	
+	public VisualRepresentationalState(DecoratedState stateFromThisTimestep, MinimumModel minimumModel) {
+		reassignObjects(stateFromThisTimestep, minimumModel);
+	}
+
+
+	//Getter:
+	public ArrayList<Supplier> getSupplierList() {
+		return supplierList;
+	}
+	public ArrayList<Passiv> getPassivList() {
+		return passivList;
+	}
+	public ArrayList<Consumer> getConsumerList() {
+		return consumerList;
+	}
+	public ArrayList<CpsNode> getNodeList() {
+		return nodeList;
+	}
+	public ArrayList<DecoratedCable> getCableList() {
+		return cableList;
+	}
+	public ArrayList<DecoratedSwitch> getSwitchList() {
+		return switchList;
+	}
+	public ArrayList<DecoratedGroupNode> getGroupNodeList() {
+		return groupNodeList;
+	}
+	
+	//Reassignments:
+	private void reassignObjects(DecoratedState stateFromThisTimestep, MinimumModel minimumModel) {
+		HashMap<AbstractCpsObject, CpsUpperNode> inGroupObjects = minimumModel.getInGroupObjects();
+		HashMap<CpsEdge, CpsUpperNode> inGroupEdges = minimumModel.getInGroupEdges();
+		createdGroupNodes =  new HashMap<CpsUpperNode, DecoratedGroupNode>();
+		
+		ArrayList<ExitCable> exitCables = new ArrayList<ExitCable>();
+		//createThem
+		for(CpsUpperNode groupNode :  minimumModel.getUppderNodeList()) {
+			createdGroupNodes.put(groupNode, new DecoratedGroupNode(groupNode));
+		}
+		//unrolling Networks
+		for(DecoratedNetwork net : stateFromThisTimestep.getNetworkList()) {
+			for(Consumer con : net.getConsumerList()) {
+				DecoratedGroupNode groupNodeFromObject = addObject(inGroupObjects, con.getModel(), consumerList, con, createdGroupNodes);
+				if(groupNodeFromObject != null) {
+					addToGroupNode(con, groupNodeFromObject.getConsumerList());
+				}
+			}
+			for(Consumer con : net.getConsumerSelfSuppliedList()) {
+				DecoratedGroupNode groupNodeFromObject = addObject(inGroupObjects, con.getModel(), consumerList, con, createdGroupNodes);
+				if(groupNodeFromObject != null) {
+					addToGroupNode(con, groupNodeFromObject.getConsumerList());
+				}
+			}
+			for(Supplier sup : net.getSupplierList()) {
+				DecoratedGroupNode groupNodeFromObject = addObject(inGroupObjects, sup.getModel(), supplierList, sup, createdGroupNodes);
+				if(groupNodeFromObject != null) {
+					addToGroupNode(sup, groupNodeFromObject.getSupplierList());
+				}
+			}
+			for(Passiv pas : net.getPassivNoEnergyList()) {
+				DecoratedGroupNode groupNodeFromObject = addObject(inGroupObjects, pas.getModel(), passivList, pas, createdGroupNodes);
+				if(groupNodeFromObject != null) {
+					addToGroupNode(pas, groupNodeFromObject.getPassivList());
+				}
+			}
+			for(DecoratedCable cable : net.getDecoratedCableList()) {
+				DecoratedGroupNode groupNodeFromObject = addObject(inGroupEdges, cable.getModel(), cableList ,cable, createdGroupNodes);
+				addCable(inGroupObjects, cable, groupNodeFromObject, exitCables);
+			}
+		}
+		for(DecoratedCable cable : stateFromThisTimestep.getLeftOverEdges()) {
+			DecoratedGroupNode groupNodeFromObject = addObject(inGroupEdges, cable.getModel(), cableList ,cable, createdGroupNodes);
+			addCable(inGroupObjects, cable, groupNodeFromObject, exitCables);
+		}
+		for(CpsNode node : minimumModel.getNodeList()) {
+			DecoratedGroupNode groupNodeFromObject = addObject(inGroupObjects, node, nodeList ,node, createdGroupNodes);
+			if(groupNodeFromObject != null) {
+				addToGroupNode(node, groupNodeFromObject.getNodeList());
+			}
+		}
+		for(DecoratedSwitch dSwitch: stateFromThisTimestep.getDecoratedSwitches()) {
+			DecoratedGroupNode groupNodeFromObject = addObject(inGroupObjects, dSwitch.getModel(), switchList, dSwitch, createdGroupNodes);
+			if(groupNodeFromObject != null) {
+				addToGroupNode(dSwitch, groupNodeFromObject.getSwitchList());
+			}
+		}
+		for(DecoratedGroupNode dGroupNode: createdGroupNodes.values()) {
+			DecoratedGroupNode groupNodeFromObject = addObject(inGroupObjects, dGroupNode.getModel(), groupNodeList, dGroupNode, createdGroupNodes);
+			if(groupNodeFromObject != null) {
+				addToGroupNode(dGroupNode, groupNodeFromObject.getGroupNodeList());
+			}
+		}
+		//Create TreeNodeModel:
+		HashMap<CpsUpperNode, TreeNode<TreeGroupNodeData>> fastaccess= new HashMap<CpsUpperNode, TreeNode<TreeGroupNodeData>>();
+		TreeNode<TreeGroupNodeData> root = new TreeNode<TreeGroupNodeData>(null, new ArrayList<TreeNode<TreeGroupNodeData>>(), new TreeGroupNodeData(null, 0));
+		fastaccess.put(null, root);
+		for(DecoratedGroupNode dGroupNode: getGroupNodeList()) {
+			addTreeNode(root, dGroupNode, 1, fastaccess);
+		}
+		for(ExitCable cable : exitCables) {
+			createExitEdgesV2(root,cable.getCable() , cable.getInsideObject(),cable.getInsideUpperNode(),cable.getOusideObject(),cable.getOutsideUpperNode(), fastaccess);			
+		}
+	}
+
+
+	private void createExitEdgesV2(TreeNode<TreeGroupNodeData> root, DecoratedCable cable,  AbstractCpsObject insideObject,
+			CpsUpperNode insideUpperNode, AbstractCpsObject ousideObject, CpsUpperNode outsideUpperNode, HashMap<CpsUpperNode, TreeNode<TreeGroupNodeData>> fastaccess) {
+		//Create Up List
+		LinkedList<TreeNode<TreeGroupNodeData>> listFromStart = createList(insideUpperNode, fastaccess);
+		LinkedList<TreeNode<TreeGroupNodeData>> listFromEnd = createList(outsideUpperNode, fastaccess);
+		LinkedList<TreeNode<TreeGroupNodeData>> common = new LinkedList<TreeNode<TreeGroupNodeData>>(listFromStart);
+		common.retainAll(listFromEnd);
+		TreeNode<TreeGroupNodeData> firstCommon = common.getFirst();
+		LinkedList<TreeNode<TreeGroupNodeData>> resultList = new LinkedList<TreeNode<TreeGroupNodeData>>();
+		//Add from listFromStart till firstCommon
+		createresultList(listFromStart, firstCommon, resultList);		
+		//Add firstCommon
+		resultList.add(firstCommon);
+		//Add from listFromEnd till firstCommon
+		createresultList(listFromEnd, firstCommon, resultList);
+		LinkedList<NodeInfo> infoList = new LinkedList<NodeInfo>();
+		//Categorize:
+		ListIterator<TreeNode<TreeGroupNodeData>> iter = resultList.listIterator();
+		
+		while(iter.hasNext()) {
+			//categorize
+			TreeNode<TreeGroupNodeData> actual, next = null, previous = null;
+			if(iter.hasPrevious()) {
+				previous =iter.previous();
+				iter.next();
+			}
+			actual = iter.next();
+			if(iter.hasNext()) {
+				next =iter.next();
+				iter.previous();
+			}
+			NodeInfo actualInfo = new NodeInfo(actual.getData().groupNode);
+			if(previous!= null) {
+				actualInfo.previousGroupNode = previous.getData().groupNode;
+				if(previous == actual.getParent()) {
+					actualInfo.previous = Info.Parent;
+				}else {
+					actualInfo.previous = Info.Child;
+				}
+			}
+			if(next!= null) {
+				actualInfo.nextGroupNode = next.getData().groupNode;
+				if(next == actual.getParent()) {
+					actualInfo.next = Info.Parent;
+				}else {
+					actualInfo.next = Info.Child;
+				}
+			}
+			infoList.add(actualInfo);
+		}
+		for(NodeInfo info: infoList) {
+			DecoratedGroupNode group = this.createdGroupNodes.get(info.groupNode);
+			ArrayList<ExitCableV2> mylist;
+			if(group == null) {
+				mylist = this.getExitCableList();
+			}else{
+				mylist = group.getExitCableList();
+			}
+			ExitCableState state =null;
+			if(info.previous == Info.Nothing) {
+				if(info.next == Info.Child) {
+					state = ExitCableState.DOWN;
+					mylist.add(new ExitCableV2(state, insideObject, info.nextGroupNode, cable));
+				}else if(info.next == Info.Parent) {
+					state = ExitCableState.UP;
+					mylist.add(new ExitCableV2(state, insideObject, ousideObject, cable));
+				}else {
+					System.out.println("Error in VisualState");
+				}
+			}else if(info.previous == Info.Child) {
+				if(info.next == Info.Child) {
+					state = ExitCableState.DOWNDOWN;
+					mylist.add(new ExitCableV2(state, info.previousGroupNode, info.nextGroupNode, cable));
+				}else if(info.next == Info.Parent) {
+					state = ExitCableState.DOWNUP;
+					mylist.add(new ExitCableV2(state, info.previousGroupNode, ousideObject, cable));
+				}else {
+					state = ExitCableState.DOWN;
+					mylist.add(new ExitCableV2(state, info.previousGroupNode, ousideObject, cable));
+				}
+			}else {//(info.previous == Info.Parent)
+				if(info.next == Info.Child) {
+					state = ExitCableState.DOWNUP;
+					mylist.add(new ExitCableV2(state, info.nextGroupNode, insideObject, cable));
+				}else if(info.next == Info.Parent) {
+					System.out.println("Error in VisualState");
+				}else {
+					state = ExitCableState.UP;
+					mylist.add(new ExitCableV2(state, ousideObject, insideObject, cable));
+				}
+			}
+		}
+	}
+
+
+	private void createresultList(LinkedList<TreeNode<TreeGroupNodeData>> list,
+			TreeNode<TreeGroupNodeData> firstCommon, LinkedList<TreeNode<TreeGroupNodeData>> resultList) {
+		for(TreeNode<TreeGroupNodeData> node: list) {
+			if(node == firstCommon) {
+				break;
+			}
+			resultList.add(node);
+		}
+	}
+
+
+	private LinkedList<TreeNode<TreeGroupNodeData>> createList(CpsUpperNode insideUpperNode,
+			HashMap<CpsUpperNode, TreeNode<TreeGroupNodeData>> fastaccess) {
+		TreeNode<TreeGroupNodeData> actualNode = fastaccess.get(insideUpperNode);
+		LinkedList<TreeNode<TreeGroupNodeData>> list = new LinkedList<TreeNode<TreeGroupNodeData>>();
+		list.add(actualNode);
+		while(actualNode.getParent() != null) {
+			actualNode = actualNode.getParent();
+			list.add(actualNode);
+		}
+		return list;
+	}
+
+
+	private void addCable(HashMap<AbstractCpsObject, CpsUpperNode> inGroupObjects, DecoratedCable cable,
+			DecoratedGroupNode groupNodeFromObject,ArrayList<ExitCable> exitCables) {
+		if(groupNodeFromObject != null) {
+			boolean isIntern = inGroupObjects.get(cable.getModel().getA()) == inGroupObjects.get(cable.getModel().getB()); //Case null == null is not possible trough before Filtering MinimumModel#addUpperObjects(CpsUpperNode)
+			if(isIntern) {
+				addToGroupNode(cable, groupNodeFromObject.getInternCableList());						
+			}else {
+				if(inGroupObjects.get(cable.getModel().getA()) == groupNodeFromObject.getModel() && inGroupObjects.get(cable.getModel().getB()) != groupNodeFromObject.getModel()) {					
+					//addToGroupNode(new ExitCable(cable, groupNodeFromObject.getModel(),inGroupObjects.get(cable.getModel().getB()), cable.getModel().getA(), cable.getModel().getB()), groupNodeFromObject.getExitCableList());		
+					exitCables.add(new ExitCable(cable, groupNodeFromObject.getModel(),inGroupObjects.get(cable.getModel().getB()), cable.getModel().getA(), cable.getModel().getB()));
+				}else if(inGroupObjects.get(cable.getModel().getA()) != groupNodeFromObject.getModel() && inGroupObjects.get(cable.getModel().getB()) == groupNodeFromObject.getModel()) {					
+					//addToGroupNode(new ExitCable(cable, groupNodeFromObject.getModel(),inGroupObjects.get(cable.getModel().getA()), cable.getModel().getB(), cable.getModel().getA()), groupNodeFromObject.getExitCableList());		
+					exitCables.add(new ExitCable(cable, groupNodeFromObject.getModel(),inGroupObjects.get(cable.getModel().getA()), cable.getModel().getB(), cable.getModel().getA()));
+				}
+			}
+		}
+	}
+
+
+	private <DecoratedObject> void addToGroupNode(DecoratedObject object, ArrayList<DecoratedObject> groupNodeListPar) {
+		groupNodeListPar.add(object);
+	}
+
+	//Generics
+	private <ModelOfObject, DecoratedObject> DecoratedGroupNode addObject(HashMap<ModelOfObject, CpsUpperNode> inGroupObjects, ModelOfObject modelOfObject, ArrayList<DecoratedObject> listToAdd, DecoratedObject object, HashMap<CpsUpperNode, DecoratedGroupNode> createdGroupNodes) {
+		if(inGroupObjects.containsKey(modelOfObject)) {
+			return  createdGroupNodes.get(inGroupObjects.get(modelOfObject));
+		}
+		listToAdd.add(object);
+		return null;
+	}
+
+	public enum Info{
+		Nothing, Parent, Child
+	}
+	private class NodeInfo{
+		public CpsUpperNode groupNode;
+		public Info previous = Info.Nothing;
+		public Info next = Info.Nothing;
+		public CpsUpperNode previousGroupNode = null;
+		public CpsUpperNode nextGroupNode = null;
+		
+		public NodeInfo(CpsUpperNode groupNode) {
+			this.groupNode = groupNode;
+		}
+		public String toString() {
+			return "Previuos: " + previous.toString() + "|Next: " + next.toString();
+		}
+		
+	}
+	public HashMap<CpsUpperNode, DecoratedGroupNode> getCreatedGroupNodes() {
+		return createdGroupNodes;
+	}
+	private class TreeNode<T> {
+		private  TreeNode<T> parentNode;
+		private List<TreeNode<T>> children;
+		private T data;
+		
+		public TreeNode( TreeNode<T> parentNode, List<TreeNode<T>> children, T data) {
+			this.parentNode = parentNode;
+			this.children = children;
+			this.data = data;
+		}
+		
+		//Methods
+		public TreeNode<T> getParent(){
+			return parentNode;
+		}
+		public List<TreeNode<T>> getChildren(){
+			return children;
+		}
+		public T getData() {
+			return data;
+		}
+		public String toString() {
+			return "[" + data.toString() + " Children(" + children.stream().map(Object::toString).collect(Collectors.joining(", ")) + ")]";
+		}
+	}
+	private class TreeGroupNodeData{
+		public CpsUpperNode groupNode;
+		public int layer;
+		public TreeGroupNodeData(CpsUpperNode groupNode, int layer) {
+			this.groupNode = groupNode;
+			this.layer = layer;
+		}
+		public String toString() {
+			return "Layer:" + layer;
+		}
+	}
+	
+	private void addTreeNode(TreeNode<TreeGroupNodeData> node, DecoratedGroupNode dGroupNode, int layer, HashMap<CpsUpperNode, TreeNode<TreeGroupNodeData>> fastaccess) {
+		TreeNode<TreeGroupNodeData> newNode = new TreeNode<TreeGroupNodeData> (node, new ArrayList<TreeNode<TreeGroupNodeData>>() , new TreeGroupNodeData(dGroupNode.getModel(), layer));
+		node.getChildren().add(newNode);
+		fastaccess.put(newNode.data.groupNode, newNode);
+		for(DecoratedGroupNode dGroupNodeIntern: dGroupNode.getGroupNodeList()) {
+			addTreeNode(newNode, dGroupNodeIntern, layer+1, fastaccess);
+		}
+	}
+
+
+	public ArrayList<ExitCableV2> getExitCableList() {
+		return exitCableList;
+	}
+}
+

+ 7 - 156
src/ui/view/AbstractCanvas.java

@@ -92,86 +92,9 @@ public abstract class AbstractCanvas extends JPanel {
 
 	// ------------------------------------------ METHODS
 	// ------------------------------------------
-	String paintEdge(CpsEdge con, String maxCap) {
-		if (con!=null && con.getA() != null && con.getB() != null && con.getA().getId() != model.getSelectedObjectID() && con.getB().getId() != model.getSelectedObjectID()
-				&& con != edgeHighlight) {
-			if (con.getConnected() == CpsEdge.CON_UPPER_NODE
-					|| con.getConnected() == CpsEdge.CON_UPPER_NODE_AND_INSIDE) {
-				setEdgeState(con);
-			} else {
-				g2.setColor(Color.DARK_GRAY);
-				g2.setStroke(new BasicStroke(2));
-			}
-			g2.drawLine(con.getA().getPosition().x, con.getA().getPosition().y, con.getB().getPosition().x,
-					con.getB().getPosition().y);
-
-			maxCap = setCapacityString(con, maxCap);
-
-			if (showedInformation[0]) {
-				if (con.getConnected() == CpsEdge.CON_UPPER_NODE
-						|| con.getConnected() == CpsEdge.CON_UPPER_NODE_AND_INSIDE) {
-					g2.drawString(con.getFlow() + "/" + maxCap,
-							(con.getA().getPosition().x + con.getB().getPosition().x) / 2,
-							(con.getA().getPosition().y + con.getB().getPosition().y) / 2);
-				} else {
-					g2.drawString("not connected", (con.getA().getPosition().x + con.getB().getPosition().x) / 2,
-							(con.getA().getPosition().y + con.getB().getPosition().y) / 2);
-				}
-			}
-		}
-
-		return maxCap;
-	}
-
-	void setEdgeState(CpsEdge con) {
-		if (con.isWorking()) {
-			g2.setColor(Color.GREEN);
-			if (con.getCapacity() != CpsEdge.CAPACITY_INFINITE) {
-				g2.setStroke(new BasicStroke(Math.min(((con.getFlow() / con.getCapacity() * 3) + 1), 4)));
-			}
-		} else {
-			g2.setColor(Color.RED);
-			g2.setStroke(new BasicStroke(2));
-		}
-	}
-
-	String setCapacityString(CpsEdge con, String maxCap) {
-		if (con.getCapacity() == -1) {
-			maxCap = Character.toString('\u221e');
-		} else if (con.getCapacity() == -2) {
-			maxCap = "???";
-		} else {
-			maxCap = String.valueOf(con.getCapacity());
-		}
-		return maxCap;
-	}
-
-	String drawEdgeLine(CpsEdge con, String maxCap) {
-		if (con.getA().getId() == model.getSelectedObjectID() || model.getSelectedCpsObjects().contains(con.getA())
-				|| tempSelected.contains(con.getA()) || con.getB().getId() == model.getSelectedObjectID()
-				|| model.getSelectedCpsObjects().contains(con.getB())
-				|| tempSelected.contains(con.getB()) && con != edgeHighlight) {
-			g2.drawLine(con.getA().getPosition().x, con.getA().getPosition().y, con.getB().getPosition().x,
-					con.getB().getPosition().y);
-
-			maxCap = setCapacityString(con, maxCap);
-
-			if (showedInformation[0]) {
-				if (con.getConnected() == CpsEdge.CON_UPPER_NODE
-						|| con.getConnected() == CpsEdge.CON_UPPER_NODE_AND_INSIDE) {
-					g2.drawString(con.getFlow() + "/" + maxCap,
-							(con.getA().getPosition().x + con.getB().getPosition().x) / 2,
-							(con.getA().getPosition().y + con.getB().getPosition().y) / 2);
-				} else {
-					g2.drawString("not connected", (con.getA().getPosition().x + con.getB().getPosition().x) / 2,
-							(con.getA().getPosition().y + con.getB().getPosition().y) / 2);
-				}
-			}
-		}
-
-		return maxCap;
-	}
+	
 
+	
 	/**
 	 * Paints the SupplyBar for the given cps object on the canvas
 	 * 
@@ -179,6 +102,7 @@ public abstract class AbstractCanvas extends JPanel {
 	 *            Graphics used
 	 * @param cps
 	 *            cpsObject which the supplyBar should be drawn for
+	 * @deprecated
 	 */
 	protected void paintSupplyBar(Graphics g, AbstractCpsObject cps) {
 		g2.setColor(Color.black);
@@ -311,83 +235,7 @@ public abstract class AbstractCanvas extends JPanel {
 		}
 	}
 
-	void setEdgePictureAndHighlighting(AbstractCpsObject cps) {
-		// node image
-		if (cps instanceof CpsNode && (cps == tempCps || model.getSelectedCpsObject() == cps
-				|| model.getSelectedCpsObjects().contains(cps) || tempSelected.contains(cps))) {
-			img = Util.loadImage("/Images/node_selected.png");
-		} else {
-			if (cps instanceof HolonSwitch) {//TODO: What the hell are thes ecalls doing here?
-				if (((HolonSwitch) cps).getState(model.getCurIteration())) {
-					((HolonSwitch) cps).setAutoState(true);
-				} else {
-					((HolonSwitch) cps).setAutoState(false);
-				}
-			}
-			// Highlighting
-			if ((cps == tempCps && model.getSelectedCpsObjects().size() == 0 && tempSelected.size() == 0)
-					|| model.getSelectedCpsObjects().contains(cps) || tempSelected.contains(cps)) {
-				/**
-				 * draw selected Blue Frame
-				 */
-				g2.setColor(Color.BLUE);
-				g2.fillRect((int) (cps.getPosition().x - controller.getScaleDiv2() - scalediv20),
-						(int) (cps.getPosition().y - controller.getScaleDiv2() - scalediv20),
-						(int) (controller.getScale() + (scalediv20 * 2)),
-						(int) (controller.getScale() + (scalediv20 * 2)));
-				/**
-				 * 
-				 */
-				if(cps instanceof HolonObject){
-					g2.setColor(((HolonObject)cps).getColor());
-					g2.fillRect((int) (cps.getPosition().x - controller.getScaleDiv2() - scalediv20+3),
-							(int) (cps.getPosition().y - controller.getScaleDiv2() - scalediv20+3),
-							(int) (controller.getScale() + (scalediv20 * 2)-6),
-							(int) (controller.getScale() + (scalediv20 * 2)-6));					
-				}
-				
-				if (showedInformation[1] && cps instanceof HolonObject) {
-					g2.setColor(Color.BLACK);
-					float totalEnergy = ((HolonObject) cps).getEnergyAtTimeStep(model.getCurIteration());
-					g2.drawString(Float.toString(totalEnergy), cps.getPosition().x - controller.getScaleDiv2(),
-							cps.getPosition().y - controller.getScaleDiv2() - 10);
-				}else if (showedInformation[1] && cps instanceof HolonBattery)
-                {
-                	g2.setColor(Color.BLACK);
-                    g2.drawString(((HolonBattery) cps).getCanvasBatteryString(model.getCurIteration()), cps.getPosition().x - controller.getScaleDiv2(),
-                            cps.getPosition().y - controller.getScaleDiv2() - 10);
-                }
-			} else if (cps instanceof HolonObject) {
-				g2.setColor(((HolonObject) cps).getColor());
-
-				g2.fillRect((int) (cps.getPosition().x - controller.getScaleDiv2() - scalediv20),
-						(int) (cps.getPosition().y - controller.getScaleDiv2() - scalediv20),
-						(int) (controller.getScale() + (scalediv20 * 2)),
-						(int) (controller.getScale() + (scalediv20 * 2)));
 
-				if (showedInformation[1]) {
-					g2.setColor(Color.BLACK);
-					float totalEnergy = ((HolonObject) cps).getEnergyAtTimeStep(model.getCurIteration());
-					g2.drawString(Float.toString(totalEnergy), cps.getPosition().x - controller.getScaleDiv2(),
-							cps.getPosition().y - controller.getScaleDiv2() - 10);
-				}
-			}else if (cps instanceof HolonBattery) {
-                if (showedInformation[1]) {
-                	g2.setColor(Color.BLACK);
-                    g2.drawString(((HolonBattery) cps).getCanvasBatteryString(model.getCurIteration()), cps.getPosition().x - controller.getScaleDiv2(),
-                            cps.getPosition().y - controller.getScaleDiv2() - 10);
-                }
-            }
-			// set image
-			if(cps instanceof HolonBattery)
-			{
-				img = Util.loadImage(((HolonBattery) cps).getImageBattery());
-			}else
-			{
-				img = Util.loadImage(cps.getImage());
-			}
-		}
-	}
 
 	void drawMarker() {
 		if (sx > x && sy > y) {
@@ -400,7 +248,10 @@ public abstract class AbstractCanvas extends JPanel {
 			g2.drawRect(sx, y, x - sx, sy - y);
 		}
 	}
-
+	/**
+	 * @deprecated
+	 * @param g
+	 */
 	void showTooltip(Graphics g) {
 		if (toolTip) {
 			g2.setColor(new Color(255, 225, 150));

+ 2 - 2
src/ui/view/GUI.java

@@ -2764,12 +2764,12 @@ public class GUI implements CategoryListener {
 		JScrollPane scrollPane = getScrollPaneFromTabbedPane();
 		if (scrollPane.getViewport().getComponent(0) instanceof MyCanvas) {
 			unc = new UpperNodeCanvas(model, controller, unitGraph,
-					(CpsUpperNode) temp, "");
+					(CpsUpperNode) temp, "", scrollPane.getViewport().getComponent(0));
 
 		} else {
 			unc = new UpperNodeCanvas(model, controller, unitGraph,
 					(CpsUpperNode) temp, ((UpperNodeCanvas) scrollPane
-							.getViewport().getComponent(0)).path + " -> ");
+							.getViewport().getComponent(0)).path + " -> ", scrollPane.getViewport().getComponent(0));
 		}
 		unc.setShowedInformation(canvas.getShowedInformation());
 

+ 98 - 73
src/ui/view/MyCanvas.java

@@ -10,6 +10,7 @@ import ui.controller.UpdateController;
 import ui.model.CableWithState;
 import ui.model.Consumer;
 import ui.model.DecoratedCable;
+import ui.model.DecoratedGroupNode;
 import ui.model.DecoratedHolonObject;
 import ui.model.DecoratedHolonObject.HolonObjectState;
 import ui.model.DecoratedNetwork;
@@ -19,6 +20,7 @@ import ui.model.MinimumModel;
 import ui.model.Model;
 import ui.model.Passiv;
 import ui.model.Supplier;
+import ui.model.VisualRepresentationalState;
 
 import javax.swing.*;
 
@@ -34,6 +36,7 @@ import java.awt.font.LineMetrics;
 import java.awt.geom.Line2D;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 
 /**
@@ -45,7 +48,6 @@ public class MyCanvas extends AbstractCanvas implements MouseListener,
 		MouseMotionListener {
 
 	private static final long serialVersionUID = 1L;
-    private int displayOther = 0;
 	/**
 	 * Constructor.
 	 *
@@ -66,7 +68,6 @@ public class MyCanvas extends AbstractCanvas implements MouseListener,
 		showedInformation[3] = false;
 		showedInformation[4] = true;
 		control.setMaxCapacity(10000);
-		setKeyBindings();
 		popmenu.add(itemCut);
 		popmenu.add(itemCopy);
 		popmenu.add(itemPaste);
@@ -132,9 +133,10 @@ public class MyCanvas extends AbstractCanvas implements MouseListener,
 							animCps.get(i).getPosition().x = savePos.get(i).x;
 							animCps.get(i).getPosition().y = savePos.get(i).y;
 						}
-						controller.addUpperNode("NodeOfNode", null, animCps);
+						controller.addUpperNode("GroupNode", null, animCps);
 						controller.calculateStateForCurrentTimeStep();
 						triggerUpdateController();
+						model.getSelectedCpsObjects().clear();
 						repaint();
 					}
 				});
@@ -167,6 +169,7 @@ public class MyCanvas extends AbstractCanvas implements MouseListener,
 					animT = new javax.swing.Timer(
 							animDelay,
 							actionEvent1 -> {
+								model.getSelectedCpsObjects().clear();
 								if (animDuration - animDelay >= 0) {
 									for (int i = 0; i < animCps.size(); i++) {
 										Position pos = animCps.get(i).getPosition();
@@ -188,9 +191,7 @@ public class MyCanvas extends AbstractCanvas implements MouseListener,
 										animCps.get(i).getPosition().y = savePos
 												.get(i).y;
 									}
-
-									controller
-											.calculateStateForCurrentTimeStep();
+									controller.calculateStateForCurrentTimeStep();
 									triggerUpdateController();
 									repaint();
 								}
@@ -436,8 +437,70 @@ public class MyCanvas extends AbstractCanvas implements MouseListener,
 	{
 		drawCanvasObject(g, dSwitch.getState() == SwitchState.Open ? HolonSwitch.getSwitchOpenImage(): HolonSwitch.getSwitchClosedImage() , dSwitch.getModel().getPosition());
 	}
+	
+	private void paintExitCable(Graphics2D g, ExitCableV2 eCable) {
+		Position start = eCable.getStart().getPosition();
+		Position end = eCable.getFinish().getPosition();
+		float currentEnergy = eCable.getCable().getFlowEnergy();
+		float capacity = eCable.getCable().getModel().getCapacity();
+		switch(eCable.getCable().getState()) {
+		case Burned:
+			g.setColor(Color.RED);
+			g.setStroke(new BasicStroke(2));
+			break;
+		case Working:
+			g.setColor(new Color(13, 175, 28));
+			g.setStroke(new BasicStroke((currentEnergy / capacity* 2f) + 1));
+			break;
+		}
+		g.drawLine(start.x, start.y, end.x, end.y);
+		Position middle = new Position((start.x + end.x) / 2, (start.y + end.y) / 2);
+		g.setFont(new Font("TimesRoman", Font.PLAIN, Math.max((int) (controller.getScale() / 3.5f), 10) )); 
+		g.drawString(currentEnergy + "/" + capacity , middle.x, middle.y);
+		switch(eCable.getState()) {
+		case DOWN:
+			break;
+		case DOWNDOWN:
+			break;
+		case DOWNUP:
+		case UP:
+		default:
+			System.out.println("Error");
+			break;
+		}
+	}
+	private void paintGroupNode(Graphics2D g, DecoratedGroupNode dGroupNode, CpsUpperNode onThisGroupNodeModel) {
+//		for(ExitCable exitCable : dGroupNode.getExitCableList()) {
+//			if(exitCable.getOutsideUpperNode() != onThisGroupNodeModel) {
+//				System.out.println("Check!");
+//				continue;
+//			}
+//			Position start = exitCable.getInsideUpperNode().getPosition();
+//			Position end =  exitCable.getOusideObject().getPosition();
+//			float currentEnergy = exitCable.getCable().getFlowEnergy();
+//			float capacity = exitCable.getModel().getCapacity();
+//			switch(exitCable.getCable().getState()) {
+//			case Burned:
+//				g.setColor(Color.RED);
+//				g.setStroke(new BasicStroke(2));
+//				break;
+//			case Working:
+//				g.setColor(new Color(13, 175, 28));
+//				g.setStroke(new BasicStroke((currentEnergy / capacity* 2f) + 1));
+//				break;
+//			}
+//			g.drawLine(start.x, start.y, end.x, end.y);
+//			Position middle = new Position((start.x + end.x) / 2, (start.y + end.y) / 2);
+//			g.setFont(new Font("TimesRoman", Font.PLAIN, Math.max((int) (controller.getScale() / 3.5f), 10) )); 
+//			g.drawString(currentEnergy + "/" + capacity , middle.x, middle.y);
+//		}
+		Position pos = dGroupNode.getModel().getPosition();
+		g.setColor(Color.lightGray);
+		g.fillRect(pos.x - controller.getScaleDiv2(), pos.y - controller.getScaleDiv2(), controller.getScale(), controller.getScale());
+		drawCanvasObject(g, "/Images/upper_node.png" , pos);
+	}
 	private void paintSupplyBar(Graphics2D g, float percentage, Color color, Position pos) {
-		// +1, -2, -1 little Adjustment for pixelperfect alignment
+		// +1, -2, -1 little Adjustment for pixel perfect alignment
 		int barWidth = (int) (controller.getScale());
 		int barHeight = (int) (controller.getScale() / 5);
 		g.setColor(Color.WHITE);
@@ -498,36 +561,35 @@ public class MyCanvas extends AbstractCanvas implements MouseListener,
 		if(model.getSelectedEdge() != null) selectedEdges.add(model.getSelectedEdge());
 		//timstep:
 		g.setFont(new Font("TimesNewRoman", Font.PLAIN, Math.max((int) (controller.getScale() / 3.5f), 10) )); 
-		g.drawString("DEBUG Timestep:" + controller.getSimManager().getActualDecorState().getTimestepOfState() + ((displayOther != 0) ? " " + ((displayOther > 0) ? "+" + displayOther: displayOther): "") , 10, 10);
 		g2d.setColor(Color.BLACK);
-		for(DecoratedCable cable : controller.getSimManager().getActualDecorStateWithOffSet(displayOther).getLeftOverEdges()) {
+		
+		VisualRepresentationalState  visualState = controller.getSimManager().getActualVisualRepresentationalState();
+		//VisualState Representation:
+		for(ExitCableV2 cable : visualState.getExitCableList()) {
+			paintExitCable(g2d, cable);
+		}
+		for(DecoratedCable cable : visualState.getCableList()) {
 			paintCable(g2d, cable, selectedEdges.contains(cable.getModel()));
 		}
-		for(DecoratedNetwork network : controller.getSimManager().getActualDecorStateWithOffSet(displayOther).getNetworkList()) {
-			for(DecoratedCable cable : network.getDecoratedCableList()) {
-				paintCable(g2d, cable, selectedEdges.contains(cable.getModel()));
-			}
-			for(Consumer con: network.getConsumerList()) {
-				paintConsumer(g2d, con);
-			}
-			for(Consumer con: network.getConsumerSelfSuppliedList()) {
-				paintConsumer(g2d, con);
-			}
-			for(Supplier sup: network.getSupplierList()) {
-				paintSupplier(g2d, sup);
-			}
-			for(Passiv pas: network.getPassivNoEnergyList()) {
-				paintCanvasObject(g2d, pas);
-			}
+		for(DecoratedGroupNode dGroupNode : visualState.getGroupNodeList()) {
+			paintGroupNode(g2d, dGroupNode, null);
 		}
-		
-		for(DecoratedSwitch dSwitch : controller.getSimManager().getActualDecorStateWithOffSet(displayOther).getDecoratedSwitches()) {
-			paintSwitch(g2d, dSwitch);
+		for(Consumer con: visualState.getConsumerList()) {
+			paintConsumer(g2d, con);					
+		}
+		for(Supplier sup: visualState.getSupplierList()) {
+			paintSupplier(g2d, sup);				
+		}
+		for(Passiv pas: visualState.getPassivList()) {
+			paintCanvasObject(g2d, pas);
 		}
-		//should be in DecorState
-		for(CpsNode node : controller.getSimManager().getActualDecorStateWithOffSet(displayOther).getNodeList()) {
+		for(DecoratedSwitch dSwitch : visualState.getSwitchList()) {
+				paintSwitch(g2d, dSwitch);
+		}
+		for(CpsNode node : visualState.getNodeList()) {
 			drawCanvasObject(g2d, "/Images/node.png" , node.getPosition());
 		}
+		
 		//-->oldCode 
 		if (doMark) {
 			g2d.setColor(Color.BLACK);
@@ -888,8 +950,11 @@ public class MyCanvas extends AbstractCanvas implements MouseListener,
 							deleteNode = true;
 						}
 					} else {
-						e = new CpsEdge(cps, tempCps, model.getMaxCapacity());
-						controller.addEdgeOnCanvas(e);
+						if(!(cps instanceof CpsUpperNode || tempCps instanceof CpsUpperNode)) {
+							e = new CpsEdge(cps, tempCps, model.getMaxCapacity());
+							controller.addEdgeOnCanvas(e);
+						}
+						
 					}
 				}
 			}
@@ -1079,46 +1144,6 @@ public class MyCanvas extends AbstractCanvas implements MouseListener,
 		}
 	}
 	
-	private void setKeyBindings() {
-	      ActionMap actionMap = getActionMap();
-	      int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
-	      InputMap inputMap = getInputMap(condition );
-
-	      String vkLeft = "VK_UP";
-	      String vkRight = "VK_DOWN";
-	      inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), vkLeft);
-	      inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), vkRight);
-
-	      actionMap.put(vkLeft, new KeyAction(vkLeft));
-	      actionMap.put(vkRight, new KeyAction(vkRight));
-
-	   }
-
-
-	   @SuppressWarnings("serial")
-	private class KeyAction extends AbstractAction {
-	      public KeyAction(String actionCommand) {
-	         putValue(ACTION_COMMAND_KEY, actionCommand);
-	      }
-
-		@Override
-		public void actionPerformed(ActionEvent actionEvent) {
-			System.out.println(actionEvent.getActionCommand() + " pressed");
-			switch(actionEvent.getActionCommand()) {
-			case "VK_UP":
-				System.out.println("increase");
-				if(displayOther < 0)displayOther++;
-				repaint();
-				break;
-			case "VK_DOWN":
-				System.out.println("decrease");
-				displayOther--;
-				repaint();
-				break;
-			default:
-				break;
-			}
-		}
-	   }
+	
 	   
 }

+ 2 - 2
src/ui/view/Outliner.java

@@ -83,9 +83,9 @@ public class Outliner extends JFrame {
 			switches.add(new DefaultMutableTreeNode(dSwitch.getModel().getName()));
 		}
 		
-		for(CpsNode node: decoratedState.getNodeList()) {
+		/*for(CpsNode node: decoratedState.getNodeList()) {
 			nodes.add(new DefaultMutableTreeNode(node.getName()));
-		}
+		}*/
 		
 		for(DecoratedNetwork dNet: decoratedState.getNetworkList()) {
 			DefaultMutableTreeNode network = new DefaultMutableTreeNode("Network");

+ 352 - 19
src/ui/view/UpperNodeCanvas.java

@@ -6,7 +6,17 @@ import com.google.gson.JsonParseException;
 
 import ui.controller.Control;
 import ui.controller.UpdateController;
+import ui.model.Consumer;
+import ui.model.DecoratedCable;
+import ui.model.DecoratedGroupNode;
+import ui.model.DecoratedHolonObject;
+import ui.model.DecoratedSwitch;
 import ui.model.Model;
+import ui.model.Passiv;
+import ui.model.Supplier;
+import ui.model.VisualRepresentationalState;
+import ui.model.DecoratedHolonObject.HolonObjectState;
+import ui.model.DecoratedSwitch.SwitchState;
 
 import javax.swing.*;
 
@@ -16,9 +26,11 @@ import java.awt.event.MouseEvent;
 import java.awt.event.MouseListener;
 import java.awt.event.MouseMotionListener;
 import java.awt.geom.Line2D;
+import java.awt.image.BufferedImage;
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.HashSet;
 
 /**
  * This Class is the Canvas. All Objects will be visualized here
@@ -35,7 +47,8 @@ public class UpperNodeCanvas extends AbstractCanvas implements MouseListener, Mo
     int code;
     private JLabel breadCrumb;
     private int upperNodeID;
-
+    private Component parent;
+    private BufferedImage parentPreview;
     /**
      * Constructor.
      *
@@ -43,7 +56,7 @@ public class UpperNodeCanvas extends AbstractCanvas implements MouseListener, Mo
      * @param control   the Controller
      * @param unitGraph
      */
-    UpperNodeCanvas(Model mod, Control control, UnitGraph unitGraph, CpsUpperNode UpperNode, String parentPath) {
+    UpperNodeCanvas(Model mod, Control control, UnitGraph unitGraph, CpsUpperNode UpperNode, String parentPath, Component parentComponent) {
         toolTip = false;
 
         this.controller = control;
@@ -53,6 +66,8 @@ public class UpperNodeCanvas extends AbstractCanvas implements MouseListener, Mo
         this.code = UpperNode.hashCode();
         this.path = parentPath + upperNode.getName();
         this.breadCrumb = new JLabel(path);
+        this.parent =  parentComponent;
+        parentPreview = this.getScaledImageOfComponent(parentComponent, 1f);
         // this.add(breadCrumb);
         scalediv20 = model.getScale() / 20;
 
@@ -138,7 +153,7 @@ public class UpperNodeCanvas extends AbstractCanvas implements MouseListener, Mo
                         animCps.get(i).getPosition().x = savePos.get(i).x;
                         animCps.get(i).getPosition().y = savePos.get(i).y;
                     }
-                    controller.addUpperNode("NodeOfNode", upperNode, model.getSelectedCpsObjects());
+                    controller.addUpperNode("GroupNode", upperNode, model.getSelectedCpsObjects());
                     controller.calculateStateForCurrentTimeStep();
                     repaint();
                 }
@@ -328,14 +343,331 @@ public class UpperNodeCanvas extends AbstractCanvas implements MouseListener, Mo
         this.addMouseMotionListener(this);
     }
 
-    /**
-     * Paints all Components on the Canvas.
-     *
-     * @param g Graphics
-     */
-    public void paintComponent(Graphics g) {
-        String maxCap = null;
-        super.paintComponent(g);
+	/**
+	 * Paints all Components on the Canvas.
+	 *
+	 * @param g
+	 *            Graphics
+	 */
+	
+	private Color getStateColor(HolonObjectState state) {
+		switch(state) {
+		case NOT_SUPPLIED:
+			return new Color(230, 120, 100);
+		case NO_ENERGY:
+			return Color.white;
+		case OVER_SUPPLIED:
+			return new Color(166, 78, 229);
+		case PARTIALLY_SUPPLIED:
+			return Color.yellow;
+		case PRODUCER:
+			return Color.lightGray;
+		case SUPPLIED:
+			return new Color(13, 175, 28);
+		default:
+			return Color.BLACK;
+		}
+	}
+	private void paintCanvasObject(Graphics2D g, DecoratedHolonObject decoratedHolonObject){
+		Position pos = decoratedHolonObject.getModel().getPosition();
+		Color statecolor = getStateColor(decoratedHolonObject.getState());
+		g.setColor(statecolor);
+		g.fillRect(pos.x - controller.getScaleDiv2(), pos.y - controller.getScaleDiv2(), controller.getScale(), controller.getScale());
+		drawCanvasObject(g, decoratedHolonObject.getModel().getImage(), pos);
+	}
+	private void drawCanvasObjectString(Graphics2D g, Position posOfCanvasObject, float energy) {
+		g.setColor(Color.BLACK);
+		g.setFont(new Font("TimesNewRoman", Font.PLAIN, (int) (controller.getScale() / 4f) )); 
+		g.drawString((energy > 0)? "+" + Float.toString(energy): Float.toString(energy), posOfCanvasObject.x - controller.getScaleDiv2(), posOfCanvasObject.y - controller.getScaleDiv2() - 1);
+	}
+	private void paintConsumer(Graphics2D g, Consumer con){
+		paintCanvasObject(g, con);
+		paintSupplyBar(g,con.getSupplyBarPercentage(), getStateColor(con.getState()), con.getModel().getPosition());
+		drawCanvasObjectString(g, con.getModel().getPosition(), -con.getEnergyNeededFromNetwork());
+	}
+	private void paintSupplier(Graphics2D g, Supplier sup){
+		paintCanvasObject(g, sup);
+		drawCanvasObjectString(g, sup.getModel().getPosition(), sup.getEnergyToSupplyNetwork());
+	}
+	
+	private void drawCanvasObject(Graphics2D g, String Image, Position pos) {
+		g.drawImage(Util.loadImage(Image, controller.getScale(), controller.getScale()) , 
+				pos.x - controller.getScaleDiv2(),
+				pos.y - controller.getScaleDiv2(),
+				controller.getScale(), controller.getScale() , null);
+	}
+	
+	private void paintCable(Graphics2D g, DecoratedCable cable, boolean isSelected)
+	{
+		Position start = cable.getModel().getA().getPosition();
+		Position end =  cable.getModel().getB().getPosition();
+		float currentEnergy = cable.getFlowEnergy();
+		float capacity = cable.getModel().getCapacity();
+		switch(cable.getState()) {
+		case Burned:
+			g.setColor(Color.RED);
+			g.setStroke(new BasicStroke(2));
+			break;
+		case Working:
+			g.setColor(new Color(13, 175, 28));
+			g.setStroke(new BasicStroke((currentEnergy / capacity* 2f) + 1));
+			break;
+		}
+		if(isSelected){
+			g.setColor(Color.lightGray);
+		}
+		g.drawLine(start.x, start.y, end.x, end.y);
+		Position middle = new Position((start.x + end.x) / 2, (start.y + end.y) / 2);
+		g.setFont(new Font("TimesRoman", Font.PLAIN, Math.max((int) (controller.getScale() / 3.5f), 10) )); 
+		g.drawString(currentEnergy + "/" + capacity , middle.x, middle.y);
+	}
+	private void paintSwitch(Graphics2D g, DecoratedSwitch dSwitch)
+	{
+		drawCanvasObject(g, dSwitch.getState() == SwitchState.Open ? HolonSwitch.getSwitchOpenImage(): HolonSwitch.getSwitchClosedImage() , dSwitch.getModel().getPosition());
+	}
+	private void paintGroupNode(Graphics2D g, DecoratedGroupNode dGroupNode) {
+		Position pos = dGroupNode.getModel().getPosition();
+		g.setColor(Color.lightGray);
+		g.fillRect(pos.x - controller.getScaleDiv2(), pos.y - controller.getScaleDiv2(), controller.getScale(), controller.getScale());
+		drawCanvasObject(g, "/Images/upper_node.png" , pos);
+	}
+	private void paintExitCable(Graphics2D g, ExitCableV2 eCable) {
+		Position start = eCable.getStart().getPosition();
+		Position end = eCable.getFinish().getPosition();
+		float currentEnergy = eCable.getCable().getFlowEnergy();
+		float capacity = eCable.getCable().getModel().getCapacity();
+		switch(eCable.getCable().getState()) {
+		case Burned:
+			g.setColor(Color.RED);
+			g.setStroke(new BasicStroke(2));
+			break;
+		case Working:
+			g.setColor(new Color(13, 175, 28));
+			g.setStroke(new BasicStroke((currentEnergy / capacity* 2f) + 1));
+			break;
+		}
+		switch(eCable.getState()) {
+		case DOWN:
+		case DOWNDOWN:
+			g.drawLine(start.x, start.y, end.x, end.y);
+			Position middle = new Position((start.x + end.x) / 2, (start.y + end.y) / 2);
+			g.setFont(new Font("TimesRoman", Font.PLAIN, Math.max((int) (controller.getScale() / 3.5f), 10) )); 
+			g.drawString(currentEnergy + "/" + capacity , middle.x, middle.y);
+			break;
+		case DOWNUP:
+		case UP:
+			Vector2d vStart = new Vector2d(start.x, start.y);
+			Vector2d vEnd = new Vector2d(end.x, end.y);
+			float stretchFactor = 4 * model.getScale();
+			stretchFactor =  (stretchFactor > vStart.getDistance(vEnd))? vStart.getDistance(vEnd) : stretchFactor;
+			Vector2d vPosition = vStart.add((vEnd.subtract(vStart)).normalize().multiply(stretchFactor));
+			Position result = new Position(Math.round(vPosition.getX()),Math.round(vPosition.getY()));
+			g.drawLine(start.x, start.y, result.x, result.y);
+			Position middle1 = new Position((start.x +result.x) / 2, (start.y + +result.y) / 2);
+			g.setFont(new Font("TimesRoman", Font.PLAIN, Math.max((int) (controller.getScale() / 3.5f), 10) )); 
+			g.drawString(currentEnergy + "/" + capacity , middle1.x, middle1.y);
+			drawCanvasObject(g, "/Images/arrowUp.png" , result);
+			break;
+		default:
+			System.out.println("Error");
+			break;
+		}
+	}
+	private void paintSupplyBar(Graphics2D g, float percentage, Color color, Position pos) {
+		// +1, -2, -1 little Adjustment for pixel perfect alignment
+		int barWidth = (int) (controller.getScale());
+		int barHeight = (int) (controller.getScale() / 5);
+		g.setColor(Color.WHITE);
+		g.fillRect(pos.x - controller.getScaleDiv2(), pos.y + controller.getScaleDiv2() - 1, (int) barWidth, barHeight);
+		g.setColor(color);
+		g.fillRect(pos.x - controller.getScaleDiv2(), pos.y + controller.getScaleDiv2() - 1, (int) (barWidth * (percentage < 1 ? percentage : 1.0f) - 1), barHeight);
+		g.setColor(Color.BLACK);
+		g.setStroke(new BasicStroke(1));
+		g.drawRect(pos.x - controller.getScaleDiv2(), pos.y + controller.getScaleDiv2() - 1, barWidth - 1 , barHeight);
+		g.setFont(new Font("TimesNewRoman", Font.PLAIN, (int) (barHeight * 1.5) - 2)); 
+		String percentageString = (Math.round((percentage * 100))) + "%";
+		int stringWidth = (int) g.getFontMetrics().getStringBounds(percentageString, g).getWidth();
+		if(percentage > 1.0f) g.setColor(Color.WHITE); //Just to see better on purple
+		g.drawString(percentageString, pos.x + 1 - stringWidth / 2, pos.y + controller.getScaleDiv2() - 1+ barHeight);
+		
+	}
+	
+	//old code
+	void drawMarker(Graphics2D g) {
+		Color transparentGrey = new Color(128, 174, 247, 40);
+		if (sx > x && sy > y) {
+			g.drawRect(x, y, sx - x, sy - y);
+			g.setColor(transparentGrey);
+			g.fillRect(x, y, sx - x, sy - y);
+		} else if (sx < x && sy < y) {
+			g.drawRect(sx, sy, x - sx, y - sy);
+			g.setColor(transparentGrey);
+			g.fillRect(sx, sy, x - sx, y - sy);
+		} else if (sx >= x) {
+			g.drawRect(x, sy, sx - x, y - sy);
+			g.setColor(transparentGrey);
+			g.fillRect(x, sy, sx - x, y - sy);
+		} else if (sy >= y) {
+			g.drawRect(sx, y, x - sx, sy - y);
+			g.setColor(transparentGrey);
+			g.fillRect(sx, y, x - sx, sy - y);
+		}
+	}
+   private BufferedImage getScaledImageOfComponent(Component component, double scale) {
+            BufferedImage bi = new BufferedImage(
+                (int)(component.getWidth()*scale),
+                (int)(component.getHeight()*scale),
+                BufferedImage.TYPE_INT_RGB);
+            Graphics2D gNew = bi.createGraphics();
+            gNew.scale(scale, scale);
+            component.paint(gNew);
+            gNew.dispose();
+
+            return bi;
+        }
+	public void paintComponent(Graphics g) {		
+		super.paintComponent(g);
+		Graphics2D g2d = (Graphics2D) g;
+		g2d.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING,
+				RenderingHints.VALUE_ANTIALIAS_ON));
+		//-->Old code
+		if (drawEdge) {
+			g2d.setColor(Color.BLACK);
+			g2d.setStroke(new BasicStroke(1));
+			g2d.drawLine(tempCps.getPosition().x, tempCps.getPosition().y, x, y);
+		}
+		//<--
+		//SelectedCable
+		HashSet<CpsEdge> selectedEdges = new HashSet<CpsEdge>();
+		for(AbstractCpsObject aCps:  model.getSelectedCpsObjects()) {
+			for(CpsEdge edge: aCps.getConnections()) {
+				selectedEdges.add(edge);
+			}
+		}
+		if(model.getSelectedEdge() != null) selectedEdges.add(model.getSelectedEdge());
+
+		
+		DecoratedGroupNode  actualGroupNode = controller.getSimManager().getActualVisualRepresentationalState().getCreatedGroupNodes().get(upperNode);
+		//VisualState Representation:
+		for(ExitCableV2 cable : actualGroupNode.getExitCableList()) {
+			paintExitCable(g2d, cable);
+		}
+		for(DecoratedCable cable : actualGroupNode.getInternCableList()) {
+			paintCable(g2d, cable, selectedEdges.contains(cable.getModel()));
+		}
+		//ExitCable:
+//		for(ExitCable exitCable : actualGroupNode.getExitCableList()) {
+//			Position start = exitCable.getInsideObject().getPosition();
+//			Position end =  exitCable.getOusideObject().getPosition();
+//			Vector2d vStart = new Vector2d(start.x, start.y);
+//			Vector2d vEnd = new Vector2d(end.x, end.y);
+//			float stretchFactor = 4 * model.getScale();
+//			stretchFactor =  (stretchFactor > vStart.getDistance(vEnd))? vStart.getDistance(vEnd) : stretchFactor;
+//			Vector2d vPosition = vStart.add((vEnd.subtract(vStart)).normalize().multiply(stretchFactor));// vStart + (direction to end) * magnitude; 
+//			float currentEnergy = exitCable.getCable().getFlowEnergy();
+//			float capacity = exitCable.getModel().getCapacity();
+//			switch(exitCable.getCable().getState()) {
+//			case Burned:
+//				g2d.setColor(Color.RED);
+//				g2d.setStroke(new BasicStroke(2));
+//				break;
+//			case Working:
+//				g2d.setColor(new Color(13, 175, 28));
+//				g2d.setStroke(new BasicStroke((currentEnergy / capacity* 2f) + 1));
+//				break;
+//			}
+//			Position result = new Position(Math.round(vPosition.getX()),Math.round(vPosition.getY()));
+//			g2d.drawLine(start.x, start.y, result.x, result.y);
+//			Position middle = new Position((start.x +result.x) / 2, (start.y + +result.y) / 2);
+//			g2d.setFont(new Font("TimesRoman", Font.PLAIN, Math.max((int) (controller.getScale() / 3.5f), 10) )); 
+//			g2d.drawString(currentEnergy + "/" + capacity , middle.x, middle.y);
+//			drawCanvasObject(g2d, "/Images/arrowUp.png" , result);
+			//Get Window:
+//			int scale = controller.getScale() * 2 ;
+//			g2d.drawRect(result.x - scale/2 - 1 , result.y - scale/2 -1 ,scale + 2,scale + 2);
+//			Position groupNode = exitCable.getCpsUpperNode().getPosition();
+//			Position outSideNode = exitCable.getOusideObject().getPosition();;
+//			int smallX, smallY, bigX, bigY;
+//			smallX = Math.min(groupNode.x, outSideNode.x) - controller.getScaleDiv2() ;
+//			smallY = Math.min(groupNode.y, outSideNode.y) - controller.getScaleDiv2();
+//			bigX = Math.max(groupNode.x, outSideNode.x)+ controller.getScaleDiv2();
+//			bigY = Math.max(groupNode.y, outSideNode.y)+ controller.getScaleDiv2();
+//			smallX = groupNode.x - controller.getScaleDiv2() * 3;
+//			smallY = groupNode.y - controller.getScaleDiv2() * 3;
+//			bigX = groupNode.x + controller.getScaleDiv2() * 3;
+//			bigY = groupNode.y + controller.getScaleDiv2() * 3;
+//			smallX= (smallX < 0) ? 0: smallX;
+//			smallY = (smallY < 0) ? 0: smallY;
+//			bigX = (bigX < parentPreview.getWidth()) ? bigX :  parentPreview.getWidth();
+//			bigY = (bigY < parentPreview.getHeight()) ? bigY :  parentPreview.getHeight();
+//			float aspectratio =  ((float)bigX-smallX) /  ((float)bigY-smallY);
+//			g2d.drawImage(parentPreview.getSubimage(smallX, smallY,bigX-smallX,bigY-smallY).getScaledInstance(Math.round(((float)scale) * aspectratio), Math.round(((float)scale) / aspectratio), Image.SCALE_SMOOTH), 
+//					result.x - scale/2,
+//					result.y - scale/2,
+//					scale, scale , null);
+//		}
+		
+		for(DecoratedGroupNode dGroupNode : actualGroupNode.getGroupNodeList()) {
+			paintGroupNode(g2d, dGroupNode);
+		}
+		for(Consumer con: actualGroupNode.getConsumerList()) {
+			paintConsumer(g2d, con);					
+		}
+		for(Supplier sup: actualGroupNode.getSupplierList()) {
+			paintSupplier(g2d, sup);				
+		}
+		for(Passiv pas: actualGroupNode.getPassivList()) {
+			paintCanvasObject(g2d, pas);
+		}
+		for(DecoratedSwitch dSwitch : actualGroupNode.getSwitchList()) {
+				paintSwitch(g2d, dSwitch);
+		}
+		for(CpsNode node : actualGroupNode.getNodeList()) {
+			drawCanvasObject(g2d, "/Images/node.png" , node.getPosition());
+		}
+		
+		//-->oldCode 
+		if (doMark) {
+			g2d.setColor(Color.BLACK);
+			g2d.setStroke(new BasicStroke(0));
+			drawMarker(g2d);
+		}
+		//Test Selection
+		//Objects:
+		g2d.setColor(Color.BLUE);
+		g2d.setStroke(new BasicStroke(1));
+		Color transparentGrey = new Color(128, 174, 247, 40);
+		for(AbstractCpsObject aCps:  model.getSelectedCpsObjects()) {
+			if(aCps instanceof CpsNode) {
+				Position pos = aCps.getPosition();
+				g2d.setColor(transparentGrey);
+				g2d.fillOval(pos.x - (int) (controller.getScaleDiv2()), pos.y - (int) (controller.getScaleDiv2()),  controller.getScale(),  controller.getScale());
+				g2d.setColor(Color.LIGHT_GRAY);
+				g2d.setStroke(new BasicStroke(2));
+				g2d.drawOval(pos.x - (int) (controller.getScaleDiv2()), pos.y - (int) (controller.getScaleDiv2()),  controller.getScale(),  controller.getScale());
+			}
+			else {
+				Position pos = aCps.getPosition();
+				g2d.setColor(transparentGrey);
+				g2d.fillRect(pos.x - (int) (controller.getScaleDiv2()* 1.5f), pos.y - (int) (controller.getScaleDiv2()* 1.5f), (int) (controller.getScale()* 1.5f) , (int) (controller.getScale()* 1.5f));
+				g2d.setColor(Color.LIGHT_GRAY);
+				g2d.setStroke(new BasicStroke(2));
+				g2d.drawRect(pos.x - (int) (controller.getScaleDiv2()* 1.5f), pos.y - (int) (controller.getScaleDiv2()* 1.5f), (int) (controller.getScale()* 1.5f) , (int) (controller.getScale()* 1.5f));				
+			}
+
+		}
+		//maybeReplace:
+		if(mayBeReplaced != null){
+			g2d.setColor(Color.RED);
+			Position pos = mayBeReplaced.getPosition();
+			g.drawImage(Util.loadImage("/Images/replace.png") , 
+					pos.x + controller.getScaleDiv2(),
+					pos.y - controller.getScale(),
+					controller.getScaleDiv2(), controller.getScaleDiv2(), null);
+		}
+		//<-- OldCode
+	}
+        
 //        ((JScrollPane) this.getParent().getParent()).setColumnHeaderView(breadCrumb);
 //        // Rendering
 //        g2 = (Graphics2D) g;
@@ -580,8 +912,7 @@ public class UpperNodeCanvas extends AbstractCanvas implements MouseListener, Mo
 //
 //        // Tooltip
 //        showTooltip(g);
-        System.out.println("PaintCanvas");
-    }
+
 
     @Override
     public void mouseClicked(MouseEvent e) {
@@ -984,12 +1315,14 @@ public class UpperNodeCanvas extends AbstractCanvas implements MouseListener, Mo
                         deleteNode = true;
                     }
                 } else {
-                    e = new CpsEdge(cps, tempCps, model.getMaxCapacity());
-                    if (outsideCon) {
-                        controller.connectNodes(e, upperNode);
-                    } else {
-                        controller.addEdgeUpperNode(e, upperNode);
-                    }
+                	if(!(cps instanceof CpsUpperNode || tempCps instanceof CpsUpperNode)) {
+						e = new CpsEdge(cps, tempCps, model.getMaxCapacity());
+						if (outsideCon) {
+							controller.connectNodes(e, upperNode);
+						} else {
+							controller.addEdgeUpperNode(e, upperNode);
+						}
+					}
                 }
             }
         }