package sim.lib.functions;

import java.awt.*;

import sim.*;
import sim.engine.*;

public abstract class Function extends WrapperPainted implements EngineModule
{
	protected double delay = 1;
	protected int busSize;
	
	public Function()
	{
		super();
		this.busSize = 8;
	}
	
	public double getDelay()
	{
		return this.delay;
	}
	
	public void changeDelay(double newValue)
	{
		this.delay = newValue;
	}
	
	public int getBusSize()
	{
		return this.busSize;
	}
	
	public void setBusSize(int size)
	{
		this.busSize = size;
	}

/* ==================================================================
	Creation Part
	================================================================= */
	
	public Wrapper createWrapper()
	{
		return this.getCopy();
	}
	
	public Wrapper createWrapper(Point gridPosition)
	{
		Wrapper result = this.getCopy();
		result.setGridLocation(gridPosition);
		return result;
	}
	
	protected abstract Wrapper getCopy();
	
/* ==================================================================
	Simulation part
	================================================================= */
	public void reset()
	{
	}
	
	public Wrapper getParentWrapper()
	{
		return this;
	}
	
/* ==================================================================
	Storage Part
	================================================================= */
	public String getSpecificParameters()
	{
		return (Double.toString(this.delay) + Wrapper.SEPARATOR + this.busSize + Wrapper.SEPARATOR);
	}
	
	public void loadWrapper(String[] specificParameters) throws SimException
	{
		if(specificParameters.length == this.getNumberOfSpecificParameters())
		{
			try
			{
				this.delay = Double.valueOf(specificParameters[0]).doubleValue();
				this.busSize = Integer.valueOf(specificParameters[1]).intValue();
			}
			catch(NumberFormatException e)
			{
				throw (new SimException("incorrect parameter type"));
			}
		}
		else
			throw (new SimException("incorrect number of parameters"));
	}
	
	public int getNumberOfSpecificParameters()
	{
		return 2;
	}
	
/* ==================================================================
	Popup Part
	================================================================= */
	protected int oldBusSize = 0;
	
	public boolean hasProperties()
	{
		return true;
	}
	
	public Component getPropertyWindow()
	{
		return (new FunctionProperty(this.busSize, this.delay));
	}
		
	public void respondToChanges(Component property)
	{
		this.delay = ((FunctionProperty)property).getDelay();
		
		if(this.oldBusSize == 0)
			this.oldBusSize = this.busSize;
		
		CentralPanel.ACTIVE_GRID.eraseComponent(this);
		this.setBusSize(((FunctionProperty)property).getBusSize());
		CentralPanel.ACTIVE_GRID.paintComponent(this);
		
	}
	
	public void restoreOriginalProperties()
	{
		if(this.oldBusSize != 0)
		{
			this.setBusSize(this.oldBusSize);
			this.oldBusSize = 0;
		}
	}
}
