import java.awt.*;
import java.applet.*;
import java.awt.event.*;

public class cmos extends Applet
{
	String zeminRenk, onRenk;
	public void init(){
		zeminRenk = getParameter("zeminrenk");
		onRenk = getParameter("onrenk");
		
		if ((zeminRenk == null) ||
			(onRenk == null))
		{
			zeminRenk = "f0f0f0";
			onRenk = "000000";
		}
		
		setBackground(stringToColor(zeminRenk));
		setForeground(stringToColor(onRenk));
		
		DevreAlani devreAlani = new DevreAlani(zeminRenk);
		add(devreAlani);
	}
	
	private Color stringToColor(String paramDeger)
	{
		int red;
		int green;
		int blue;

		red = (Integer.decode("0x" + paramDeger.substring(0,2))).intValue();
		green = (Integer.decode("0x" + paramDeger.substring(2,4))).intValue();
		blue = (Integer.decode("0x" + paramDeger.substring(4,6))).intValue();

		return new Color(red,green,blue);
	}
}

class DevreAlani extends Panel{
	double I_t[] = new double[500];
	double Vo_t[] = new double[500];
	
	double I, VOH, VOL, VDD, VT, VIH ,VIL, Vo, Vi, Vth, rdsn, rdsp, artim;
	int xfark=300, yfark=30,uzunluk, ybas, ybas2, x=40;
	int genislik, yukseklik, boyut, kat, cmosx, cmosy, cmosgen, cmosyuk, counter=0;
	
	String baslik = new String("CMOS Evirici");
	String baslik2 = new String("Geçiş Eğrisi");
	
	String birlesim1;
	String birlesim2;
	String renkPS = new String("#ff0000");
	String renkNS = new String("#0000ff");
	String renkDrain = new String("#ff0000");
	String giris = new String("#0000ff");
	
	Image winBellek;
	Graphics gBellek;
	
	public DevreAlani(String renk){
		setBackground(Color.decode("#"+renk));
		setLayout(new FlowLayout(FlowLayout.LEFT));
		
		cmosx=70;
		cmosy=70;
		cmosgen=100;
		cmosyuk=150;
		
		VDD = 5;
		VT = 2;
		
		VIH = (1/8)*(5*VDD - 2*VT);
		VIL = (1/8)*(3*VDD + 2*VT);
		
		Vth = VDD/2;
		
		rdsn = 1/(VDD-VT);
		rdsp = 1/(VDD-VT);
		
		artim=1/((VDD-VT-Vth)*100);
		
		kat = (int)((VDD-VT)*10);
		
		addMouseListener(new MouseAdapter(){
			public void mousePressed(MouseEvent olay){
				if(olay.getX()>=cmosx+cmosgen-80 && olay.getX()<=cmosx+cmosgen-50 && 
				   olay.getY()<=(300-cmosy-cmosyuk/2+20) && olay.getY()>=(300-cmosy-cmosyuk/2-20)){
					if((olay.getModifiers() & InputEvent.BUTTON1_MASK) != 0){
						if(counter<=4)counter++;
						if(counter>4) counter=0;
					}
					else{
						if(counter>=0) counter--;
						if(counter<0) counter=4;
					}
				}
				if(olay.getX()>=xfark && olay.getX()<=xfark+(int)(VT*x) && olay.getY()<=320-(int)(VDD*x)-yfark
				   && olay.getY()>=280-(int)(VDD*x)-yfark) counter = 1;
				
				if(olay.getX()>xfark+(int)(VT*x) && olay.getX()<=xfark+(int)(Vth*x) && olay.getY()<=300-(int)((Vth+VT)*x)-yfark
				   && olay.getY()>=300-(int)(VDD*x)-yfark) counter = 2;
				
				if(olay.getX()>=xfark+(int)(x*Vth)-20 && olay.getX()<=xfark+(int)(x*Vth)+20 && olay.getY()<=300-(int)(x*(Vth-VT)-yfark)
				   && olay.getY()>=300-(int)(x*(Vth+VT))-yfark) counter = 3;
				
				if(olay.getX()>xfark+(int)(x*Vth) && olay.getX()<=xfark+(int)((VDD-VT)*x) && olay.getY()<=300-yfark
				   && olay.getY()>=300-(int)((Vth-VT)*x)-yfark) counter = 4;
				
				if(olay.getX()>xfark+(int)((VDD-VT)*x)&& olay.getX()<=xfark+(int)(VDD*x) && olay.getY()<=300
				   && olay.getY()>=280-yfark) counter = 0;
				
					if(counter==0){
						renkDrain="#ff0000";
						giris="#0000ff";
					}
					else if(counter==1){
						renkDrain="#0000ff";
						giris="#ff0000";
					}
					else if(counter==2){
						renkDrain="#45BFF8";
						giris="#F8470A";
					}
					else if(counter==3){
						renkDrain="#00ff00";
						giris="#F623EF";
					}
					else if(counter==4){
						renkDrain="#F8470A";
						giris="#45BFF8";
					}
					repaint();
			}
		});
	}
	
