package sim.lib.functions;

import java.awt.*;

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

public class NotEqualTo extends CompareTo
{
/* ==================================================================
	Creation Part
	================================================================= */
	private static Image ICON = GuiFileLink.getImage("sim/lib/functions/NotEqualToIcon.gif");
	
	public Image getIcon()
	{
		return NotEqualTo.ICON;
	}
	
	public String getBubbleHelp()
	{
		return "Not equal to constant";
	}
	
/* ==================================================================
	GUI part
	================================================================= */
	public NotEqualTo()
	{
		super();
	}
	
	protected Wrapper getCopy()
	{
		NotEqualTo result = new NotEqualTo();
		result.changeDelay(this.delay);
		result.setBusSize(this.busSize);
		result.constant = this.constant;
		
		return result;
	}
	
	public void paint(Graphics g)
	{
		// draw if visible
		if(this.isVisible())
		{
			int gridGap = CentralPanel.ACTIVE_GRID.getCurrentGridGap();
			int increment = gridGap / 4;
			
			g.setColor(this.brush);
			
			g.drawRect(0, gridGap, 2 * gridGap - 1, 2 * gridGap - 1);
			
			g.fillRect(gridGap - 1, 0, 3, gridGap);
			g.drawLine(gridGap, 3 * gridGap, gridGap, 4 * gridGap);
			
			g.setFont(new Font(Wrapper.FONT_NAME, Font.PLAIN, 3 * increment));
			
			FontMetrics fm = g.getFontMetrics(g.getFont());
			
			Shape old = g.getClip();
			String toDraw = "= " + Integer.toString(this.constant, 16);
			g.setClip(0, gridGap, 2 * gridGap - 1, 2 * gridGap - 1);
			g.drawString(toDraw, gridGap - fm.stringWidth(toDraw) / 2, 2 * gridGap + fm.getAscent() / 2);
			g.drawString("/", gridGap - (fm.stringWidth(toDraw) - fm.stringWidth("=") + fm.stringWidth("/")) / 2, 2 * gridGap + fm.getAscent() / 2);
			
			g.setClip(old);
		}
	}
	
/* ==================================================================
	Simulation part
	================================================================= */
	public void evaluateOutput(double currentTime, Data[] currentInputs, EnginePeer peer)
	{
		double time = this.delay + currentTime;
		
		String binary = Integer.toBinaryString(this.constant);
		
		for(int loop = binary.length(); loop < this.busSize; loop++)
			binary = "0" + binary;
		
		boolean foundUndefined = false;
		boolean foundDifferent = false;
		
		for(int loop = 0; (loop < this.busSize) && (!foundDifferent); loop++)
		{
			if(currentInputs[loop].isUndefined())
				foundUndefined = true;
			else if(currentInputs[loop].getValue())
				foundDifferent = binary.charAt(this.busSize - 1 - loop) == '0';
			else
				foundDifferent = binary.charAt(this.busSize - 1 - loop) == '1';
		}
		
		if(foundDifferent)
			peer.setOutputPinValue(0, true, time);
		else if(foundUndefined)
			peer.setOutputPinUndefined(0, time);
		else
			peer.setOutputPinValue(0, false, time);
	}
	
	@Override
	public void writeVHDLEntity(String path) {
		VHDLGeneral.write1busto1bitFunction(path,getVHDLName(),this.busSize,"x /= "+this.constant);
	}

	@Override
	public String getVHDLName() {
		return "NOTEQUALTObus_ent_" + this.busSize;
	}
}