package sim.lib.gates;

import java.awt.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.util.Scanner;

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

import sim.MainWindow;

public class GateOR extends MultiInputGate
{
/* ==================================================================
	Creation Part
	================================================================= */
	private static Image ICON = GuiFileLink.getImage("sim/lib/gates/OrIcon.gif");
	
	public Image getIcon()
	{
		return GateOR.ICON;
	}
	
	public String getBubbleHelp()
	{
		return "OR gate";
	}
	
/* ==================================================================
	GUI part
	================================================================= */
	public GateOR()
	{
		super();
	}
	
	protected Wrapper getCopy()
	{
		GateOR result = new GateOR();
		
		result.setInputSize(this.inputSize);
		result.setOutputInvert(this.invertOutput);
		
		for(int loop = 0; loop < this.inputSize; loop++)
			result.setInputInvert(this.invertInputs[loop], loop);
		
		result.changeDelay(this.delay);
		
		return result;
	}
	
/* ==================================================================
	Simulation part
	================================================================= */
	public void evaluateOutput(double currentTime, Data[] currentInputs, EnginePeer peer)
	{
		double time = this.delay + currentTime;
		
		boolean foundTrue = false;
		boolean foundUndefined = false;
		
		for(int loopNumber = 0; (loopNumber < this.inputSize) && (!foundTrue); loopNumber++)
			if(currentInputs[loopNumber].isUndefined())
				foundUndefined = true;
			else if(currentInputs[loopNumber].getValue() ^ this.invertInputs[loopNumber])
				foundTrue = true;
		
		if(foundTrue)
			peer.setOutputPinValue(0, !this.invertOutput, time);
		else if(foundUndefined)
			peer.setOutputPinUndefined(0, time);
		else
			peer.setOutputPinValue(0, this.invertOutput, time);
	}
	
/* ==================================================================
	Rotation abd Flipping Part
	================================================================= */
	protected void paintNormal_0(Graphics g)
	{
		int gridGap = CentralPanel.ACTIVE_GRID.getCurrentGridGap();
		int increment = gridGap / 4;
		int center = this.gridSize.height * gridGap / 2;
		int middle = this.inputSize / 2;
		int diameter = 2 * increment;
		
		g.setColor(this.brush);
		
		int height = 17 * increment;
		int up = 10 * increment;
		int down = gridGap * 6;
		
		int seven = 7 * increment;
		int five = 5 * increment;
		
		if(this.invertOutput)
		{
			g.drawLine(height + diameter + 1, center, down, center);
			g.drawOval(height + 1, center - increment, diameter, diameter);
		}
		else
			g.drawLine(height, center, down, center);
		
		g.drawLine(seven, center + five, up, center + five);
		g.drawLine(seven, center - five, up, center - five);
		
		Shape old = g.getClip();
		g.setClip(up, center, height, center);
		g.drawOval(increment, center - height + gridGap, height, height + increment);
		
		g.setClip(up, 0, height, center);
		g.drawOval(increment, center - five, height, height + increment);
		
		g.setClip(seven, center - five, height, up);
		g.drawOval(0, center - seven - increment, seven + increment, height - increment);
		
		g.setClip(seven, diameter + increment, height, this.gridSize.height * gridGap - gridGap - diameter + 1);
		
		if(this.inputSize > 3)
		{
			up = center;
			down = center;
			
			while(up > 0)
			{
				up = up - seven - five;
				down = down + seven + five;
				g.drawOval(0, up - seven - increment, seven + increment, height - increment);
				g.drawLine(seven, up + five, seven, up + seven);
				g.drawOval(0, down - seven - increment, seven + increment, height - increment);
				g.drawLine(seven, down - five, seven, down - seven);
			}
		}
		g.setClip(old);
		
		up = gridGap;
		
		for(height = 0; height < middle; height++)
		{
			if(this.invertInputs[height])
			{
				g.drawLine(0, up, five - 1, up);
				g.drawOval(five - 1, up - increment, diameter, diameter);
			}
			else
				g.drawLine(0, up, seven, up);
		
			up = up + gridGap;
		}
		
		if((this.inputSize % 2 ) != 0)
		{
			if(this.invertInputs[middle])
			{
				g.drawLine(0, up, five - 1, up);
				g.drawOval(five - 1, up - increment, diameter, diameter);
			}
			else
				g.drawLine(0, up, seven, up);
			
			up = up + gridGap;
			
			for(height = middle + 1; height < this.inputSize; height++)
			{
				if(this.invertInputs[height])
				{
					g.drawLine(0, up, five - 1, up);
					g.drawOval(five - 1, up - increment, diameter, diameter);
				}
				else
					g.drawLine(0, up, seven, up);
				
				up = up + gridGap;
			}
		}
		else
		{
			up = up + gridGap;
			for(height = middle; height < this.inputSize; height++)
			{
				if(this.invertInputs[height])
				{
					g.drawLine(0, up, five - 1, up);
					g.drawOval(five - 1, up - increment, diameter, diameter);
				}
				else
					g.drawLine(0, up, seven, up);
				
				up = up + gridGap;
			}
		}
	}
	
