package classes;

import com.google.gson.annotations.Expose;

import java.awt.Color;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * The abstract class "CpsObject" represents any possible object in the system
 * (except Edges). The representation of any object contains following
 * variables: see description of variables
 * 
 * @author Gruppe14
 *
 */
public abstract class AbstractCanvasObject {
	/* Type of the Object. */
	@Expose
	String objName;
	/* Name given by the user. */
	@Expose
	String name;
	/* ID of the Obj. */
	@Expose
	int id;
	/* Path of the image for the Obj. */
	@Expose
	String image;
	/* Array of neighbors */
	ArrayList<Edge> connections = new ArrayList<>();
	/* Position with a X and Y value */
	@Expose
	Position position = new Position(0,0);
	/*
	 * Energy input and output of each object in the grid Where the Object is
	 * Stored
	 */
	@Expose
	String sav;
	/* tags that can be used */
	public Set<Integer> tags = new HashSet<Integer>();

	/**
	 * Constructor for a CpsObejct with an unique ID.
	 * 
	 * @param objName
	 *            of the Object
	 */
	public AbstractCanvasObject(String objName) {
		setObjName(objName);
		setName(objName);
		setImage("/Images/Dummy_House.png");
	}

	/**
	 * Constructor for a new CpsObject with an unique ID (This constructor
	 * correspond to the interaction between the Categories and Canvas)-->
	 * actually the "new" Object is a copy.
	 * 
	 * @param obj
	 *            Object to be copied
	 */
	public AbstractCanvasObject(AbstractCanvasObject obj) {
		setObjName(obj.getObjName());
		setName(obj.getObjName());
		setConnections(new ArrayList<>());
		setId(IdCounter.nextId());
		setImage(obj.getImage());
	}
	
	public abstract AbstractCanvasObject makeCopy();

	/**
	 * Getter for the type of the Object.
	 * 
	 * @return String
	 */
	public String getObjName() {
		return objName;
	}

	/**
	 * Set the type of Object.
	 * 
	 * @param objName
	 *            String
	 */
	public void setObjName(String objName) {
		this.objName = objName;
	}

	/**
	 * Getter for the user-defined name (no unique).
	 * 
	 * @return String
	 */
	public String getName() {
		return name;
	}

	/**
	 * Set the name.
	 * 
	 * @param name
	 *            String
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * Getter of the unique ID.
	 * 
	 * @return int
	 */
	public int getId() {
		return id;
	}

	/**
	 * Set the ID to a new one.
	 * 
	 * @param id
	 *            the iD to set
	 */
	public void setId(int id) {
		this.id = id;
	}

	/**
	 * Get the path of the image for the selected Object.
	 * 
	 * @return String
	 */
	public String getImage() {
		return image;
	}

	/**
	 * Set the path of the image.
	 * 
	 * @param image
	 *            the Image to set
	 */
	public void setImage(String image) {
		this.image = image;
	}

	/**
	 * List of all existing connections.
	 * 
	 * @return the connections ArrayList
	 */
	public ArrayList<Edge> getConnections() {
		return connections;
	}

	/**
	 * Set a new ArrayList of connections (Update).
	 * 
	 * @param arrayList
	 *            the connections to set
	 */
	public void setConnections(ArrayList<Edge> arrayList) {
		this.connections = arrayList;
	}

	/**
	 * List of all existing connections.
	 * 
	 * @return the connections ArrayList
	 */
	public ArrayList<Edge> getConnectedTo() {
		return connections;
	}

	/**
	 * Add a new connection to the selected Object.
	 * 
	 * @param toConnect
	 *            Edge
	 */
	public void addConnection(Edge toConnect) {
		connections.add(toConnect);
	}

	/**
	 * Set the position of the Object in the canvas.
	 *
	 * @param x
	 *            X-Coord
	 * @param y
	 *            Y-Coord
	 */
	public void setPosition(int x, int y) {
		setPosition(new Position(x, y));
	}

	/**
	 * Get the actual position of the Object.
	 *
	 * @return Position Position of this Object
	 */
	public Position getPosition() {
		return position;
	}

	/**
	 * Set the position of the Object in the canvas.
	 *
	 * @param pos Coordinates
	 */
	public void setPosition(Position pos) {
		this.position = pos;
	}

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

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


}
