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

public class mosfet extends Applet
{
	DevreAlani devreAlani;
	String zeminRenk, onRenk;
	Button kontrolButon = new Button("Kontrol Panelini Göster");
	KontrolDialog kontrol;
	KontrolPaneli kontrolPaneli;
	Panel birlestir = new Panel();
	
	public void init(){
		zeminRenk = getParameter("zeminrenk");
		onRenk = getParameter("onrenk");
		
		if ((zeminRenk == null) ||
			(onRenk == null))
		{
			zeminRenk = "f0f0f0";
			onRenk = "000000";
		}
		
		setBackground(stringToColor(zeminRenk));
		setForeground(stringToColor(onRenk));
		
		setLayout(new FlowLayout(FlowLayout.LEFT));
		devreAlani = new DevreAlani(zeminRenk);
		birlestir.setLayout(new BorderLayout());
		
		GrafikAlani grafikAlani = new GrafikAlani(zeminRenk);
		kontrolPaneli = new KontrolPaneli(grafikAlani);
		kontrolButon.setFont(new Font("Courier",Font.BOLD,12));
		kontrolButon.setBackground(Color.decode("#e0e0e0"));
		kontrolButon.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent olay){
				if(kontrol ==null) {
					kontrol = new KontrolDialog(kontrolPaneli);
					kontrol.addWindowListener(new WindowAdapter(){
						public void windowClosing(WindowEvent olay){
							kontrolButon.setLabel("Kontrol Panelini Göster");
							kontrol.dispose();
							kontrol = null;
						}
					});
					kontrolButon.setLabel("Kontrol Panelini Gizle");
					kontrol.setLocation(100, 100);
					kontrol.show();
					kontrol.pack();
					kontrol.setResizable(false);
				}
				else if(kontrol != null){
					kontrolButon.setLabel("Kontrol Panelini Göster");
					kontrol.dispose();
					kontrol = null;
				}
			}
		});
		birlestir.add(devreAlani,"North");
		birlestir.add(kontrolButon,"South");
		add(birlestir);
		add(grafikAlani);
	}
	
	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{
	
	int mos_gen=40, mos_yuk=50, mosx_fark, mosy_fark=100;
	int genislik, yukseklik;
	boolean aktif=false;
	String renk1=new String("#ff3f00");
	String renk2=new String("#003fff");
	
	Image winBellek;
	Graphics gBellek;
	
	public DevreAlani(String renk){
		setBackground(Color.decode("#"+renk));
		setLayout(new FlowLayout(FlowLayout.LEFT));
		
		addMouseListener(new MouseAdapter(){
			public void mousePressed(MouseEvent olay){
				if(olay.getX()>=50 && olay.getX()<=150 && 
				   olay.getY()<=(300-mosy_fark) && olay.getY()>=(300-mosy_fark-mos_yuk)){
					if(aktif){ 
						aktif=false;
						renk1 = "#ff3f00";
						renk2 = "#003fff";
					}
					else if(!aktif){ 
						aktif = true;
						renk1 = "#003fff";
						renk2 = "#ff3f00";
					}
					repaint();
				}
			}
		});
	}
	
	public void paint(Graphics g){
		genislik = this.getSize().width;
		yukseklik = this.getSize().height;
		
		mosx_fark = (genislik-mos_gen)/2;
		
		winBellek = createImage(genislik,yukseklik);
		gBellek = winBellek.getGraphics();
		
		gBellek.drawString("Renkler :",20,yukseklik-20);
		gBellek.setColor(Color.red);
		gBellek.drawString("[VDD]", 80, yukseklik-20);
		gBellek.setColor(Color.blue);
		gBellek.drawString("[GND]",140,yukseklik-20);
		gBellek.setColor(Color.decode("#ff3f00"));
		gBellek.drawString("[VOH]",200,yukseklik-20);
		gBellek.setColor(Color.decode("#003fff"));
		gBellek.drawString("[VOL]",260,yukseklik-20);
		gBellek.setColor(Color.decode(renk1));
		gBellek.drawLine(mos_gen+mosx_fark,yukseklik-(90-mos_yuk)/2-mos_yuk-mosy_fark,
						 mos_gen+mosx_fark+30,yukseklik-(90-mos_yuk)/2-mos_yuk-mosy_fark);
		gBellek.drawOval(mos_gen+mosx_fark+30,yukseklik-(90-mos_yuk)/2-mos_yuk-mosy_fark-3,6,6);
		gBellek.fillOval(mos_gen+mosx_fark-3,yukseklik-(90-mos_yuk)/2-mos_yuk-mosy_fark-3,6,6);
		
		mosfetCiz(gBellek, mos_gen, mos_yuk, mosx_fark, mosy_fark, false, 1);
		mosfetCiz(gBellek, mos_gen, mos_yuk, mosx_fark, mosy_fark+90, true, 2);
		
		//imza
		gBellek.setFont(new Font("Courier",Font.ITALIC,14));
		gBellek.setColor(Color.red);
		gBellek.drawString("H.G.",0,20);
		g.drawImage(winBellek,0,0,this);
	}
	
	public void mosfetCiz(Graphics gBellek, int mos_gen, int mos_yuk, int mosx_fark, int mosy_fark, boolean direnc, int num){
		
		gBellek.setColor(Color.black);
		gBellek.drawString("G"+Integer.toString(num),mosx_fark-20,yukseklik-mosy_fark-mos_yuk/2-5);
		gBellek.drawString("D"+Integer.toString(num),mosx_fark+mos_gen+5,yukseklik-mosy_fark-mos_yuk-5);
		gBellek.drawString("S"+Integer.toString(num),mosx_fark+mos_gen+5,yukseklik-mosy_fark-5);
		
		if(direnc) gBellek.setColor(Color.red);
		else if(!direnc) gBellek.setColor(Color.decode(renk2));
		gBellek.drawLine(mosx_fark,yukseklik-mosy_fark-(int)(mos_yuk/2),mosx_fark+mos_gen/2-3,
						 yukseklik-mosy_fark-(int)(mos_yuk/2));
		gBellek.drawLine(mosx_fark+mos_gen/2-3,yukseklik-mosy_fark,mosx_fark+mos_gen/2-3,
						 yukseklik-mosy_fark-mos_yuk);
				
		gBellek.setColor(Color.blue);//mosfet ortası
		gBellek.drawLine(mosx_fark+mos_gen/2+3,yukseklik-mosy_fark-(int)(mos_yuk/3)-3,mosx_fark+mos_gen/2+3,yukseklik-mosy_fark-(int)(2*mos_yuk/3)+3);
		gBellek.drawLine(mosx_fark+mos_gen/2+3,yukseklik-mosy_fark-(int)(mos_yuk/2),mosx_fark+mos_gen,yukseklik-mosy_fark-(int)(mos_yuk/2));
				
		gBellek.fillOval(mosx_fark+mos_gen/2+3,yukseklik-mosy_fark-mos_yuk/2-3,6,6);
		
		gBellek.setColor(Color.decode(renk1));
		gBellek.drawLine(mosx_fark+mos_gen,yukseklik-mosy_fark-(int)(mos_yuk/6)+3,mosx_fark+mos_gen,
						 yukseklik-mosy_fark+30);
		gBellek.drawLine(mosx_fark+mos_gen,yukseklik-mosy_fark-(int)(5*mos_yuk/6)-3,mosx_fark+mos_gen,
						 yukseklik-mosy_fark-mos_yuk-20);
		
		
		if(direnc) gBellek.setColor(Color.decode(renk1));
		else if(!direnc) gBellek.setColor(Color.blue);//mosfet altı
		gBellek.drawLine(mosx_fark+mos_gen/2+3,yukseklik-mosy_fark,
						 mosx_fark+mos_gen/2+3,yukseklik-mosy_fark-(int)(mos_yuk/3)+6);
		gBellek.drawLine(mosx_fark+mos_gen/2+3,yukseklik-mosy_fark-(int)(mos_yuk/6)+3,
						 mosx_fark+mos_gen,yukseklik-mosy_fark-(int)(mos_yuk/6)+3);
				
		if(direnc) gBellek.setColor(Color.red);//mosfet üstü
		else if(!direnc) gBellek.setColor(Color.decode(renk1));
		gBellek.drawLine(mosx_fark+mos_gen/2+3,yukseklik-mosy_fark-(int)(5*mos_yuk/6)-3,
						 mosx_fark+mos_gen,yukseklik-mosy_fark-(int)(5*mos_yuk/6)-3);
		gBellek.drawLine(mosx_fark+mos_gen/2+3,yukseklik-mosy_fark-(int)(2*mos_yuk/3)-6,
						 mosx_fark+mos_gen/2+3,yukseklik-mosy_fark-mos_yuk);
		
		if(direnc){
			gBellek.setColor(Color.red);
			gBellek.drawLine(mosx_fark+mos_gen,yukseklik-mosy_fark-(int)(5*mos_yuk/6)-3,mosx_fark+mos_gen,
						 yukseklik-mosy_fark-mos_yuk-40);
			gBellek.drawLine(mosx_fark,yukseklik-mosy_fark-mos_yuk/2,mosx_fark,yukseklik-mosy_fark-mos_yuk-20);
			gBellek.drawLine(mosx_fark,yukseklik-mosy_fark-mos_yuk-20,mosx_fark+mos_gen,yukseklik-mosy_fark-mos_yuk-20);
			gBellek.fillOval(mosx_fark+mos_gen-2,yukseklik-mosy_fark-mos_yuk-22,4,4);
			gBellek.drawOval(mosx_fark+mos_gen-3,yukseklik-mosy_fark-mos_yuk-46,6,6);
			
			gBellek.setColor(Color.blue);
			gBellek.drawLine(mosx_fark+mos_gen/2+3,yukseklik-mosy_fark-(int)(mos_yuk/2),
							 mosx_fark+mos_gen+20,yukseklik-mosy_fark-(int)(mos_yuk/2));
			gBellek.drawLine(mosx_fark+mos_gen+20,yukseklik-mosy_fark-(int)(mos_yuk/2),
							 mosx_fark+mos_gen+20,yukseklik-mosy_fark-(int)(mos_yuk/2)+10);
			gBellek.drawLine(mosx_fark+mos_gen+11,yukseklik-mosy_fark-(int)(mos_yuk/2)+10,
							 mosx_fark+mos_gen+29,yukseklik-mosy_fark-(int)(mos_yuk/2)+10);
			gBellek.drawLine(mosx_fark+mos_gen+14,yukseklik-mosy_fark-(int)(mos_yuk/2)+13,
							 mosx_fark+mos_gen+26,yukseklik-mosy_fark-(int)(mos_yuk/2)+13);
			gBellek.drawLine(mosx_fark+mos_gen+17,yukseklik-mosy_fark-(int)(mos_yuk/2)+17,
							 mosx_fark+mos_gen+23,yukseklik-mosy_fark-(int)(mos_yuk/2)+17);
		}
		
		else if(!direnc){
			gBellek.setColor(Color.blue);
			gBellek.drawLine(mosx_fark+mos_gen,yukseklik-mosy_fark-mos_yuk/2,mosx_fark+mos_gen,yukseklik-mosy_fark+30);
			gBellek.fillOval(mosx_fark+mos_gen-2,yukseklik-mosy_fark-(int)(mos_yuk/6)+1,4,4);
			
			gBellek.drawLine(mosx_fark+mos_gen-9,yukseklik-mosy_fark+30,mosx_fark+mos_gen+9,yukseklik-mosy_fark+30);
			gBellek.drawLine(mosx_fark+mos_gen-6,yukseklik-mosy_fark+33,mosx_fark+mos_gen+6,yukseklik-mosy_fark+33);
			gBellek.drawLine(mosx_fark+mos_gen-3,yukseklik-mosy_fark+36,mosx_fark+mos_gen+3,yukseklik-mosy_fark+36);
			
			gBellek.setColor(Color.decode(renk2));
			gBellek.drawOval(mosx_fark-26,yukseklik-mosy_fark-mos_yuk/2-3,6,6);
			gBellek.drawLine(mosx_fark-20,yukseklik-mosy_fark-mos_yuk/2,mosx_fark,yukseklik-mosy_fark-mos_yuk/2);
			
		}
	}
	
	public void update(Graphics g){
		paint(g);
	}
	public Dimension getPreferredSize(){
		return new Dimension(300,300);
	}
}