	protected void paintNormal_90(Graphics g)
	{
		int gridGap = CentralPanel.ACTIVE_GRID.getCurrentGridGap();
		int increment = gridGap / 4;
		int center = this.gridSize.width * gridGap / 2;
		int middle = this.inputSize / 2;
		int diameter = 2 * increment;
		
		g.setColor(this.brush);
		
		int height = 14 * increment;
		int up = 5 * increment;
		int down;
		
		int sevenTeen = 17 * increment;
		int seven = 7 * increment;
		
		if(this.invertOutput)
		{
			g.drawLine(center, up - 1, center, 0);
			g.drawOval(center - increment, up - 1, diameter, diameter);
		}
		else
			g.drawLine(center, seven, center, 0);
		
		g.drawLine(center + up, sevenTeen, center + up, height);
		g.drawLine(center - up, sevenTeen, center - up, height);
		
		Shape old = g.getClip();
		g.setClip(center, 0, center, height);
		g.drawOval(center - sevenTeen + gridGap, up + increment, sevenTeen + increment, sevenTeen);
		
		g.setClip(0, 0, center, height);
		g.drawOval(center - up, up + increment, sevenTeen + increment, sevenTeen);
		
		g.setClip(center - up, 0, height - gridGap, sevenTeen + 1);
		g.drawOval(center - seven - increment, sevenTeen - increment, sevenTeen - increment, seven + increment);
		
		g.setClip(diameter + increment, 0, this.gridSize.width * gridGap - up - increment + 1, sevenTeen + 1);
		
		height = height - diameter;
		
		if(this.inputSize > 3)
		{
			up = center;
			down = center;
			
			while(up > 0)
			{
				up = up - height;
				down = down + height;
				g.drawOval(up - seven - increment, sevenTeen - increment, sevenTeen - increment, seven + increment);
				g.drawLine(up + seven - diameter, sevenTeen, up + seven, sevenTeen);
				g.drawOval(down - seven - increment, sevenTeen - increment, sevenTeen - increment, seven + increment);
				g.drawLine(down - seven + diameter, sevenTeen, down - seven, sevenTeen);
			}
		}
		g.setClip(old);
		
		up = gridGap;
		down = 6 * gridGap - 1;
		seven = sevenTeen + diameter;
		
		for(height = 0; height < middle; height++)
		{
			if(this.invertInputs[height])
			{
				g.drawLine(up, down, up, seven + 1);
				g.drawOval(up - increment, sevenTeen + 1, diameter, diameter);
			}
			else
				g.drawLine(up, down, up, sevenTeen);
		
			up = up + gridGap;
		}
		
		if((this.inputSize % 2 ) != 0)
		{
			if(this.invertInputs[middle])
			{
				g.drawLine(up, down, up, seven + 1);
				g.drawOval(up - increment, sevenTeen + 1, diameter, diameter);
			}
			else
				g.drawLine(up, down, up, sevenTeen);
			
			up = up + gridGap;
			
			for(height = middle + 1; height < this.inputSize; height++)
			{
				if(this.invertInputs[height])
				{
					g.drawLine(up, down, up, seven + 1);
					g.drawOval(up - increment, sevenTeen + 1, diameter, diameter);
				}
				else
					g.drawLine(up, down, up, sevenTeen);
				
				up = up + gridGap;
			}
		}
		else
		{
			up = up + gridGap;
			for(height = middle; height < this.inputSize; height++)
			{
				if(this.invertInputs[height])
				{
					g.drawLine(up, down, up, seven + 1);
					g.drawOval(up - increment, sevenTeen + 1, diameter, diameter);
				}
				else
					g.drawLine(up, down, up, sevenTeen);
				
				up = up + gridGap;
			}
		}
	}
	
