package tests;

import classes.*;
import static org.junit.Assert.assertTrue;

import java.awt.Color;
import java.util.ArrayList;

import org.junit.Test;

/**
 * Test for the Classes.
 * 
 * @author Gruppe14
 */
public class PraktikumHolonsTestClasses {

	/**
	 * Test for the Categories.
	 */
	@Test
	public void testCategory() {
		Category test1 = new Category("Test1");
		Category test2 = new Category("Test2");
		HolonObject obj1 = new HolonObject("Test Object");
		ArrayList<AbstractCpsObject> arr = new ArrayList<>();

		assertTrue("Name not correct", test1.getName().equals("Test1"));
		assertTrue("Name not correct", test2.getName().equals("Test2"));
		assertTrue("Name should not be the same", !test1.getName().equals(test2.getName()));
		assertTrue("Should be empty", test1.getObjects().size() == 0);
		test1.getObjects().add(obj1);
		assertTrue("Should not be empty", test1.getObjects().size() == 1);
		assertTrue("Should be empty", test2.getObjects().size() == 0);
		test1.setObjects(arr);
		assertTrue("Should be empty", test1.getObjects().size() == 0);
		arr.add(obj1);
		test2.setObjects(arr);
		arr = new ArrayList<>();
		assertTrue("Shoud be empty", arr.isEmpty());
		arr = test2.getObjects();
		assertTrue("Shoud not be empty", !arr.isEmpty());
	}

	/**
	 * Test for HolonObject.
	 */
	@Test
	public void testHolonObject() {

		HolonObject test1 = new HolonObject("Test1");
		HolonObject test2 = new HolonObject("Test2");
		HolonObject test3 = new HolonObject(test1);
		HolonElement ele = new HolonElement("Element", 1, 10);
		ArrayList<HolonElement> arr = new ArrayList<>();
		assertTrue("Should be Empty", test1.getElements().isEmpty());
		test1.setElements(arr);
		assertTrue("Should be Empty", test1.getElements().isEmpty());
		arr.add(ele);
		arr.add(ele);
		assertTrue("Should be Empty", test2.getElements().isEmpty());
		assertTrue("Current Energy not corrent", test2.getCurrentEnergy() == 0);
		test2.setElements(arr);
		assertTrue("Should not be Empty", !test2.getElements().isEmpty());
		assertTrue("Current Energy not corrent", test2.getCurrentEnergy() == 20);
		assertTrue("Current Energy not corrent", test2.getCurrentEnergyAtTimeStep(20) == 20);
		String str = test2.toStringElements();
		assertTrue("String not corrent", str.equals("Element, Element"));
		test2.deleteElement(0);
		test2.addElements(ele);
		assertTrue("Current Energy not corrent", test2.getCurrentEnergy() == 20);
		assertTrue("Should be Empty", test3.getElements().isEmpty());
		test3.setElements(test2.copyElements(test2.getElements()));
		assertTrue("Should be Empty", !test3.getElements().isEmpty());
		assertTrue("Should be state 0", test3.getState() == 0);
		test3.setState(1);
		assertTrue("Should be state 1", test3.getState() == 1);
		test3.setState(2);
		assertTrue("Should be state 2", test3.getState() == 2);
		test3.setState(3);
		assertTrue("Should be state 3", test3.getState() == 3);
		test3.setState(4);
		assertTrue("Should be state 4", test3.getState() == 4);
		assertTrue("Element not Found", test3.searchElement("Element") != null);
		test1.setElements(new ArrayList<HolonElement>());
		assertTrue("Not Empty", !test1.checkIfPartiallySupplied(1));
		test3.addElements(new HolonElement("Element2", 1, -10));
		assertTrue("Not Partially Supplied", test3.checkIfPartiallySupplied(1));
		test3.addElements(new HolonElement("Element2", 2, -10));
		assertTrue("Not Partially Supplied", test3.checkIfPartiallySupplied(1));
		test1.addElements(new HolonElement("Element2", 2, -10));
		assertTrue("minSupply < 0", !test1.checkIfPartiallySupplied(1));
		Color color = test3.getColor();
		test3.setColor(new Color(0, 255, 255));
		assertTrue(color.getBlue() != test3.getColor().getBlue());
		test3.addElements(new HolonElement("Element3", 3, 50));
		test3.setState();
		assertTrue("Should be state 3", test3.getState() == 3);
		test1.setState();
		assertTrue("Should be state 0", test1.getState() == 0);
		test2.setState();
		test2.setBorderColor(color);
		assertTrue("Color not Same", color == test2.getBorderColor());
	}

	/**
	 * Test for HolonSwitch.
	 */
	@Test
	public void testHolonSwitch() {
		HolonSwitch test1 = new HolonSwitch("Test1");
		HolonSwitch test2 = new HolonSwitch(test1);

		assertTrue("Manuel Mode is on", !test2.getManualMode());
		test2.switchState();
		assertTrue(test2.getState());
		assertTrue(test2.getState(1));
		test2.setManualMode(true);
		test2.switchState();
		test2.switchState();
		assertTrue(test2.getState());
		assertTrue(test2.getState(1));
		assertTrue("Manuel Mode is off", test2.getManualMode());
		assertTrue("ManuelActive is off", test2.getActiveManual());
		test2.switchState();
		assertTrue("ManuelActive is on", !test2.getActiveManual());
		test2.switchState();
		assertTrue("ManuelActive is off", test2.getActiveManual());
		assertTrue(test1.getGraphPoints() != test2.getGraphPoints());
		test2.setGraphPoints(test1.getGraphPoints());
		assertTrue(test1.getGraphPoints() == test2.getGraphPoints());
	}

