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

//Author:H.Hakan GENÇ - 2001-2002 - Turkiye
//GSM: +905052610452, E-mail:hasanhakangenc@hotmail.com

public class Transistor extends Applet
{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	KontrolPaneli kontrolPaneli;
	Button kontrolButon = new Button("Kontrol Panelini Göster");
	KontrolDialog kontrol;
	Panel buton = new Panel();
	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));
		
		setLayout(new BorderLayout(10,10));
		CizimAlani cizimAlani = new CizimAlani(zeminRenk);
		kontrolPaneli = new KontrolPaneli(cizimAlani);
		
		kontrolButon.setFont(new Font("Courier",Font.BOLD,14));
		kontrolButon.setBackground(Color.decode("#ffffd0"));
		kontrolButon.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent olay){
				Point konum = Transistor.this.getLocationOnScreen();
				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;
							showStatus("Kontrol Paneli Kapatıldı");
						}
					});
					kontrolButon.setLabel("Kontrol Butonunu Gizle");
					kontrol.setLocation(konum.x + 402, konum.y);
					kontrol.show();
					kontrol.pack();
					kontrol.setResizable(false);
					showStatus("Kontrol Paneli Açıldı");	
				}
				else if(kontrol != null){
					kontrolButon.setLabel("Kontrol Panelini Göster");
					kontrol.dispose();
					kontrol=null;
				}
			}
		});
		buton.setLayout(new FlowLayout(FlowLayout.CENTER));
		buton.add(kontrolButon);
		add(cizimAlani,"Center");
		add(buton,"South");
		//	add(kontrolPaneli,"Center");
	}
	
	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 CizimAlani extends Canvas{
	
	Image winBellek;
	Graphics gBellek;
	
	String baslik1 = "saturasyon bölgesi";
	String baslik2 = "aktif bölge       ";
	String baslik3 = "kesim bölgesi     ";
	String gecici = "";
	String renk;	
	DecimalFormat df = new DecimalFormat("0.00");
	final int early_voltage = -200;//akım eğrilerini çizdirmek için gerekli,negatif gerilim. eksenin solunda kalan değer.
	final double VBE = 0.7;
	double RC, yuk_akim, IB, IC, VCE, Q_y, Q_x;
	int VCC, RB, beta;
	int b1, b2, b3, b4, b5, b6, b7, b;		// baz akımları (uA cinsinden)
	double e1, e2, e3, e4, e5, e6, e7;	//çizdirilecek olan 5 adet Ic akım eğrisinin eğim değerleri
	int x11, x12;						//ilk akım eğrisinin başlangıç ve son yatay eksen voltaj değerleri
	int x21, x22;						//ikinci akım eğrisinin başlangıç ve son yatay eksen voltaj değerleri
	int x31, x32;						//üçüncü akım eğrisinin başlangıç ve son yatay eksen voltaj değerleri
	int x41, x42;						//dördüncü akım eğrisinin başlangıç ve son yatay eksen voltaj değerleri
	int x51, x52;						//beşinci akım eğrisinin başlangıç ve son yatay eksen voltaj değerleri
	int x61, x62;						//beşinci akım eğrisinin başlangıç ve son yatay eksen voltaj değerleri
	int x71, x72;						//beşinci akım eğrisinin başlangıç ve son yatay eksen voltaj değerleri
	
	int y11, y12;
	int y21, y22;
	int y31, y32;
	int y41, y42;
	int y51, y52;
	int y61, y62;
	int y71, y72;
	int y;
	
	int genislik, yukseklik;
	int xfark=70, yfark=30;
	
	public CizimAlani(String renk){
		setBackground(Color.decode("#"+renk));
		renk = "#000000";
		VCC = 0;
		RB = 350;
		RC = 2;
		beta = 75;
		if(VCC <= VBE){
			yuk_akim = 0;
			IB = 0;
			IC = 0;
			VCE = 0;
			Q_y = 0;
			Q_x = 0;
			
		}
		else if(VCC > VBE){
			yuk_akim = (VCC/RC)*25;
			IB = (VCC - VBE)/RB;
			IC = beta*IB;
			VCE = VCC - IC*RC;
			Q_y = (-VCE/RC + VCC/RC)*25;
			Q_x = VCE*10;
		}
		
		b1=10;b2=20;b3=30;b4=40;b5=50;b6=60;b7=70;
		b=10;
		
		x11 = x21 = x31 = x41 = x51 = x61 = x71 = 1;
		x12 = x22 = x32 = x42 = x52 = x62 = x72 = 50;
		y11 = b1*beta/40;
		y21 = b2*beta/40;
		y31 = b3*beta/40;
		y41 = b4*beta/40;
		y51 = b5*beta/40;
		y61 = b6*beta/40;
		y71 = b7*beta/40;
		y = b*100/40;
		
		e1 = ((double)y11/(x11-early_voltage));
		e2 = ((double)y21/(x21-early_voltage));
		e3 = ((double)y31/(x31-early_voltage));
		e4 = ((double)y41/(x41-early_voltage));
		e5 = ((double)y51/(x51-early_voltage));
		e6 = ((double)y61/(x61-early_voltage));
		e7 = ((double)y71/(x71-early_voltage));
		
	}
	public void cizimAlaniGuncelle(int RB, double RC, int beta, int VCC){
		this.RB = RB;
		this.RC = RC;
		this.beta = beta;
		this.VCC = VCC;
		
		if(VCC <= VBE){
			yuk_akim = 0;
			IB = 0;
			IC = 0;
			VCE = 0;
			Q_y = 0;
			Q_x = 0;
			
		}
		else if(VCC > VBE){
			yuk_akim = (VCC/RC);
			IB = (VCC - VBE)/RB;
			IC = beta*IB;
			VCE = VCC - IC*RC;
			Q_y = (-VCE/RC + VCC/RC)*25;
			Q_x = VCE*10;
		}
		
		y11 = b1*beta/40;
		y21 = b2*beta/40;
		y31 = b3*beta/40;
		y41 = b4*beta/40;
		y51 = b5*beta/40;
		y61 = b6*beta/40;
		y71 = b7*beta/40;
		
		e1 = ((double)y11/(x11-early_voltage));
		e2 = ((double)y21/(x21-early_voltage));
		e3 = ((double)y31/(x31-early_voltage));
		e4 = ((double)y41/(x41-early_voltage));
		e5 = ((double)y51/(x51-early_voltage));
		e6 = ((double)y61/(x61-early_voltage));
		e7 = ((double)y71/(x71-early_voltage));
		repaint();
	}
	public void paint(Graphics g){
		genislik = this.getSize().width;
		yukseklik = this.getSize().height;
		
		winBellek = createImage(genislik,yukseklik);
		gBellek = winBellek.getGraphics();
		
		gBellek.setFont(new Font("TimesRoman",Font.PLAIN,12));
		//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("Ic (mA)",xfark+10,12);
		gBellek.drawString("VCE (Volt)",genislik-75,yukseklik-yfark-10);
		
		//düşey cetvel çiziliyor
		for(int i=1;i<=7;i++){
			gBellek.drawLine(xfark-4,yukseklik-i*y-yfark,xfark+3,yukseklik-i*y-yfark);
			gBellek.drawString(Integer.toString(i),xfark-20,yukseklik-i*y-yfark+5);
		}
		//yatay cetvel çiziliyor
		for(int i=1;i<=5;i++){
			gBellek.drawLine(50*i+xfark,yukseklik-yfark+4,50*i+xfark,yukseklik-yfark-3);
			gBellek.drawString(Integer.toString(5*i),50*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);
		
		//yuk eğrisi çiziliyor
		gBellek.setColor(Color.decode("#077F50"));
		gBellek.drawLine(xfark,yukseklik-(int)(yuk_akim*25)-yfark,VCC*10+xfark,yukseklik-yfark);
		gBellek.drawLine(xfark,yukseklik-(int)(yuk_akim*25)-yfark+1,VCC*10+xfark-1,yukseklik-yfark);
		gBellek.setColor(Color.gray);
		gBellek.drawLine(xfark,yukseklik-(int)(yuk_akim*25)-yfark,xfark-30,yukseklik-(int)(yuk_akim*25)-yfark);
		gBellek.drawString("VCC/RC",xfark-70,yukseklik-(int)(yuk_akim*25)-yfark);
		gBellek.drawString(Float.toString((float)(VCC/RC)),xfark-70,yukseklik-(int)(yuk_akim*25)-yfark+20);
		gBellek.drawLine(VCC*10+xfark,yukseklik-yfark,VCC*10+xfark,yukseklik-yfark+30);
		gBellek.drawString("VCC="+Integer.toString(VCC),VCC*10+xfark,yukseklik-yfark+30);
		
		//çalışma durumu uyarısı
		gBellek.drawString("Operation = ",125,20);
		gBellek.setFont(new Font("Courier",Font.BOLD,12));
		if(IC<=0.2 || VCE*10 == VCC){
			gBellek.setColor(Color.red);
			gBellek.drawString("Cut-off Mode",225,20);
		}
		else if(IC >= yuk_akim || VCE*10 <= x11*5){
			gBellek.setColor(Color.red);
			renk = "#ff0000";
			gBellek.drawString("Saturated Mode",225,20);
		}
		else{
			gBellek.setColor(Color.decode("#077F50"));
			gBellek.drawString("Active Mode",225,20);
		}
		
		gBellek.setFont(new Font("TimesRoman",Font.PLAIN,12));
		//q noktası çiziliyor
		if((IC < yuk_akim && IC > 0.1 )&& VCE > 0){
			if(VCE*10 > x11*5) renk = "#000000";
			gBellek.setColor(Color.decode(renk));
			gBellek.fillOval(xfark+(int)Q_x-3,yukseklik-yfark-(int)Q_y-3,6,6);
			gBellek.setColor(Color.black);
			gBellek.drawString("Q point",xfark+(int)Q_x,yukseklik-(int)Q_y-yfark);
			gBellek.setColor(Color.lightGray);
			gBellek.drawLine(xfark+(int)Q_x,yukseklik-yfark-(int)Q_y,xfark,yukseklik-yfark-(int)Q_y);
			gBellek.drawLine(xfark+(int)Q_x,yukseklik-yfark-(int)Q_y,xfark+(int)Q_x,yukseklik-yfark);
		}
		
		//emiter kuplajlı transistor çıkış eğrileri çizdiriliyor
		gBellek.setColor(Color.blue);
		gBellek.drawLine(x11*5+xfark,yukseklik-y11-yfark,x12*5+xfark,yukseklik-yfark-(int)(5*e1*(x12-x11)));
		gBellek.drawLine(x21*5+xfark,yukseklik-y21-yfark,x22*5+xfark,yukseklik-yfark-(int)(5*e2*(x22-x21)));
		gBellek.drawLine(x31*5+xfark,yukseklik-y31-yfark,x32*5+xfark-10,yukseklik-yfark-(int)(5*e3*(x32-x31)));
		gBellek.drawLine(x41*5+xfark,yukseklik-y41-yfark,x42*5+xfark-20,yukseklik-yfark-(int)(5*e4*(x42-x41)));
		gBellek.drawLine(x51*5+xfark,yukseklik-y51-yfark,x52*5+xfark-35,yukseklik-yfark-(int)(5*e5*(x52-x51)));
		gBellek.drawLine(x61*5+xfark,yukseklik-y61-yfark,x62*5+xfark-55,yukseklik-yfark-(int)(5*e6*(x62-x61)));
		gBellek.drawLine(x71*5+xfark,yukseklik-y71-yfark,x72*5+xfark-75,yukseklik-yfark-(int)(5*e7*(x72-x71)));
		
		// IB değerleri yazdırılıyor
		gBellek.setColor(Color.black);
		gBellek.setFont(new Font("TimesRoman",Font.PLAIN,10));
		for(int i=1;i<=7;i++){
		//	gBellek.drawString("IB = "+Float.toString((float)(1000*(float)i/(float)beta))+"uA",(7-i)*25+xfark+70,yukseklik-i*y11-yfark-10);
			gBellek.drawString("IB = "+df.format(500*i/(150-beta))+"uA",(7-i)*25+xfark+70,yukseklik-i*y11-yfark-10);
		}
		
		//imza
		gBellek.setFont(new Font("Courier",Font.ITALIC,14));
		gBellek.setColor(Color.red);
		gBellek.drawString("H.G.",genislik-50,20);
		
		gBellek.setFont(new Font("TimesRoman",Font.PLAIN,12));
		gBellek.setColor(Color.black);
		
		g.drawImage(winBellek,0,0,this);
	}
	
	public void update(Graphics g){
		paint(g);
	}
	public Dimension getPreferredSize(){
		return new Dimension(400,300);
	}
}

class KontrolPaneli extends Panel{
	Slider slider;
	public KontrolPaneli(CizimAlani cizimAlani){
		slider = new Slider(cizimAlani);
		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 CerceveliPanel extends Panel{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public CerceveliPanel(){
		setBackground(Color.white);
	}
	public Insets getInsets(){
		return new Insets(0,0,0,0);
	}
	public Dimension getPreferredSize(){
		return new Dimension(200,200);
	}
}

class Slider extends CerceveliPanel implements AdjustmentListener{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	int RB, betaInt, VCC;
	double RC;
	Scrollbar baz_direnci, kollektor_direnci, beta, VCCayar;
	Label baz_direnci_baslik, kollektor_direnci_baslik, beta_baslik, VCC_baslik;
	Label baz_direnci_deger, kollektor_direnci_deger, beta_degeri, VCC_degeri;
	Panel panel1, panel2, panel3, panel4;
	Panel butun1, butun2, butun3, butun4;
	private CizimAlani cizimAlani;
	
	public Slider(CizimAlani cizimAlani){
		this.cizimAlani = cizimAlani;
		
		baz_direnci = new Scrollbar(Scrollbar.HORIZONTAL,100,50,350,2050);
		kollektor_direnci = new Scrollbar(Scrollbar.HORIZONTAL,2000,500,2000,6500);
		beta = new Scrollbar(Scrollbar.HORIZONTAL,50,5,75,105);
		VCCayar = new Scrollbar(Scrollbar.HORIZONTAL,0,1,0,13);
		
		baz_direnci_baslik = new Label("RB (kohm)     =");
		kollektor_direnci_baslik = new Label("RC (kohm)     =");
		beta_baslik = new Label("Beta =");
		VCC_baslik = new Label("VCC (V) =");
			
		baz_direnci_deger= new Label("350");
		kollektor_direnci_deger= new Label("2.0");
		beta_degeri = new Label("75");
		VCC_degeri = new Label("0");
		
		baz_direnci_baslik.setFont(new Font("Courier",Font.BOLD,12));
		kollektor_direnci_baslik.setFont(new Font("Courier",Font.BOLD,12));
		beta_baslik.setFont(new Font("Courier",Font.BOLD,12));
		VCC_baslik.setFont(new Font("Courier",Font.BOLD,12));
				
		baz_direnci_deger.setFont(new Font("Courier",Font.BOLD,12));
		kollektor_direnci_deger.setFont(new Font("Courier",Font.BOLD,12));
		beta_degeri.setFont(new Font("Courier",Font.BOLD,12));
		VCC_degeri.setFont(new Font("Courier",Font.BOLD,12));
				
		panel1 = new Panel();
		panel2 = new Panel();
		panel3 = new Panel();
		panel4 = new Panel();
		
		butun1 = new Panel();
		butun2 = new Panel();
		butun3 = new Panel();
		butun4 = new Panel();
		
		panel1.setLayout(new BorderLayout());
		panel1.add(baz_direnci_baslik,"West");
		panel1.add(baz_direnci_deger,"Center");
		
		panel2.setLayout(new BorderLayout());
		panel2.add(kollektor_direnci_baslik,"West");
		panel2.add(kollektor_direnci_deger,"Center");
		
		panel3.setLayout(new BorderLayout());
		panel3.add(beta_baslik,"West");
		panel3.add(beta_degeri,"Center");
		
		panel4.setLayout(new BorderLayout());
		panel4.add(VCC_baslik,"West");
		panel4.add(VCC_degeri,"Center");
		
		butun1.setLayout(new GridLayout(2,1));
		butun1.add(panel1);
		butun1.add(baz_direnci);
		
		butun2.setLayout(new GridLayout(2,1));
		butun2.add(panel2);
		butun2.add(kollektor_direnci);
		
		butun3.setLayout(new GridLayout(2,1));
		butun3.add(panel3);
		butun3.add(beta);
		
		butun4.setLayout(new GridLayout(2,1));
		butun4.add(panel4);
		butun4.add(VCCayar);
		
		
		setLayout(new GridLayout(4,1));
		add(butun1);
		add(butun2);
		add(butun3);
		add(butun4);
		
		baz_direnci.addAdjustmentListener(this);
		kollektor_direnci.addAdjustmentListener(this);
		beta.addAdjustmentListener(this);
		VCCayar.addAdjustmentListener(this);
				
		baz_direnci.setBlockIncrement(50);
		baz_direnci.setUnitIncrement(50);
		baz_direnci.setMaximum(2050);
		baz_direnci.setMinimum(100);
	
		kollektor_direnci.setBlockIncrement(500);
		kollektor_direnci.setUnitIncrement(500);
		kollektor_direnci.setMaximum(6500);
		kollektor_direnci.setMinimum(2000);
		
		beta.setBlockIncrement(5);
		beta.setUnitIncrement(5);
		beta.setMaximum(105);
		beta.setMinimum(50);
		
		VCCayar.setBlockIncrement(1);
		VCCayar.setUnitIncrement(1);
		VCCayar.setMaximum(13);
		VCCayar.setMinimum(0);
	}
	
	public void adjustmentValueChanged(AdjustmentEvent olay){
		RB = baz_direnci.getValue();
		baz_direnci_deger.setText(Integer.toString(RB));
		RC = (double)kollektor_direnci.getValue()/1000;
		kollektor_direnci_deger.setText(Double.toString(RC));
		betaInt = beta.getValue();
		beta_degeri.setText(Integer.toString(betaInt));
		VCC = VCCayar.getValue();
		VCC_degeri.setText(Integer.toString(VCC));
		
		cizimAlani.cizimAlaniGuncelle(RB,RC,betaInt,VCC);
	}
}
class KontrolDialog extends Frame {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private KontrolPaneli kontrolPaneli;
	
	public KontrolDialog(KontrolPaneli kontrolPaneli) {
//		super(getFrame(kontrolPaneli), "Kontrol Paneli");
		setTitle("Control Panel");
		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;
    }
}