	protected void paintNormal_180(Graphics g)
	{
		int gridGap = CentralPanel.ACTIVE_GRID.getCurrentGridGap();
		int increment = gridGap / 4;
		int center = this.gridSize.height * gridGap / 2;
		int middle = this.inputSize / 2;
		int diameter = 2 * increment;
		
		g.setColor(this.brush);
		
		int height = 14 * increment;
		int up = 5 * increment;
		int down;
		
		int sevenTeen = 17 * increment;
		int seven = 7 * increment;
		
		if(this.invertOutput)
		{
			g.drawLine(up - 1, center, 0, center);
			g.drawOval(up - 1, center - increment, diameter, diameter);
		}
		else
			g.drawLine(seven, center, 0, center);
		
		g.drawLine(sevenTeen, center + up, height, center + up);
		g.drawLine(sevenTeen, center - up, height, center - up);
		
		Shape old = g.getClip();
		g.setClip(0, center, height, center);
		g.drawOval(up + increment, center - sevenTeen + gridGap, sevenTeen, sevenTeen + increment);
		
		g.setClip(0, 0, height, center);
		g.drawOval(up + increment, center - up, sevenTeen, sevenTeen + increment);
		
		g.setClip(0, center - up, sevenTeen + 1, height - gridGap);
		g.drawOval(sevenTeen - increment, center - seven - increment, seven + increment, sevenTeen - increment);
		
		g.setClip(0, diameter + increment, sevenTeen + 1, this.gridSize.height * gridGap - up - increment + 1);
		
		height = height - diameter;
		
		if(this.inputSize > 3)
		{
			up = center;
			down = center;
			
			while(up > 0)
			{
				up = up - height;
				down = down + height;
				g.drawOval(sevenTeen - increment, up - seven - increment, seven + increment, sevenTeen - increment);
				g.drawLine(sevenTeen, up + seven - diameter, sevenTeen, up + seven);
				g.drawOval(sevenTeen - increment, down - seven - increment, seven + increment, sevenTeen - increment);
				g.drawLine(sevenTeen, down - seven + diameter, sevenTeen, down - seven);
			}
		}
		g.setClip(old);
		
		up = gridGap;
		down = 6 * gridGap - 1;
		seven = sevenTeen + diameter;
		
		for(height = 0; height < middle; height++)
		{
			if(this.invertInputs[this.inputSize - 1 - height])
			{
				g.drawLine(down, up, seven + 1, up);
				g.drawOval(sevenTeen + 1, up - increment, diameter, diameter);
			}
			else
				g.drawLine(down, up, sevenTeen, up);
		
			up = up + gridGap;
		}
		
		if((this.inputSize % 2 ) != 0)
		{
			if(this.invertInputs[this.inputSize - 1 - middle])
			{
				g.drawLine(down, up, seven + 1, up);
				g.drawOval(sevenTeen + 1, up - increment, diameter, diameter);
			}
			else
				g.drawLine(down, up, sevenTeen, up);
			
			up = up + gridGap;
			
			for(height = middle + 1; height < this.inputSize; height++)
			{
				if(this.invertInputs[this.inputSize - 1 - height])
				{
					g.drawLine(down, up, seven + 1, up);
					g.drawOval(sevenTeen + 1, up - increment, diameter, diameter);
				}
				else
					g.drawLine(down, up, sevenTeen, up);
				
				up = up + gridGap;
			}
		}
		else
		{
			up = up + gridGap;
			for(height = middle; height < this.inputSize; height++)
			{
				if(this.invertInputs[this.inputSize - 1 - height])
				{
					g.drawLine(down, up, seven + 1, up);
					g.drawOval(sevenTeen + 1, up - increment, diameter, diameter);
				}
				else
					g.drawLine(down, up, sevenTeen, up);
				
				up = up + gridGap;
			}
		}
	}
	
