package tests;

import classes.*;
import org.junit.Test;

import java.awt.*;
import java.util.ArrayList;

import static org.junit.Assert.assertTrue;

/**
 * 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<AbstractCanvasObject> 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, IdCounterElem.nextId(),null);
		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());

		test2.setElements(arr);
		assertTrue("Should not be Empty", !test2.getElements().isEmpty());

		assertTrue("Current Energy not corrent", test2.getEnergyAtTimeStep(20) == 20);
		String str = test2.toStringElements();
		assertTrue("String not corrent", str.equals("Element, Element"));
		test2.deleteElement(0);
		test2.addElement(ele);

		assertTrue("Should be Empty", test3.getElements().isEmpty());
		test3.setElements(test2.copyElements(test2.getElements()));
		
		assertTrue("Element not Found", test3.searchElement("Element") != null);
		test1.setElements(new ArrayList<>());
	}

	/**
	 * 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.isWorking());
//		assertTrue(test2.isWorking(1));
//		test2.setManualMode(true);
//		test2.switchState();
//		test2.switchState();
//		assertTrue(test2.isWorking());
//		assertTrue(test2.isWorking(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() {
		Node node1 = new Node("Node1");
		Node node2 = new Node("Node2");
		Node node3 = new Node("Node3");
		Edge edge1 = new Edge(node1, node2, 100);
		Edge edge2 = new Edge(node2, node3);

		node1 = (Node) edge1.getB();
		node2 = (Node) edge2.getA();
		assertTrue("Not Same", node1 == node2);
    
        edge2.setTags(new ArrayList<>());
        edge1.setTags(new ArrayList<>());
		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, -20f, IdCounterElem.nextId(),null);
		HolonElement ele2 = new HolonElement("Fridge", 1, -50f, IdCounterElem.nextId(),null);
        assertTrue("Array not empty",  ele1.getEnergyAtTimeStep(0) == -40);
        assertTrue("Array not empty", ele1.getEnergyAtTimeStep(2) == -40);
        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.getMaximumEnergy() == ele2.getAmount() * ele2.getEnergyPerElement());
	}
	/**
	 * 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<Edge> edge = new ArrayList<>();
		ArrayList<HolonSwitch> sw = new ArrayList<>();
		ArrayList<HolonBattery> sb = 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 Edge(o, s));
		}

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

		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"));

	}
	
}
