package classes;

import java.awt.Point;
import java.util.LinkedList;

/**
 * The class "HolonElement" represents any possible element that can be added to
 * a CpsObject (such as TV (consumer) or any energy source/producer).
 * 
 * @author Gruppe14
 *
 */
public class HolonElement {

	/* Name of the gadget */
	private String eleName;
	/* Quantity */
	private int amount;
	/* Energy per gadget */
	private float energy;
	/* If the gadget is working xor not (true xor false) */
	private boolean active;
	/* Total Energy */
	private float totalEnergy;
	/* +: for Consumers and -: Producers */
	private char sign;
	/* Place where the Object is Stored */
	private String sav;
	/* Object where the Element is Stored */
	private String obj;
	/* Unique Id of the Element */
	private int id; 
	/*
	 * Energy at each point of the graph with 100 predefined points. At the
	 * beginning, it starts with all values at energy
	 */
	private float[] energyAt = new float[100];
	// Points on the UnitGraph
	LinkedList<Point> graphPoints = new LinkedList<>();

	/**
	 * Create a new HolonElement with a user-defined name, amount of the same
	 * element and energy per element.
	 * 
	 * @param eleName
	 *            String
	 * @param amount
	 *            int
	 * @param energy
	 *            float
	 */
	public HolonElement(String eleName, int amount, float energy) {
		setEleName(eleName);
		setAmount(amount);
		setEnergy(energy);
		setActive(true);
		setSign(energy);
		setEnergyAt(energy);
		setId(IdCounterElem.nextId());
	}

	/**
	 * Create a copy of the HolonElement given each one a new ID.
	 * 
	 * @param element
	 *            element to copy
	 */
	public HolonElement(HolonElement element) {
		setEleName(element.getEleName());
		setAmount(element.getAmount());
		setEnergy(element.getEnergy());
		setActive(element.getActive());
		setSign(element.getEnergy());
		setEnergyAt(element.getEnergy());
		for (int i = 0; i < energyAt.length; i++) {
			energyAt[i] = element.getEnergyAt()[i];
		}
		for (Point p :element.getGraphPoints()) {
			this.graphPoints.add(new Point((int)p.getX(), (int)p.getY()));
		}
		setSav("CVS");
		setObj(element.getObj());
		setId(IdCounterElem.nextId());
	}

	/**
	 * Get the Array of energy (100 values).
	 * 
	 * @return energyAt Array of Floats
	 */
	public float[] getEnergyAt() {
		return energyAt;
	}

	/**
	 * Set energy to any value to the whole array.
	 * 
	 * @param energy
	 *            the value
	 */
	public void setEnergyAt(float energy) {
		for (int i = 0; i < energyAt.length; i++) {
			this.energyAt[i] = energy;
		}
	}

	/**
	 * Set energy to any value at a given position.
	 * 
	 * @param pos
	 *            int
	 * @param energy
	 *            float
	 */
	public void setEnergyAt(int pos, float energy) {
		this.energyAt[pos] = energy;
	}

	/**
	 * Get the user-defined Name.
	 * 
	 * @return the name String
	 */
	public String getEleName() {
		return eleName;
	}

	/**
	 * Set the name to any new name.
	 * 
	 * @param name
	 *            the name to set
	 */
	public void setEleName(String name) {
		this.eleName = name;
	}

	/**
	 * Get the actual amount of Elements in the selected Object.
	 * 
	 * @return the amount int
	 */
	public int getAmount() {
		return amount;
	}

	/**
	 * Set the amount of the Element in the selected Object.
	 * 
	 * @param amount
	 *            the amount to set
	 */
	public void setAmount(int amount) {
		this.amount = amount;
	}

	/**
	 * Get the energy value of the selected Element.
	 * 
	 * @return the energy
	 */
	public float getEnergy() {
		return energy;
	}

	/**
	 * Set the energy value of the selected Element.
	 * 
	 * @param energy
	 *            the energy to set
	 */
	public void setEnergy(float energy) {
		this.energy = energy;
	}

	/**
	 * Get the Status of the Element (see description of variables).
	 * 
	 * @return the active
	 */
	public boolean getActive() {
		return active;
	}

	/**
	 * Set the Status of the Element (see description of variables).
	 * 
	 * @param active
	 *            the active to set
	 */
	public void setActive(boolean active) {
		this.active = active;
	}

	/**
	 * Multiply the amount of gadgets, given by the user, and the
	 * consumption/production. If the switch isWorking is turned off for on
	 * gadget, the energy of this gadget have to be subtracted.
	 * 
	 * @return totalEnergy (actual)
	 */
	public float getTotalEnergy() {
		totalEnergy = ((float) amount) * energy;
		return totalEnergy;
	}

	/**
	 * Get the energy value at a selected time x.
	 * 
	 * @param x
	 *            int
	 * @return energy value
	 */
	public float getTotalEnergyAtTimeStep(int x) {
		float result = ((float) amount) * energyAt[x];
		return result;
	}

	/**
	 * Get the symbol of the value (see variable description).
	 * 
	 * @return the sign
	 */
	public char getSign() {
		return sign;
	}

	/**
	 * Set symbol of the value.
	 * 
	 * @param energy
	 *            the sign to set
	 */
	public void setSign(float energy) {
		if (energy < 0)
			this.sign = '-';
		else
			this.sign = '+';
	}

	/**
	 * @return the stored.
	 */
	public String getSav() {
		return sav;
	}

	/**
	 * for save purposes.
	 * 
	 * @param sav
	 *            the stored to set
	 */
	public void setSav(String sav) {
		this.sav = sav;
	}

	/**
	 * Get the actual object.
	 * 
	 * @return the obj
	 */
	public String getObj() {
		return obj;
	}

	/**
	 * Set the object to a new one.
	 * 
	 * @param obj
	 *            the obj to set
	 */
	public void setObj(String obj) {
		this.obj = obj;
	}

	/**
	 * Get the points (values) in the graph.
	 * 
	 * @return the Graph Points
	 */
	public LinkedList<Point> getGraphPoints() {
		return graphPoints;
	}

	/**
	 * Set the points (values) in the graph.
	 * 
	 * @param points
	 *            the Graph points
	 */
	public void setGraphPoints(LinkedList<Point> points) {
		this.graphPoints = points;
	}

	/**
	 * Set the ID of the HolonElement (one time only).
	 * 
	 * @param id
	 *            the id
	 */
	private void setId(int id) {
		this.id = id;
	}

	/**
	 * Get the Id of the selected HolonElement.
	 * 
	 * @return id the id
	 */
	public int getId() {
		return id;
	}
}
