package ui.controller;

import java.util.ArrayList;

import classes.Category;
import classes.AbstractCpsObject;
import classes.HolonElement;
import classes.HolonObject;
import classes.HolonSwitch;
import classes.HolonTransformer;
import interfaces.CategoryListener;
import ui.model.Model;

/**
 * Controller for the Categories.
 * 
 * @author Gruppe14
 */
public class CategoryController {
	private Model model;
	private MultiPurposeController mpC;

	/**
	 * Constructor.
	 * 
	 * @param model
	 *            the Model
	 * @param mp
	 *            the MultiPurposeController
	 */
	public CategoryController(Model model, MultiPurposeController mp) {
		this.model = model;
		this.mpC = mp;
		initCategories();
	}

	/**
	 * init default category and objects.
	 */
	public void initCategories() {

		addNewCategory("Energy");
		addNewCategory("Building");
		addNewCategory("Component");

		addNewHolonObject(mpC.searchCat("Energy"), "Power Plant", new ArrayList<HolonElement>(),
				"/Images/power-plant.png");
		addNewHolonObject(mpC.searchCat("Building"), "House", new ArrayList<HolonElement>(), "/Images/home-2.png");
		addNewHolonSwitch(mpC.searchCat("Component"), "Switch", "/Images/switch-on.png");

	}

	/**
	 * Adds Category into Model if a Category with the same name already exists
<<<<<<< HEAD
	 * Add Category_+1
	 *  
	 * @param toAdd
	 *            neue Kategorie
=======
	 * Add Category_+1.
	 * 
	 * @param category
	 *            the new Category
>>>>>>> 90bc29b29bece3f981eca7b6bd629093b2c90382
	 */
	public void addCategory(Category category) {
		// int number = 0;
		// String name = toAdd.getName();
		// while (sC.containsInList(MODEL.getCategories(), toAdd)) {
		// number++;
		// toAdd.setName(name + "_" + number);
		// }
		int i = 0;
		while (mpC.searchCat(category.getName()) != null) {
			if (category.getName().contains("_"))
				category.setName(category.getName().substring(0, category.getName().indexOf('_')));
			category.setName(category.getName() + "_" + i);
			i++;
		}
		model.getCgIdx().put(category.getName(), model.getCategories().size());
		model.getCategories().add(category);
		notifyCatListeners();
	}

	/**
	 * Adds New Category into Model.
	 * 
	 * @param name
	 *            Bezeichnung der neuen Kategorie
	 */
	public void addNewCategory(String name) {

		addCategory(new Category(name));
	}

	/**
	 * remove a Category from Model.
	 * 
	 * @param c
	 *            Category
	 */
	public void removeCategory(Category c) {
		mpC.decIdx(c.getName(), model.getCgIdx());
		model.getCgIdx().remove(c.getName());
		model.getCategories().remove(c);

		notifyCatListeners();
	}

	/**
	 * delete a given Category.
	 * 
	 * @param category
	 *            the Category
	 */
	public void deleteCategory(String category) {
		removeCategory(mpC.searchCat(category));
	}

	/**
	 * Add Object into a Category.
	 * 
	 * @param category
	 *            Category
	 * @param object
	 *            Object
	 */
	public void addObject(Category category, AbstractCpsObject object) {
		int i = 0;
		while (mpC.searchCatObj(category, object.getObjName()) != null) {
			if (object.getObjName().contains("_"))
				object.setObjName(object.getObjName().substring(0, object.getObjName().indexOf('_')));
			String name = object.getObjName() + "_" + i;
			object.setObjName(name);
			object.setName(name);
			i++;
		}
		category.getObjIdx().put(object.getObjName(), category.getObjects().size());
		category.getObjects().add(object);
		notifyCatListeners();
	}

	/**
	 * Add new Holon Object to a Category.
	 * 
	 * @param category
	 *            Category
	 * @param object
	 *            New Object Name
	 * @param elements
	 *            Array of Elements
	 * @param image
	 *            the image Path
	 */
	public void addNewHolonObject(Category category, String object, ArrayList<HolonElement> elements, String image) {
		HolonObject obj = new HolonObject(object);
		obj.setImage(image);
		obj.setElements(elements);
		obj.setSav(category.getName());
		addObject(category, obj);
	}

	/**
	 * Add new Holon Transformer.
	 * 
	 * @param cat
	 *            Category
	 * @param objName
	 *            New Object Name
	 * @param image
	 *            the image Path
	 */
	public void addNewHolonTransformer(Category cat, String objName, String image) {
		HolonTransformer transformer = new HolonTransformer(objName);
		transformer.setImage(image);
		transformer.setSav(cat.getName());
		addObject(cat, transformer);
	}

	/**
	 * Add new Holon Switch.
	 * 
	 * @param cat
	 *            Category
	 * @param objName
	 *            New Object Name
	 * @param image
	 *            the Image Path
	 */
	public void addNewHolonSwitch(Category cat, String objName, String image) {
		HolonSwitch holonSwitch = new HolonSwitch(objName);

		holonSwitch.setImage(image);
		holonSwitch.setSav(cat.getName());
		addObject(cat, holonSwitch);
	}

	/**
	 * Removes an Object from a Category.
	 * @param category Category
	 * @param cps the Object
	 */
	public void removeObject(Category category, AbstractCpsObject cps) {

		mpC.decIdx(cps.getObjName(), category.getObjIdx());
		category.getObjIdx().remove(cps.getObjName());
		category.getObjects().remove(cps);

		notifyCatListeners();
	}

	/**
	 * Delete an Object from a Category.
	 * 
	 * @param category
	 *            the Category
	 * @param obj
	 *            the Object
	 */
	public void deleteObject(String category, String obj) {
		Category cat = mpC.searchCat(category);
		removeObject(cat, mpC.searchCatObj(cat, obj));
	}

	/**
	 * Init the CategoryListener.
	 * 
	 * @param catLis
	 *            the CategoryListener
	 */
	public void addCategoryListener(CategoryListener catLis) {
		model.getCategoryListeners().add(catLis);
	}

	/**
	 * notifies all listeners about changes in the Categories.
	 */
	public void notifyCatListeners() {
		for (CategoryListener l : model.getCategoryListeners()) {
			l.onChange(model.getCategories());
		}
	}

}