	public void paint(Graphics g){
		genislik = this.getSize().width;
		yukseklik = this.getSize().height;
		ybas = yukseklik-yfark;
		ybas2 = yukseklik-cmosy;
		
		winBellek = createImage(genislik,yukseklik);
		gBellek = winBellek.getGraphics();
		
		cmosCiz(gBellek, cmosx, cmosy, cmosgen, cmosyuk, false);
		//giriş
		gBellek.setColor(Color.decode(giris));
		gBellek.drawString("Vi",cmosx+cmosgen-100,ybas2-cmosyuk/2-5);
		gBellek.drawLine(cmosx+cmosgen-50,ybas2-cmosyuk/2,cmosx+cmosgen-80,ybas2-cmosyuk/2);
		gBellek.drawOval(cmosx+cmosgen-86,ybas2-cmosyuk/2-3,6,6);
		gBellek.fillOval(cmosx+cmosgen-53,ybas2-cmosyuk/2-3,6,6);
		//çıkış
		gBellek.setColor(Color.decode(renkDrain));
		gBellek.drawString("Vo",cmosx+cmosgen+35,ybas2-cmosyuk/2-5);
		gBellek.drawLine(cmosx+cmosgen,ybas2-cmosyuk/2,cmosx+cmosgen+30,ybas2-cmosyuk/2);
		gBellek.drawOval(cmosx+cmosgen+30,ybas2-cmosyuk/2-3,6,6);
		gBellek.fillOval(cmosx+cmosgen-3,ybas2-cmosyuk/2-3,6,6);
		
		uzunluk = baslik.length();
		FontMetrics fm = gBellek.getFontMetrics();
		gBellek.setColor(Color.blue);
		gBellek.drawString(baslik,(int)((genislik-fm.stringWidth(baslik))/2)-100,20);
		gBellek.drawString(baslik2,(int)((genislik-fm.stringWidth(baslik2))/2)+100,20);
		
		gBellek.setColor(Color.black);
		//eksenler çiziliyor
		gBellek.drawLine(xfark,ybas,xfark,30);
		gBellek.drawLine(xfark-1,ybas,xfark-1,30);
		gBellek.drawLine(xfark,ybas,genislik-30,ybas);
		gBellek.drawLine(xfark,ybas+1,genislik-30,ybas+1);
		
		//eksenin akım ve gerilim başlıkları yazılıyor
		gBellek.drawString("Vo (V)",xfark+10,32);
		gBellek.drawString("Vi (V)",genislik-50,ybas-10);
		
		//oklar çiziliyor
		gBellek.drawLine(xfark-3,35,xfark-1,30);
		gBellek.drawLine(xfark+2,35,xfark,30);
		gBellek.drawLine(genislik-35,ybas-2,genislik-30,ybas);
		gBellek.drawLine(genislik-35,ybas+3,genislik-30,ybas+1);
		
		gBellek.setColor(Color.lightGray);
		gBellek.drawLine(xfark+(int)(VT*x),ybas,xfark+(int)(VT*x),ybas-(int)(VDD*x));
		gBellek.drawLine(xfark+(int)(Vth*x),ybas,xfark+(int)(Vth*x),ybas-(int)(VDD*x));
		gBellek.drawLine(xfark,ybas-(int)((Vth+VT)*x),xfark+(int)(Vth*x),ybas-(int)((Vth+VT)*x));
		gBellek.drawLine(xfark,ybas-(int)((Vth-VT)*x),xfark+(int)(Vth*x),ybas-(int)((Vth-VT)*x));
		
		gBellek.setColor(Color.decode(renkPS));
		if(counter==0) gBellek.drawLine(xfark,ybas-(int)(VDD*x)-1,xfark+(int)(VT*x),ybas-(int)(VDD*x)-1);
		gBellek.drawLine(xfark,ybas-(int)(VDD*x),xfark+(int)(VT*x),ybas-(int)(VDD*x));
		gBellek.drawString("VOH = VDD",xfark+10,ybas-(int)(VDD*x)-2);
		gBellek.setColor(Color.decode("#F623EF"));
		if(counter==3)gBellek.drawLine(xfark+(int)(Vth*x)+1,ybas-(int)((VDD/2 + VT)*x),xfark+(int)(Vth*x)+1,ybas-(int)((VDD/2 - VT)*x));
		gBellek.drawLine(xfark+(int)(Vth*x),ybas-(int)((VDD/2 + VT)*x),xfark+(int)(Vth*x),ybas-(int)((VDD/2 - VT)*x));
		gBellek.setColor(Color.decode(renkNS));
		if(counter==1)gBellek.drawLine(xfark+(int)((VDD-VT)*x),ybas-1,xfark+(int)(VDD*x),ybas-1);
		gBellek.drawLine(xfark+(int)((VDD-VT)*x),ybas,xfark+(int)(VDD*x),ybas);
		
		gBellek.setColor(Color.decode("#F8470A"));
		if(counter==4)gBellek.drawArc(xfark+(int)(VT*x)-kat,ybas-(int)(VDD*x),(int)((Vth-VT)*x+kat+1),(int)((Vth-VT)*x+kat+1),0,90);
		gBellek.drawArc(xfark+(int)(VT*x)-kat,ybas-(int)(VDD*x),(int)((Vth-VT)*x+kat),(int)((Vth-VT)*x+kat),0,90);
		gBellek.setColor(Color.decode("#45BFF8"));
		if(counter==2)gBellek.drawArc(xfark+(int)((VDD/2)*x),ybas-(int)((VDD/2-VT)*x)-kat,(int)((Vth-VT)*x)+kat+1,(int)((Vth-VT)*x)+kat+1,180,90);
		gBellek.drawArc(xfark+(int)((VDD/2)*x),ybas-(int)((VDD/2-VT)*x)-kat,(int)((Vth-VT)*x)+kat,(int)((Vth-VT)*x)+kat,180,90);
		
		gBellek.setColor(Color.decode(renkPS));
		gBellek.drawString("[VDD]",50,yukseklik-10);
		gBellek.setColor(Color.decode(renkNS));
		gBellek.drawString("[GND]",100,yukseklik-10);
		gBellek.setColor(Color.decode("#F8470A"));
		gBellek.drawString("[<VDD]",150,yukseklik-10);
		gBellek.setColor(Color.decode("#45BFF8"));
		gBellek.drawString("[>GND]",200,yukseklik-10);
		gBellek.setColor(Color.decode("#F623EF"));
		gBellek.drawString("[floating]",250,yukseklik-10);
		gBellek.setColor(Color.decode("#00ff00"));
		gBellek.drawString("[kısa devre]",300,yukseklik-10);
		
		//imza
		gBellek.setFont(new Font("Courier",Font.ITALIC,14));
		gBellek.setColor(Color.red);
		gBellek.drawString("H.G.",30,20);
		
		g.drawImage(winBellek,0,0,this);
	}
	