class GrafikAlani extends Canvas{
	
	double I_t[] = new double[2500];
	double I, beta1, beta2, artim, xeksen, VDD, VT, A, B, C, VOL;
	int xfark=70, yfark=30, y=25, x=25,akim_max, a=1, m=0, uzunluk;
	int genislik, yukseklik, boyut, VGS;
	
	String baslik = new String("MOSFET Evirici ve Yük Eğrisi");
	Image winBellek;
	Graphics gBellek;
										   
	public GrafikAlani(String renk){
		setBackground(Color.decode("#"+renk));
		akim_max=10;
		VT=2;
		VDD=10;
		VGS=(int)(VDD-VT);
		beta2 = 25E-6;
		beta1 = 25E-5;
		boyut = (int)((VDD-VT)*x);
		artim = (VDD-VT)/boyut;
		xeksen=VT;
		
		A=1+beta1/beta2;
		B=-2*((VDD-VT)+(beta1/beta2)*(VDD-2*VT));
		C=(VDD-VT)*(VDD-VT);
		
		VOL=(-B-Math.sqrt(B*B-4*A*C))/(2*A);
		
		while(xeksen<=VDD){
			I_t[m] = 0.5*beta2*(xeksen-VT)*(xeksen-VT)*10000*y;
			xeksen +=artim;
			m++;
		}
		xeksen=VT;
		m=0;
		
	}
	