	protected void paintNormal_270(Graphics g)
	{
		int gridGap = CentralPanel.ACTIVE_GRID.getCurrentGridGap();
		int increment = gridGap / 4;
		int center = this.gridSize.width * gridGap / 2;
		int middle = this.inputSize / 2;
		int diameter = 2 * increment;
		
		g.setColor(this.brush);
		
		int height = 17 * increment;
		int up = 10 * increment;
		int down = gridGap * 6;
		
		int seven = 7 * increment;
		int five = 5 * increment;
		
		if(this.invertOutput)
		{
			g.drawLine(center, height + diameter + 1, center, down);
			g.drawOval(center - increment, height + 1, diameter, diameter);
		}
		else
			g.drawLine(center, height, center, down);
		
		g.drawLine(center + five, seven, center + five, up);
		g.drawLine(center - five, seven, center - five, up);
		
		Shape old = g.getClip();
		g.setClip(center, up, center, height);
		g.drawOval(center - height + gridGap, increment, height + increment, height);
		
		g.setClip(0, up, center, height);
		g.drawOval(center - five, increment, height + increment, height);
		
		g.setClip(center - five, seven, up, height);
		g.drawOval(center - seven - increment, 0, height - increment, seven + increment);
		
		g.setClip(diameter + increment, seven, this.gridSize.width * gridGap - gridGap - diameter + 1, height);
		
		if(this.inputSize > 3)
		{
			up = center;
			down = center;
			
			while(up > 0)
			{
				up = up - seven - five;
				down = down + seven + five;
				g.drawOval(up - seven - increment, 0, height - increment, seven + increment);
				g.drawLine(up + five, seven, up + seven, seven);
				g.drawOval(down - seven - increment, 0, height - increment, seven + increment);
				g.drawLine(down - five, seven, down - seven, seven);
			}
		}
		g.setClip(old);
		
		up = gridGap;
		
		for(height = 0; height < middle; height++)
		{
			if(this.invertInputs[this.inputSize - 1 - height])
			{
				g.drawLine(up, 0, up, five - 1);
				g.drawOval(up - increment, five - 1, diameter, diameter);
			}
			else
				g.drawLine(up, 0, up, seven);
		
			up = up + gridGap;
		}
		
		if((this.inputSize % 2 ) != 0)
		{
			if(this.invertInputs[this.inputSize - 1 - middle])
			{
				g.drawLine(up, 0, up, five - 1);
				g.drawOval(up - increment, five - 1, diameter, diameter);
			}
			else
				g.drawLine(up, 0, up, seven);
			
			up = up + gridGap;
			
			for(height = middle + 1; height < this.inputSize; height++)
			{
				if(this.invertInputs[this.inputSize - 1 - height])
				{
					g.drawLine(up, 0, up, five - 1);
					g.drawOval(up - increment, five - 1, diameter, diameter);
				}
				else
					g.drawLine(up, 0, up, seven);
				
				up = up + gridGap;
			}
		}
		else
		{
			up = up + gridGap;
			for(height = middle; height < this.inputSize; height++)
			{
				if(this.invertInputs[this.inputSize - 1 - height])
				{
					g.drawLine(up, 0, up, five - 1);
					g.drawOval(up - increment, five - 1, diameter, diameter);
				}
				else
					g.drawLine(up, 0, up, seven);
				
				up = up + gridGap;
			}
		}
	}
	