	public void cmosCiz(Graphics gBellek, int cmosx, int cmosy, int cmosgen, int cmosyuk, boolean vin){
		gBellek.setColor(Color.black);
		gBellek.drawString("G",cmosx+cmosgen-80,ybas2-cmosyuk/2-5);
		gBellek.drawString("D",cmosx+cmosgen+5,ybas2-cmosyuk/2-5);
		gBellek.drawString("S2",cmosx+cmosgen+5,ybas2-cmosyuk-5);
		gBellek.drawString("S1",cmosx+cmosgen+5,ybas2-5);
		//PMOS Source ucu çiziliyor renkPS değişkeni Drain ucu rengini ifade eder (PMOS için)
		gBellek.setColor(Color.decode(renkPS));
		gBellek.drawString("VDD",cmosx+cmosgen-10,ybas2-cmosyuk-25);
		gBellek.drawLine(cmosx+cmosgen,ybas2-cmosyuk+5,cmosx+cmosgen-20,ybas2-cmosyuk+5);
		gBellek.drawLine(cmosx+cmosgen,ybas2-cmosyuk+5,cmosx+cmosgen,ybas2-cmosyuk-20);
		gBellek.drawLine(cmosx,ybas2-cmosyuk-20,cmosx+2*cmosgen,ybas2-cmosyuk-20);
		gBellek.fillOval(cmosx+cmosgen-3,ybas2-cmosyuk-23,6,6);
		//NMOS Source ucu çiziliyor renkNS değişkeni Drain ucu rengini ifade eder (NMOS için)
		gBellek.setColor(Color.decode(renkNS));
		gBellek.drawLine(cmosx+cmosgen,ybas2-5,cmosx+cmosgen-20,ybas2-5);
		gBellek.drawLine(cmosx+cmosgen,ybas2-5,cmosx+cmosgen,ybas2+20);
		//toprak ucu
		gBellek.drawLine(cmosx+cmosgen-9,ybas2+20,cmosx+cmosgen+9,ybas2+20);
		gBellek.drawLine(cmosx+cmosgen-6,ybas2+23,cmosx+cmosgen+6,ybas2+23);
		gBellek.drawLine(cmosx+cmosgen-3,ybas2+26,cmosx+cmosgen+3,ybas2+26);
		//Drain ucları çiziliyor
		gBellek.setColor(Color.decode(renkDrain));
		gBellek.drawLine(cmosx+cmosgen,ybas2-cmosyuk+25,cmosx+cmosgen-20,ybas2-cmosyuk+25);
		gBellek.drawLine(cmosx+cmosgen,ybas2-25,cmosx+cmosgen-20,ybas2-25);
		gBellek.drawLine(cmosx+cmosgen,ybas2-25,cmosx+cmosgen,ybas2-cmosyuk+25);
		
		//birleşim yüzeyi çiziliyor
		if(renkPS.equals(renkDrain)){
			gBellek.setColor(Color.decode(renkPS));
			gBellek.fillRect(cmosx+cmosgen-23,ybas2-cmosyuk,3,30);
		}
		else{
			gBellek.setColor(Color.black);
			gBellek.drawRect(cmosx+cmosgen-23,ybas2-cmosyuk,3,30);
		}
		
		if(renkNS.equals(renkDrain)){
			gBellek.setColor(Color.decode(renkNS));
			gBellek.fillRect(cmosx+cmosgen-23,ybas2-30,3,30);
		}
		else{
			gBellek.setColor(Color.black);
			gBellek.drawRect(cmosx+cmosgen-23,ybas2-30,3,30);
		}
		
		//VGS uçları çiziliyor
		gBellek.setColor(Color.decode(giris));
		gBellek.drawLine(cmosx+cmosgen-28,ybas2-cmosyuk+10,cmosx+cmosgen-28,ybas2-cmosyuk+20);
		gBellek.drawLine(cmosx+cmosgen-28,ybas2-20,cmosx+cmosgen-28,ybas2-10);
		gBellek.drawLine(cmosx+cmosgen-28,ybas2-cmosyuk+15,cmosx+cmosgen-50,ybas2-cmosyuk+15);
		gBellek.drawLine(cmosx+cmosgen-28,ybas2-15,cmosx+cmosgen-50,ybas2-15);
		gBellek.drawLine(cmosx+cmosgen-50,ybas2-15,cmosx+cmosgen-50,ybas2-cmosyuk+15);
		
	}
	public void update(Graphics g){
		paint(g);
	}
	public Dimension getPreferredSize(){
		return new Dimension(550,300);
	}
}