package ui.controller;

import java.util.HashMap;
import java.util.Map.Entry;

import classes.Category;
import classes.CpsEdge;
import classes.AbstractCpsObject;
import classes.HolonElement;
import classes.HolonObject;
import ui.model.Model;

/**
 * Controller for Multiple Purposes.
 * 
 * @author Gruppe14
 */
public class MultiPurposeController {

	private Model model;

	/**
	 * Constructor.
	 * 
	 * @param model
	 *            Model
	 */
	public MultiPurposeController(Model model) {
		this.model = model;

	}

	/**
	 * search for category.
	 * 
	 * @param category
	 *            name of the Category
	 * @return the Category
	 */
	public Category searchCat(String category) {

		Integer idx;

		if ((idx = model.getCgIdx().get(category)) == null || model.getCgIdx().size() < 1)
			return null;
		else
			return model.getCategories().get(idx);
	}

	/**
	 * Search for Object in a Category.
	 * 
	 * @param category
	 *            name of the Category
	 * @param object
	 *            Name of the Object
	 * @return The Object
	 */
	public AbstractCpsObject searchCatObj(Category category, String object) {

		Integer idx;

		if ((idx = category.getObjIdx().get(object)) == null || category.getObjIdx().size() < 1)
			return null;
		else
			return category.getObjects().get(idx);
	}

	/**
	 * Search for Object by ID.
	 * 
	 * @param id
	 *            the ID of the Object
	 * @return the CpsObject
	 */
	public AbstractCpsObject searchByID(int id) {

		Integer idx;

		if ((idx = model.getCvsObjIdx().get(id)) == null || model.getCvsObjIdx().size() < 1)
			return null;
		else
			return model.getObjectsOnCanvas().get(idx);
	}

	/**
	 * Search for Element.
	 * 
	 * @param object
	 *            the Holon Object
	 * @param element
	 *            name of the Element
	 * @return the Holon Element
	 */
	public HolonElement searchEle(HolonObject object, String element) {

		Integer idx;

		if ((idx = object.getEleIdx().get(element)) == null || object.getEleIdx().size() < 1)
			return null;
		else
			return object.getElements().get(idx);
	}

	/**
	 * Search the Element by ID.
	 * 
	 * @param object
	 *            the Holon Object
	 * @param idEle
	 *            the Element ID
	 * @return The Holon Element
	 */
	public HolonElement searchEleById(HolonObject object, int idEle) {
		return object.searchElementById(idEle);
	}

	/**
	 * Search Edge between 2 Objects.
	 * 
	 * @param a
	 *            ID of Object a
	 * @param b
	 *            ID of Object b
	 * @return The Edge
	 */
	public CpsEdge searchEdge(int a, int b) {

		AbstractCpsObject objA = searchByID(a);
		AbstractCpsObject objB = searchByID(b);

		for (CpsEdge edge : model.getEdgesOnCanvas()) {
			// if (edge.getA().getObjName().equals(A.getObjName()) &&
			// (edge.getB().getObjName().equals(B.getObjName()))
			// || edge.getB().getObjName().equals(A.getObjName())
			// && (edge.getA().getObjName().equals(B.getObjName())))
			if ((edge.getA().equals(objA) && edge.getB().equals(objB))
					|| (edge.getB().equals(objA)) && edge.getA().equals(objB))
				return edge;
		}
		return null;
	}

	/**
	 * Decrement the Indices if a Key as been removed.
	 * 
	 * @param key
	 *            the Key
	 * @param <T>
	 *            key type
	 * @param map
	 *            the Map
	 */
	public <T> void decIdx(T key, HashMap<T, Integer> map) {

		for (Entry<T, Integer> i : map.entrySet()) {
			if (i.getValue() > map.get(key))
				i.setValue(i.getValue() - 1);
		}
	}

	/**
	 * Copies a HashMap into a new One.
	 * 
	 * @param map
	 *            the HashMap
	 * @param <T>
	 *            type
	 * @return Copy of the HashMap
	 */
	public static <T, Integer> HashMap<T, Integer> copyHashMap(HashMap<T, Integer> map) {

		HashMap<T, Integer> newMap = new HashMap<>();
		for (Entry<T, Integer> i : map.entrySet()) {
			newMap.put(i.getKey(), i.getValue());
		}
		return newMap;
	}

	/**
	 * Set the Algorithm.
	 * 
	 * @param obj
	 *            the Algorithm
	 */
	public void setAlgorithm(Object obj) {
		model.setAlgorithm(obj);
	}

}