	public void grafikGuncelle(int alfa1, int alfa2){
		this.beta1 = alfa1*1E-5;
		this.beta2 = alfa2*1E-6;
		
		A=1+beta1/beta2;
		B=-2*((VDD-VT)+(beta1/beta2)*(VDD-2*VT));
		C=(VDD-VT)*(VDD-VT);
		
		VOL=(-B-Math.sqrt(B*B-4*A*C))/(2*A);
		
		while(xeksen<=VDD){
			I_t[m] = 0.5*beta2*(xeksen-VT)*(xeksen-VT)*10000*y;
			xeksen +=artim;
			m++;
		}
		xeksen=VT;
		m=0;
		
		repaint();
	}
	
	
	public void paint(Graphics g){
		genislik = this.getSize().width;
		yukseklik = this.getSize().height;
		
		winBellek = createImage(genislik,yukseklik);
		gBellek = winBellek.getGraphics();
		
		uzunluk = baslik.length();
		FontMetrics fm = gBellek.getFontMetrics();
		gBellek.setColor(Color.blue);
		gBellek.drawString(baslik,(int)((genislik-fm.stringWidth(baslik))/2),20);
		gBellek.setColor(Color.black);
		//eksenler çiziliyor
		gBellek.drawLine(xfark,yukseklik-yfark,xfark,10);
		gBellek.drawLine(xfark-1,yukseklik-yfark,xfark-1,10);
		gBellek.drawLine(xfark,yukseklik-yfark,genislik-10,yukseklik-yfark);
		gBellek.drawLine(xfark,yukseklik-yfark+1,genislik-10,yukseklik-yfark+1);
		
		//eksenin akım ve gerilim başlıkları yazılıyor
		gBellek.drawString("ID (mA)",xfark+10,12);
		gBellek.drawString("VDS (Volt)",genislik-75,yukseklik-yfark-10);
		
		//düşey cetvel çiziliyor
		for(double i=1;i<=akim_max;i++){
			gBellek.drawLine(xfark-4,yukseklik-(int)i*y-yfark,xfark+3,yukseklik-(int)i*y-yfark);
			gBellek.drawString(Double.toString(i/10),xfark-20,yukseklik-(int)i*y-yfark+5);
		}
		//yatay cetvel çiziliyor
		for(int i=1;i<=12;i++){
			gBellek.drawLine(25*i+xfark,yukseklik-yfark+4,25*i+xfark,yukseklik-yfark-3);
			gBellek.drawString(Integer.toString(i),25*i+xfark-5,yukseklik-yfark+20);
		}
		//oklar çiziliyor
		gBellek.drawLine(xfark-3,15,xfark-1,10);
		gBellek.drawLine(xfark+2,15,xfark,10);
		gBellek.drawLine(genislik-15,yukseklik-yfark-2,genislik-10,yukseklik-yfark);
		gBellek.drawLine(genislik-15,yukseklik-yfark+3,genislik-10,yukseklik-yfark+1);
	
		//yük eğrisi çiziliyor	
		while(a<boyut){
			gBellek.setColor(Color.red);
			gBellek.drawLine((int)(xfark+boyut-a),(int)(yukseklik-yfark-I_t[a-1]),
							 (int)(xfark+boyut-a-1),(int)(yukseklik-yfark-I_t[a]));
	//		gBellek.drawLine((int)(xfark+a+x*VT),(int)(yukseklik-yfark-I_t[a]),
	//						 (int)(xfark+a+1+x*VT),(int)(yukseklik-yfark-I_t[a+1]));
			a++;
		}
		a=1;
		//akım eğrileri çiziliyor	
		gBellek.setColor(Color.black);
		for(int i=0;i<=(int)(VDD-VT);i+=2){
			gBellek.drawLine(xfark+5*i,(int)(yukseklik-yfark-I_t[i*x]),
							 (int)(VDD*x+xfark+x*VT),(int)(yukseklik-yfark-I_t[i*x]));
			gBellek.drawLine(xfark+5*i,(int)(yukseklik-yfark-I_t[i*x]-1),
							 (int)(VDD*x+xfark+x*VT),(int)(yukseklik-yfark-I_t[i*x]-1));
			gBellek.drawString("VGS1 = "+Double.toString(i-VT+2),xfark+5*i,(int)(yukseklik-yfark-I_t[i*x])-5);
		}
		
		//VOL ve VDD çiziliyor VOL tespit ediliyor	
		gBellek.setColor(Color.lightGray);
		gBellek.drawLine(xfark+(int)(x*VOL),yukseklik-yfark,xfark+(int)(x*VOL),yukseklik-yfark-(int)I_t[(int)((VDD-VT-VOL)*x)]);
		gBellek.drawLine(xfark,yukseklik-yfark-(int)I_t[(int)((VDD-VT-VOL)*x)],
						 xfark+(int)(x*VOL),yukseklik-yfark-(int)I_t[(int)((VDD-VT-VOL)*x)]);
		gBellek.setColor(Color.decode("#077F50"));
		gBellek.drawString("VOL ="+Float.toString((float)VOL),xfark+(int)(x*VOL)+5,
						   yukseklik-yfark-(int)I_t[(int)((VDD-VT-VOL)*x)]);
		gBellek.setColor(Color.black);
		gBellek.fillOval(xfark+(int)(x*VOL)-5,yukseklik-yfark-(int)I_t[(int)((VDD-VT-VOL)*x)]-5,10,10);
		
		gBellek.drawString("VDD - VT",xfark+(int)(x*(VDD-VT))+5,yukseklik-yfark-20);
		g.drawImage(winBellek,0,0,this);
	}
	
