package classes;
import ui.model.Model;

import com.google.gson.annotations.Expose;

import ui.controller.*;

public class HolonBattery extends AbstractCanvasObject{
	
	@Expose
	private float inRatio;
	@Expose
	private float outRatio;
	@Expose
	private float capacity;
	@Expose
	private float initialStateOfCharge;
	@Expose
	private float[] stateOfChargeLevels;
	@Expose
	private float iterations = 0;
	public enum State{STANDBY, COLLECT, EMIT};
	private State state;
	/** Constructor for a unique ID.
	 * @param ObjName
	 */
	public HolonBattery(String ObjName)
	{
		super(ObjName);
		inRatio = 1000.0f;
		outRatio = 1000.0f;
		capacity = 20000.0f;
		initialStateOfCharge = 0;
		setState(State.STANDBY);
	}
	/** Constructor to Copy a Battery
	 * @param obj Object to copy.
	 */
	public HolonBattery(AbstractCanvasObject obj)
	{
		super(obj);
		super.setName(obj.getName());
		setInRatio(((HolonBattery) obj).getInRatio());
		setOutRatio(((HolonBattery) obj).getOutRatio());
		setCapacity(((HolonBattery) obj).getCapacity());
		setInitialStateOfCharge(((HolonBattery) obj).getInitialStateOfCharge());
		setState(State.STANDBY);
	}
	public float getCapacity() {
		return capacity;
	}
	public void setCapacity(float capacity) {	
		if(capacity < 0) //capasity can not be negative
		{
			capacity = 0;
		}
		this.capacity = capacity;
	}
	public float getOutRatio() {
		return outRatio;
	}
	public void setOutRatio(float outRatio) {
		if(outRatio < 0) //
		{
			outRatio = 0;
		}
		this.outRatio = outRatio;
	}
	public float getInRatio() {
			return inRatio;
	}
	//For Calculations
	public float getInAtTimeStep(int x)
	{
		if(getCapacity() - getStateOfChargeAtTimeStep(x) < inRatio)
			return getCapacity() - getStateOfChargeAtTimeStep(x);
		else
			return inRatio;
	}
	public float getOutAtTimeStep(int x)
	{
		if(getStateOfChargeAtTimeStep(x) < outRatio)
			return getStateOfChargeAtTimeStep(x);
		else
			return outRatio;
	}
	public void setInRatio(float inRatio) {
		if(inRatio < 0)
		{
			inRatio = 0;
		}
		this.inRatio = inRatio;
	}
	public State getState() {
		return state;
	}
	public void setState(State state) {
		this.state = state;
	}

	/**
	 * @return The String that is over the Battery in the Canvas if COLLECT the
	 *         input if EMIT the output of the Battery
	 */
	public String getCanvasBatteryString(int x)
	{
		x--;
		float stateOfCharge1 = getStateOfChargeAtTimeStep(x-1);
		float newStateOfCharge1 =  getStateOfChargeAtTimeStep(x);
		if(newStateOfCharge1 > stateOfCharge1)
		{
			return "-" + Float.toString(newStateOfCharge1 - stateOfCharge1);
		}
		else if (newStateOfCharge1 < stateOfCharge1)
		{
			return "+" +Float.toString(-(newStateOfCharge1 - stateOfCharge1)); // '"-" +' not needed because negative
		}else
		{
			return "0";
		}
		
	}
	public String toString()
	{
		return "HolonBattery" + this.getId();
		/*
		return "HolonBattery ID:" + this.getId() + " State:" + getState().name() 
				+ " InRatio:" + getInRatio() + " OutRatio:" + getOutRatio() 
				+ " Akku: " + getStateOfChargeAtTimeStep(SingletonControl.getInstance().getControl().getModel().getCurIteration()) + "/" + getCapacity();
	    */
	}
	public void setStateOfChargeAtTimeStep(float newStateOfCharge, int x) {
		if(iterations != SingletonControl.getInstance().getControl().getModel().getIterations())
		{
			stateOfChargeLevels = new float[SingletonControl.getInstance().getControl().getModel().getIterations()];
			iterations = SingletonControl.getInstance().getControl().getModel().getIterations();
		}
		
	
		stateOfChargeLevels[x] = validStateOfCharge(newStateOfCharge);
	}
	public float getStateOfChargeAtTimeStep(int x) {
		if(iterations != SingletonControl.getInstance().getControl().getModel().getIterations())
		{
			stateOfChargeLevels = new float[SingletonControl.getInstance().getControl().getModel().getIterations()];
			iterations = SingletonControl.getInstance().getControl().getModel().getIterations();
		}
		if(x < 0)
		{
			return initialStateOfCharge;
		}
		return stateOfChargeLevels[x];
	}
	public float getInitialStateOfCharge() {
		return initialStateOfCharge;
	}
	public void setInitialStateOfCharge(float initialStateOfCharge) {
		this.initialStateOfCharge = validStateOfCharge(initialStateOfCharge);
	}
	/** Correct if a state of charge is to big or to less
	 * @return a valid State of charge
	 */
	public float validStateOfCharge(float stateOfChargeToValid)
	{
		if(stateOfChargeToValid > capacity) //state of Charege can not more than the capacity
		{
			return capacity;
		}
		else if(stateOfChargeToValid < 0) // state of charge can not be a negativ value
		{
			return 0;
		}
		else
		{
			return stateOfChargeToValid;
		}
	}
	public String getImageBattery() {
		//HardCoded Image selection
		
		float actualStateOfCharge = getStateOfChargeAtTimeStep(SingletonControl.getInstance().getControl().getModel().getCurIteration() - 1 );
		int whichOne = (int)(actualStateOfCharge/capacity * 4);
		String battery = "/Images/battery"+ whichOne + ".png";
		setImage(battery);
		return battery;
	}
	
	@Override
	public HolonBattery makeCopy(){
		return new HolonBattery(this);
	}
}