	protected void paintFlipped_0(Graphics g)
	{
		int gridGap = CentralPanel.ACTIVE_GRID.getCurrentGridGap();
		int increment = gridGap / 4;
		int center = this.gridSize.height * gridGap / 2;
		int middle = this.inputSize / 2;
		int diameter = 2 * increment;
		
		g.setColor(this.brush);
		
		int height = 17 * increment;
		int up = 10 * increment;
		int down = gridGap * 6;
		
		int seven = 7 * increment;
		int five = 5 * increment;
		
		if(this.invertOutput)
		{
			g.drawLine(height + diameter + 1, center, down, center);
			g.drawOval(height + 1, center - increment, diameter, diameter);
		}
		else
			g.drawLine(height, center, down, center);
		
		g.drawLine(seven, center + five, up, center + five);
		g.drawLine(seven, center - five, up, center - five);
		
		Shape old = g.getClip();
		g.setClip(up, center, height, center);
		g.drawOval(increment, center - height + gridGap, height, height + increment);
		
		g.setClip(up, 0, height, center);
		g.drawOval(increment, center - five, height, height + increment);
		
		g.setClip(seven, center - five, height, up);
		g.drawOval(0, center - seven - increment, seven + increment, height - increment);
		
		g.setClip(seven, diameter + increment, height, this.gridSize.height * gridGap - gridGap - diameter + 1);
		
		if(this.inputSize > 3)
		{
			up = center;
			down = center;
			
			while(up > 0)
			{
				up = up - seven - five;
				down = down + seven + five;
				g.drawOval(0, up - seven - increment, seven + increment, height - increment);
				g.drawLine(seven, up + five, seven, up + seven);
				g.drawOval(0, down - seven - increment, seven + increment, height - increment);
				g.drawLine(seven, down - five, seven, down - seven);
			}
		}
		g.setClip(old);
		
		up = gridGap;
		
		for(height = 0; height < middle; height++)
		{
			if(this.invertInputs[this.inputSize - 1 - height])
			{
				g.drawLine(0, up, five - 1, up);
				g.drawOval(five - 1, up - increment, diameter, diameter);
			}
			else
				g.drawLine(0, up, seven, up);
		
			up = up + gridGap;
		}
		
		if((this.inputSize % 2 ) != 0)
		{
			if(this.invertInputs[this.inputSize - 1 - middle])
			{
				g.drawLine(0, up, five - 1, up);
				g.drawOval(five - 1, up - increment, diameter, diameter);
			}
			else
				g.drawLine(0, up, seven, up);
			
			up = up + gridGap;
			
			for(height = middle + 1; height < this.inputSize; height++)
			{
				if(this.invertInputs[this.inputSize - 1 - height])
				{
					g.drawLine(0, up, five - 1, up);
					g.drawOval(five - 1, up - increment, diameter, diameter);
				}
				else
					g.drawLine(0, up, seven, up);
				
				up = up + gridGap;
			}
		}
		else
		{
			up = up + gridGap;
			for(height = middle; height < this.inputSize; height++)
			{
				if(this.invertInputs[this.inputSize - 1 - height])
				{
					g.drawLine(0, up, five - 1, up);
					g.drawOval(five - 1, up - increment, diameter, diameter);
				}
				else
					g.drawLine(0, up, seven, up);
				
				up = up + gridGap;
			}
		}
	}
	