	public void update(Graphics g){
		paint(g);
	}
	
	public Dimension getPreferredSize(){
		return new Dimension(400,300);
	}
}

class CerceveliPanel extends Panel{
	public CerceveliPanel(){
		setBackground(Color.white);
	}
	public Insets getInsets(){
		return new Insets(0,0,0,0);
	}
	public Dimension getPreferredSize(){
		return new Dimension(200,200);
	}
}

class KontrolPaneli extends Panel{
	Slider slider;
	
	public KontrolPaneli(GrafikAlani grafikAlani){
		slider = new Slider(grafikAlani);
		setBackground(Color.white);
		setLayout(new FlowLayout(FlowLayout.LEFT));
		
		add(slider);
	}
	public Insets getInsets(){
		return new Insets(0,0,0,0);
	}
	
	public Dimension getPreferredSize(){
		return new Dimension(210,210);
	}
}

class Slider extends CerceveliPanel implements AdjustmentListener{
	int beta1, beta2;
	Scrollbar beta1S, beta2S;
	Label beta1B, beta2B;
	Label beta1E, beta2E;
	Panel panel1, panel2;
	Panel butun1, butun2;
	
	private GrafikAlani grafikAlani;
	
	public Slider(GrafikAlani grafikAlani){
		this.grafikAlani = grafikAlani;
		
		beta1S = new Scrollbar(Scrollbar.HORIZONTAL,10,1,25,31);
		beta2S = new Scrollbar(Scrollbar.HORIZONTAL,10,1,25,31);
		
		beta1B = new Label("Beta1 = ");
		beta2B = new Label("Beta2 = ");
	
		beta1E = new Label("25.0E-5     ");
		beta2E = new Label("25.0E-6     ");
		
		beta1B.setFont(new Font("Courier",Font.BOLD,12));
		beta2B.setFont(new Font("Courier",Font.BOLD,12));
		
		beta1E.setFont(new Font("Courier",Font.BOLD,12));
		beta2E.setFont(new Font("Courier",Font.BOLD,12));
		
		panel1 = new Panel();
		panel2 = new Panel();
		
		butun1 = new Panel();
		butun2 = new Panel();
		
		panel1.setLayout(new BorderLayout());
		panel1.add(beta1B,"West");
		panel1.add(beta1E,"East");
		
		panel2.setLayout(new BorderLayout());
		panel2.add(beta2B,"West");
		panel2.add(beta2E,"East");
		
		
		butun1.setLayout(new GridLayout(2,1));
		butun1.add(panel1);
		butun1.add(beta1S);
		
		butun2.setLayout(new GridLayout(2,1));
		butun2.add(panel2);
		butun2.add(beta2S);
		
		
		setLayout(new GridLayout(4,1));
		add(butun1);
		add(butun2);
		
		beta1S.addAdjustmentListener(this);
		beta2S.addAdjustmentListener(this);
		
		beta1S.setBlockIncrement(1);
		beta1S.setUnitIncrement(1);
		beta1S.setMaximum(31);
		beta1S.setMinimum(10);
	
		beta2S.setBlockIncrement(1);
		beta2S.setUnitIncrement(1);
		beta2S.setMaximum(31);
		beta2S.setMinimum(10);
	}
	
	public void adjustmentValueChanged(AdjustmentEvent olay){
		beta1 = beta1S.getValue();
		beta1E.setText(Double.toString(beta1)+"E-5");
		beta2 = beta2S.getValue();
		beta2E.setText(Double.toString(beta2)+"E-6");
		grafikAlani.grafikGuncelle(beta1, beta2);
	}
}

class KontrolDialog extends Frame {
	private KontrolPaneli kontrolPaneli;
	
	public KontrolDialog(KontrolPaneli kontrolPaneli) {
	//	super(getFrame(kontrolPaneli), "Kontrol Paneli");
		setTitle("Kontrol Paneli");
		this.kontrolPaneli=kontrolPaneli;
		setLayout(new BorderLayout());
		add(kontrolPaneli,"Center");
	}
	static Frame getFrame(Component c) {
		Frame     frame = null;

        while((c = c.getParent()) != null) {
            if(c instanceof Frame)
                frame = (Frame)c;
        }
        return frame;
    }
}