	/**
	 * Test for CpsEdge.
	 */
	@Test
	public void testCpsEdge() {
		CpsNode node1 = new CpsNode("Node1");
		CpsNode node2 = new CpsNode("Node2");
		CpsNode node3 = new CpsNode("Node3");
		CpsEdge edge1 = new CpsEdge(node1, node2, 100);
		CpsEdge edge2 = new CpsEdge(node2, node3);

		assertTrue("Flow not 0", edge1.getFlow() == 0);
		edge1.setFlow(50);
		assertTrue("Capacity not right", edge1.getCapacity() == 100);
		edge2.setFlow(50);
		edge1.setCapacity(200);
		assertTrue("Flow was not changed", edge1.getFlow() == 50);
		assertTrue("Capacity not right", edge1.getCapacity() == 200);
		assertTrue("line broken", edge2.getState());
		edge2.calculateState(false);
		assertTrue("line broken", edge2.getState());
		edge2.setFlow(200);
		edge2.calculateState(false);
		assertTrue("line not broken", !edge2.getState());
		edge1.setCapacity(-1);
		edge1.calculateState(false);
		edge1.setCapacity(500);
		edge1.calculateState(true);
		node1 = (CpsNode) edge1.getB();
		node2 = (CpsNode) edge2.getA();
		assertTrue("Not Same", node1 == node2);
		assertTrue("State not right", edge1.getState());
		edge1.setState(false);
		assertTrue("State not right", !edge1.getState());
		edge2.setTags(new ArrayList<Integer>());
		edge1.setTags(new ArrayList<Integer>());
		assertTrue("Tags not Empty", edge2.getTags().isEmpty());
		edge2.addTag(1);
		assertTrue("Tags not Empty", edge1.getTags().isEmpty());
		assertTrue("Tags Empty", !edge2.getTags().isEmpty());
		edge1.setTags(edge2.getTags());
		assertTrue("Tags Empty", !edge1.getTags().isEmpty());
	}

	/**
	 * Test for HolonElement.
	 */
	@Test
	public void testHolonElement() {
		HolonElement ele1 = new HolonElement("TV", 2, -20);
		HolonElement ele2 = new HolonElement("Fridge", 1, -50);
		HolonElement ele3 = new HolonElement(ele2);

		assertTrue("Array not empty", ele1.getEnergyAt()[0] == -20);
		assertTrue("Array not empty", ele1.getEnergyAt()[2] == -20);
		ele1.setEnergyAt(2, -10);
		assertTrue("Array not empty", ele1.getEnergyAt()[2] == -10);
		assertTrue("Name not correct", ele1.getEleName().equals("TV"));
		ele1.setEleName(ele2.getEleName());
		assertTrue("Name not correct", ele1.getEleName().equals("Fridge"));
		assertTrue("Amount not correct", ele2.getAmount() == 1);
		ele2.setAmount(5);
		assertTrue("Amount not correct", ele2.getAmount() == 5);
		assertTrue("Total Energy not Correct", ele2.getTotalEnergy() == ele2.getAmount() * ele2.getEnergy());
		assertTrue("Sign not correct", ele2.getSign() == '-');
		ele3.setSav("CVS");
		assertTrue("SAV not correct", ele3.getSav().equals("CVS"));
	}

	/**
	 * Test for Position.
	 */
	@Test
	public void testPosition() {
		Position pos1 = new Position(100, 200);
		Position pos2 = new Position();

		assertTrue("Wrong coordinates", pos1.x == 100 && pos1.y == 200);
		assertTrue("Are the Same", pos1.x != pos2.x);
		assertTrue("not (-1,-1)", pos2.x == -1 && pos2.y == -1);
	}

	/**
	 * Test SubNet.
	 */
	@Test
	public void testSubNet() {
		PraktikumHolonsAdapter adapter = new PraktikumHolonsAdapter();

		ArrayList<HolonObject> obj = new ArrayList<>();
		ArrayList<CpsEdge> edge = new ArrayList<>();
		ArrayList<HolonSwitch> sw = new ArrayList<>();

		assertTrue("Not Empty", obj.isEmpty());
		assertTrue("Not Empty", sw.isEmpty());
		assertTrue("Not Empty", edge.isEmpty());

		for (int i = 1; i < 10; i++) {
			HolonObject o = new HolonObject(adapter.generate(i));
			HolonSwitch s = new HolonSwitch(adapter.generate(i));
			o = new HolonObject(o);
			s = new HolonSwitch(s);
			obj.add(o);
			sw.add(s);
			edge.add(new CpsEdge(o, s));
		}

		SubNet sub = new SubNet(obj, edge, sw);

		assertTrue("Empty", !sub.getObjects().isEmpty() && sub.getObjects().size() == 9);
		assertTrue("Empty", !sub.getSwitches().isEmpty() && sub.getSwitches().size() == 9);
		assertTrue("Empty", !sub.getEdges().isEmpty() && sub.getEdges().size() == 9);
		assertTrue("Wrong Obj", sub.getObjects().get(5).getObjName().equals("F"));

	}

}