	protected void paintFlipped_90(Graphics g)
	{
		int gridGap = CentralPanel.ACTIVE_GRID.getCurrentGridGap();
		int increment = gridGap / 4;
		int center = this.gridSize.width * gridGap / 2;
		int middle = this.inputSize / 2;
		int diameter = 2 * increment;
		
		g.setColor(this.brush);
		
		int height = 17 * increment;
		int up = 10 * increment;
		int down = gridGap * 6;
		
		int seven = 7 * increment;
		int five = 5 * increment;
		
		if(this.invertOutput)
		{
			g.drawLine(center, height + diameter + 1, center, down);
			g.drawOval(center - increment, height + 1, diameter, diameter);
		}
		else
			g.drawLine(center, height, center, down);
		
		g.drawLine(center + five, seven, center + five, up);
		g.drawLine(center - five, seven, center - five, up);
		
		Shape old = g.getClip();
		g.setClip(center, up, center, height);
		g.drawOval(center - height + gridGap, increment, height + increment, height);
		
		g.setClip(0, up, center, height);
		g.drawOval(center - five, increment, height + increment, height);
		
		g.setClip(center - five, seven, up, height);
		g.drawOval(center - seven - increment, 0, height - increment, seven + increment);
		
		g.setClip(diameter + increment, seven, this.gridSize.width * gridGap - gridGap - diameter + 1, height);
		
		if(this.inputSize > 3)
		{
			up = center;
			down = center;
			
			while(up > 0)
			{
				up = up - seven - five;
				down = down + seven + five;
				g.drawOval(up - seven - increment, 0, height - increment, seven + increment);
				g.drawLine(up + five, seven, up + seven, seven);
				g.drawOval(down - seven - increment, 0, height - increment, seven + increment);
				g.drawLine(down - five, seven, down - seven, seven);
			}
		}
		g.setClip(old);
		
		up = gridGap;
		
		for(height = 0; height < middle; height++)
		{
			if(this.invertInputs[height])
			{
				g.drawLine(up, 0, up, five - 1);
				g.drawOval(up - increment, five - 1, diameter, diameter);
			}
			else
				g.drawLine(up, 0, up, seven);
		
			up = up + gridGap;
		}
		
		if((this.inputSize % 2 ) != 0)
		{
			if(this.invertInputs[middle])
			{
				g.drawLine(up, 0, up, five - 1);
				g.drawOval(up - increment, five - 1, diameter, diameter);
			}
			else
				g.drawLine(up, 0, up, seven);
			
			up = up + gridGap;
			
			for(height = middle + 1; height < this.inputSize; height++)
			{
				if(this.invertInputs[height])
				{
					g.drawLine(up, 0, up, five - 1);
					g.drawOval(up - increment, five - 1, diameter, diameter);
				}
				else
					g.drawLine(up, 0, up, seven);
				
				up = up + gridGap;
			}
		}
		else
		{
			up = up + gridGap;
			for(height = middle; height < this.inputSize; height++)
			{
				if(this.invertInputs[height])
				{
					g.drawLine(up, 0, up, five - 1);
					g.drawOval(up - increment, five - 1, diameter, diameter);
				}
				else
					g.drawLine(up, 0, up, seven);
				
				up = up + gridGap;
			}
		}
	}
	
	protected void paintFlipped_180(Graphics g)
	{
		int gridGap = CentralPanel.ACTIVE_GRID.getCurrentGridGap();
		int increment = gridGap / 4;
		int center = this.gridSize.height * gridGap / 2;
		int middle = this.inputSize / 2;
		int diameter = 2 * increment;
		
		g.setColor(this.brush);
		
		int height = 14 * increment;
		int up = 5 * increment;
		int down;
		
		int sevenTeen = 17 * increment;
		int seven = 7 * increment;
		
		if(this.invertOutput)
		{
			g.drawLine(up - 1, center, 0, center);
			g.drawOval(up - 1, center - increment, diameter, diameter);
		}
		else
			g.drawLine(seven, center, 0, center);
		
		g.drawLine(sevenTeen, center + up, height, center + up);
		g.drawLine(sevenTeen, center - up, height, center - up);
		
		Shape old = g.getClip();
		g.setClip(0, center, height, center);
		g.drawOval(up + increment, center - sevenTeen + gridGap, sevenTeen, sevenTeen + increment);
		
		g.setClip(0, 0, height, center);
		g.drawOval(up + increment, center - up, sevenTeen, sevenTeen + increment);
		
		g.setClip(0, center - up, sevenTeen + 1, height - gridGap);
		g.drawOval(sevenTeen - increment, center - seven - increment, seven + increment, sevenTeen - increment);
		
		g.setClip(0, diameter + increment, sevenTeen + 1, this.gridSize.height * gridGap - up - increment + 1);
		
		height = height - diameter;
		
		if(this.inputSize > 3)
		{
			up = center;
			down = center;
			
			while(up > 0)
			{
				up = up - height;
				down = down + height;
				g.drawOval(sevenTeen - increment, up - seven - increment, seven + increment, sevenTeen - increment);
				g.drawLine(sevenTeen, up + seven - diameter, sevenTeen, up + seven);
				g.drawOval(sevenTeen - increment, down - seven - increment, seven + increment, sevenTeen - increment);
				g.drawLine(sevenTeen, down - seven + diameter, sevenTeen, down - seven);
			}
		}
		g.setClip(old);
		
		up = gridGap;
		down = 6 * gridGap - 1;
		seven = sevenTeen + diameter;
		
		for(height = 0; height < middle; height++)
		{
			if(this.invertInputs[height])
			{
				g.drawLine(down, up, seven + 1, up);
				g.drawOval(sevenTeen + 1, up - increment, diameter, diameter);
			}
			else
				g.drawLine(down, up, sevenTeen, up);
		
			up = up + gridGap;
		}
		
		if((this.inputSize % 2 ) != 0)
		{
			if(this.invertInputs[middle])
			{
				g.drawLine(down, up, seven + 1, up);
				g.drawOval(sevenTeen + 1, up - increment, diameter, diameter);
			}
			else
				g.drawLine(down, up, sevenTeen, up);
			
			up = up + gridGap;
			
			for(height = middle + 1; height < this.inputSize; height++)
			{
				if(this.invertInputs[height])
				{
					g.drawLine(down, up, seven + 1, up);
					g.drawOval(sevenTeen + 1, up - increment, diameter, diameter);
				}
				else
					g.drawLine(down, up, sevenTeen, up);
				
				up = up + gridGap;
			}
		}
		else
		{
			up = up + gridGap;
			for(height = middle; height < this.inputSize; height++)
			{
				if(this.invertInputs[height])
				{
					g.drawLine(down, up, seven + 1, up);
					g.drawOval(sevenTeen + 1, up - increment, diameter, diameter);
				}
				else
					g.drawLine(down, up, sevenTeen, up);
				
				up = up + gridGap;
			}
		}
	}
	
	protected void paintFlipped_270(Graphics g)
	{
		int gridGap = CentralPanel.ACTIVE_GRID.getCurrentGridGap();
		int increment = gridGap / 4;
		int center = this.gridSize.width * gridGap / 2;
		int middle = this.inputSize / 2;
		int diameter = 2 * increment;
		
		g.setColor(this.brush);
		
		int height = 14 * increment;
		int up = 5 * increment;
		int down;
		
		int sevenTeen = 17 * increment;
		int seven = 7 * increment;
		
		if(this.invertOutput)
		{
			g.drawLine(center, up - 1, center, 0);
			g.drawOval(center - increment, up - 1, diameter, diameter);
		}
		else
			g.drawLine(center, seven, center, 0);
		
		g.drawLine(center + up, sevenTeen, center + up, height);
		g.drawLine(center - up, sevenTeen, center - up, height);
		
		Shape old = g.getClip();
		g.setClip(center, 0, center, height);
		g.drawOval(center - sevenTeen + gridGap, up + increment, sevenTeen + increment, sevenTeen);
		
		g.setClip(0, 0, center, height);
		g.drawOval(center - up, up + increment, sevenTeen + increment, sevenTeen);
		
		g.setClip(center - up, 0, height - gridGap, sevenTeen + 1);
		g.drawOval(center - seven - increment, sevenTeen - increment, sevenTeen - increment, seven + increment);
		
		g.setClip(diameter + increment, 0, this.gridSize.width * gridGap - up - increment + 1, sevenTeen + 1);
		
		height = height - diameter;
		
		if(this.inputSize > 3)
		{
			up = center;
			down = center;
			
			while(up > 0)
			{
				up = up - height;
				down = down + height;
				g.drawOval(up - seven - increment, sevenTeen - increment, sevenTeen - increment, seven + increment);
				g.drawLine(up + seven - diameter, sevenTeen, up + seven, sevenTeen);
				g.drawOval(down - seven - increment, sevenTeen - increment, sevenTeen - increment, seven + increment);
				g.drawLine(down - seven + diameter, sevenTeen, down - seven, sevenTeen);
			}
		}
		g.setClip(old);
		
		up = gridGap;
		down = 6 * gridGap - 1;
		seven = sevenTeen + diameter;
		
		for(height = 0; height < middle; height++)
		{
			if(this.invertInputs[this.inputSize - 1 - height])
			{
				g.drawLine(up, down, up, seven + 1);
				g.drawOval(up - increment, sevenTeen + 1, diameter, diameter);
			}
			else
				g.drawLine(up, down, up, sevenTeen);
		
			up = up + gridGap;
		}
		
		if((this.inputSize % 2 ) != 0)
		{
			if(this.invertInputs[this.inputSize - 1 - middle])
			{
				g.drawLine(up, down, up, seven + 1);
				g.drawOval(up - increment, sevenTeen + 1, diameter, diameter);
			}
			else
				g.drawLine(up, down, up, sevenTeen);
			
			up = up + gridGap;
			
			for(height = middle + 1; height < this.inputSize; height++)
			{
				if(this.invertInputs[this.inputSize - 1 - height])
				{
					g.drawLine(up, down, up, seven + 1);
					g.drawOval(up - increment, sevenTeen + 1, diameter, diameter);
				}
				else
					g.drawLine(up, down, up, sevenTeen);
				
				up = up + gridGap;
			}
		}
		else
		{
			up = up + gridGap;
			for(height = middle; height < this.inputSize; height++)
			{
				if(this.invertInputs[this.inputSize - 1 - height])
				{
					g.drawLine(up, down, up, seven + 1);
					g.drawOval(up - increment, sevenTeen + 1, diameter, diameter);
				}
				else
					g.drawLine(up, down, up, sevenTeen);
				
				up = up + gridGap;
			}
		}
	}
	
	public void writeVHDLEntity(String path)
	{
		String fileName = "gates.vhd";
		File file = new File(path+"\\"+fileName);
		boolean written = false;
		try {
			Scanner scanner = new Scanner(file);
			while(scanner.hasNextLine()){
				String line = scanner.nextLine();
				if(line.contains(getVHDLName())){
					written = true;
				}
			}
			scanner.close();
		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		}
		
		if(!written){
			sim.VHDLExporter.writeLib(path);
			FileWriter writer = null;
			try {
				writer = new FileWriter(path+"\\"+fileName,true);
				if(this.invertOutput)
					writer.write("\nentity NOR_ent_" + this.inputSize + " is\n");
				else
					writer.write("\nentity OR_ent_" + this.inputSize + " is\n");
				writer.write("port( x0: in std_logic;\n");
				for(int x = 1; x < this.inputSize; x++){
					writer.write("x" + x + ": in std_logic;\n");
				}
				writer.write("F: out std_logic);\n");
				if(this.invertOutput){
					writer.write("end NOR_ent_" + this.inputSize +";\n\n");
					writer.write("architecture behav of NOR_ent_" + this.inputSize + " is\n");
				}else{
					writer.write("end OR_ent_" + this.inputSize +";\n\n");
					writer.write("architecture behav of OR_ent_" + this.inputSize + " is\n");
				}
				writer.write("begin\n");
				writer.write("F<=x0");
				for(int x = 1; x < this.inputSize; x++){
					if(this.invertOutput)
						writer.write(" nor x" + x);
					else
						writer.write(" or x" + x);
				}
				writer.write(";\n");
				writer.write("end behav;\n");
				
				writer.close();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
	public String getVHDLName()
	{
		if(this.invertOutput)
			return "NOR_ent_" + this.inputSize;
		else
			return "OR_ent_" + this.inputSize;
	}	
}