//X = ((1/alfaR) + (IC/IB)*(1/betaR))/(1 - (IC/IB)*(1/betaF));

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

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

public class bjt_evirici_1 extends Applet implements Runnable{
	
	Image winBellek;
	Graphics gBellek;
	Font font = this.getFont();
	
	int y1=10,y2=50, atom =10, direnc =60, tr_genislik=30, x1 =220, son =250, 
		tr_baz=75, tr_kollektor=110, bas =46, diyot=40;
	int orta = (son-bas)/2, x=x1-atom/2, y=y1, kollektor_x=(x1-atom/2), kollektor_y=y1, 
		baz_x=bas-atom, baz_y=(son-tr_baz-atom/2), emetor_x=(x1-tr_genislik-atom/2), emetor_y=(son-tr_kollektor+40-atom/2);
	boolean akis=true, kollektor=true, baz=true, emetor=false, akisSarj=false;
	
	double VBE=0.7, VCEsat;
	final int betaF=100;
	final double betaR = 2;
	final int VCC=5;
	final double VT = 27E-3;
	int VHI=5;
	double RB=200, RC=5;
	double IB, IC, X;
	double alfaR = betaR/(1+betaR), alfaF = betaF/(1+betaF);
	float Vout;
	
	Thread kosucu, dolum;
	String atomrenk = "#ff0000";
	String voltaj_giris_renk = "#ff0000";
	String zeminRenk, onRenk;

	DirencDialog RBdirenci = new DirencDialog(this, "RB");
	DirencDialog RCdirenci = new DirencDialog(this, "RC");
	
	Sarj sarj;
	Applet aplet = new Applet();
	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.RIGHT));
		winBellek = createImage(this.getSize().width,this.getSize().height);
		gBellek = winBellek.getGraphics();
		
		IB = (VHI-VBE)/RB;
		IC = betaF*IB;
		 
		X = (1 + ((((VCC-0.3)/(IB*RC))+1)/betaR))/(1 - ((VCC-0.3)/(IB*RC))/betaF);
	//	X = ((1/alfaR) + (IC/IB)*(1/betaR))/(1 - (IC/IB)*(1/betaF));
		VCEsat = (VT*(Math.log(X)/Math.log(Math.E)));
		
		Vout = (float)(VCC - IC*RC);		
		
		if(Vout<=0.3) Vout = (float)VCEsat;
		
		addMouseListener(new MouseAdapter(){
			public void mousePressed(MouseEvent olay){
				if(olay.getX()>=(bas-atom) && olay.getX()<=bas 
						 && olay.getY()>=son-tr_baz-atom/2 && olay.getY() <=son-tr_baz+atom/2){
					if(baz){
						kollektor = false;
						baz = false;
						emetor = false;
						kollektor_x = x1-atom/2;
						kollektor_y = y1;
						baz_x = bas;
						baz_y = son-tr_baz-atom/2;
						voltaj_giris_renk="#000000";
						X = (1 + ((((VCC-0.3)/(IB*RC))+1)/betaR))/(1 - ((VCC-0.3)/(IB*RC))/betaF);
					//	X = ((1/alfaR) + (IC/IB)*(1/betaR))/(1 - (IC/IB)*(1/betaF));
						VCEsat = (VT*(Math.log(X)/Math.log(Math.E)));
						Vout = (float)(VCC-IC*RC);
						if(Vout <= 0.3) Vout = (float)VCEsat;
						akisSarj = true;
						sarj.guncelle(Vout,akisSarj);
					}
					else{
						X = (1 + ((((VCC-0.3)/(IB*RC))+1)/betaR))/(1 - ((VCC-0.3)/(IB*RC))/betaF);
					//	X = ((1/alfaR) + (IC/IB)*(1/betaR))/(1 - (IC/IB)*(1/betaF));
						VCEsat = (VT*(Math.log(X)/Math.log(Math.E)));
						Vout = (float)(VCC - IC*RC);
						if(Vout<=0.3) Vout = (float)VCEsat;
						akisSarj = false;
						kollektor = true;
						baz = true;
						sarj.guncelle(Vout,akisSarj);
						voltaj_giris_renk="#ff0000";
					}
					repaint();
				}
				
				if(olay.getX() >= bas+35 && olay.getX() <= bas+95 && olay.getY() >= son-tr_baz-10
				   && olay.getY() <= son-tr_baz+10){
					Point konum = bjt_evirici_1.this.getLocationOnScreen();
						RBdirenci.addWindowListener(new WindowAdapter(){
							public void windowClosing(WindowEvent olay){
								RBdirenci.dispose();
							}
						});
					RBdirenci.setLocation(konum.x+bas+35,konum.y+son-tr_baz-10);
					RBdirenci.show();
					RBdirenci.pack();
					RBdirenci.setResizable(false);
				}
				
				if(olay.getX() >= x1-10 && olay.getX() <= x1+10
					&& olay.getY() >= y2 && olay.getY() <= y2+60)
				{
					Point konum = bjt_evirici_1.this.getLocationOnScreen();
						RCdirenci.addWindowListener(new WindowAdapter(){
							public void windowClosing(WindowEvent olay){
								RCdirenci.dispose();
							}
						});
					RCdirenci.setLocation(konum.x+x1-50,konum.y+y2);
					RCdirenci.show();
					RCdirenci.pack();
					RCdirenci.setResizable(false);
				}
			}
			
		}) ;
		addMouseMotionListener(new MouseMotionListener(){
			public void mouseMoved(MouseEvent olay){
				if((olay.getX()>=(bas-atom) && olay.getX()<=bas 
				   && olay.getY()>=son-tr_baz-atom/2 && olay.getY() <=son-tr_baz+atom/2) ||
				   (olay.getX() >= bas+35 && olay.getX() <= bas+95 && olay.getY() >= son-tr_baz-10
					&& olay.getY() <= son-tr_baz+10) ||
				   (olay.getX() >= x1-10 && olay.getX() <= x1+10
					&& olay.getY() >= y2 && olay.getY() <= y2+60))
				{
					setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
				}
				else setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
			}
			public void mouseDragged(MouseEvent olay){
			}
		});
		sarj = new Sarj(zeminRenk, Vout,akisSarj, dolum);
		add(sarj);

	}
	
	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);
	}
	
	public void start(){
		if (kosucu==null){	
			kosucu = new Thread(this);
			kosucu.start();
		}
	}
	
	public void stop(){
		if(kosucu != null){
			kosucu.stop();
			kosucu = null;
			
		}
	}
	
	public void run(){
		while(akis){
			if(baz && baz_x<x1-tr_genislik-atom/2 && !emetor) baz_x +=2;
			if(baz_x>=x1-tr_genislik-atom/2){ 
				emetor = true;
				baz_x=bas-atom;
			}
			
			if(kollektor && kollektor_y<son-tr_kollektor-atom/2 && !emetor) kollektor_y += 2;
			if(kollektor_y>=son-tr_kollektor-atom/2){
				kollektor_y +=2;
				kollektor_x -=2;
			}
			if((kollektor_x <= x1-tr_genislik) || (kollektor_y >=son-tr_baz-atom/2)){
				emetor = true;
				kollektor_x = x1-atom/2;
				kollektor_y = y1;
			}
			
			if(emetor && emetor_y<son-tr_kollektor+70){
				emetor_x +=2;
				emetor_y +=2;
			}
			if(emetor_x >= x1-atom/2 || emetor_y >= son-tr_kollektor+70){ 
				emetor_x = x1-atom/2;
				emetor_y +=2;
			}
			if(emetor_y >= son+10-atom/2){ 
				emetor = false;
				emetor_x=(x1-tr_genislik-atom/2); 
				emetor_y=(son-tr_kollektor+40-atom/2);
			}
			repaint();
			try{kosucu.sleep(75);}
			catch(InterruptedException e){}
		}
	}
	
	public void direncGuncelle(double direnc_degeri, String direnc){
		if(direnc == "RB") this.RB = direnc_degeri;
		else if(direnc == "RC") this.RC = direnc_degeri;
		
		IB = (VHI-VBE)/RB;
		IC = betaF*IB;
		X = (1 + ((((VCC-0.3)/(IB*RC))+1)/betaR))/(1 - ((VCC-0.3)/(IB*RC))/betaF);
	//	X = ((1/alfaR) + (IC/IB)*(1/betaR))/(1 - (IC/IB)*(1/betaF));
		VCEsat = (VT*(Math.log(X)/Math.log(Math.E)));
		if(baz){
			Vout = (float)(VCC - IC*RC);
			if(Vout<=0.3) Vout = (float)VCEsat;
			sarj.guncelle(Vout,akisSarj);
		}
		repaint();
	}
	public void paint(Graphics g){
		int genislik=getSize().width;
		
		gBellek.setFont(font);
		gBellek.setColor(Color.decode("#"+zeminRenk));
		gBellek.fillRect(0,0,this.getSize().width,this.getSize().height);
		gBellek.setColor(Color.decode("#007846"));
		gBellek.drawString("+VCC",x1,y1);
		gBellek.drawString("G i r i ş",0,son-tr_baz);
		gBellek.setColor(Color.red);
		gBellek.drawOval(x1-atom/2,y1,atom,atom);
		gBellek.setColor(Color.decode(voltaj_giris_renk));
		gBellek.drawOval(bas-atom,son-tr_baz-atom/2,atom,atom);
		
		
		//5V 0V bilgileri yazdırılıyor
		gBellek.setColor(Color.red);
		gBellek.drawOval(20,250,atom,atom);
		gBellek.drawString("5V",18,240);
		gBellek.setColor(Color.black);
		gBellek.drawOval(50,250,atom,atom);
		gBellek.drawString("0V",48,240);
		
		gBellek.setColor(Color.black);
		gBellek.drawLine(x1,y1+10,x1,y2);
		gBellek.drawLine(x1,direnc+y2,x1,son-tr_kollektor);
		gBellek.drawLine(bas,son-tr_baz,bas+35,son-tr_baz);
		gBellek.drawLine(bas+95,son-tr_baz,x1-tr_genislik,son-tr_baz);
		gBellek.drawLine(x1,son-tr_kollektor+70,x1,son+10);
		
		//transistor çiziliyor
		gBellek.drawLine(x1-tr_genislik,son-tr_baz-20,x1-tr_genislik,son-tr_baz+20);
		gBellek.drawLine(x1,son-tr_kollektor,x1-tr_genislik,son-tr_kollektor+30);
		gBellek.drawLine(x1,son-tr_kollektor+70,x1-tr_genislik,son-tr_kollektor+40);
		gBellek.drawLine(x1,son-tr_kollektor+70,x1-5,son-tr_kollektor+60);
		gBellek.drawLine(x1,son-tr_kollektor+70,x1-9,son-tr_kollektor+66);
		
		// RC çiziliyor
		gBellek.drawString("RC = "+Double.toString(RC)+"k",x1+20,y1+70);
		gBellek.drawLine(x1,y2,x1+10,y2+5);
		gBellek.drawLine(x1+10,y2+5,x1-10,y2+15);
		gBellek.drawLine(x1-10,y2+15,x1+10,y2+25);
		gBellek.drawLine(x1+10,y2+25,x1-10,y2+35);
		gBellek.drawLine(x1-10,y2+35,x1+10,y2+45);
		gBellek.drawLine(x1+10,y2+45,x1-10,y2+55);
		gBellek.drawLine(x1-10,y2+55,x1,y2+60);
		
		// RB çiziliyor
		gBellek.drawString("RB = "+Double.toString(RB)+"k",bas+50,son-tr_baz-20);
		gBellek.drawLine(bas+35,son-tr_baz,bas+40,son-tr_baz-10);
		gBellek.drawLine(bas+40,son-tr_baz-10,bas+50,son-tr_baz+10);
		gBellek.drawLine(bas+50,son-tr_baz+10,bas+60,son-tr_baz-10);
		gBellek.drawLine(bas+60,son-tr_baz-10,bas+70,son-tr_baz+10);
		gBellek.drawLine(bas+70,son-tr_baz+10,bas+80,son-tr_baz-10);
		gBellek.drawLine(bas+80,son-tr_baz-10,bas+90,son-tr_baz+10);
		gBellek.drawLine(bas+90,son-tr_baz+10,bas+95,son-tr_baz);
		
		
		//toprak işareti ve çıkış gerilimi ölçeği çiziliyor
		gBellek.drawLine(x1+31,son+10,x1+45,son+10);
		gBellek.drawLine(x1+33,son+15,x1+43,son+15);
		gBellek.drawLine(x1+35,son+20,x1+41,son+20);
		gBellek.drawLine(x1-7,son+10,x1+7,son+10);
		gBellek.drawLine(x1-5,son+15,x1+5,son+15);
		gBellek.drawLine(x1-3,son+20,x1+3,son+20);
		gBellek.drawLine(x1+38,son,x1+38,son-tr_kollektor);
		gBellek.fillOval(x1-atom/2,son-tr_kollektor-atom/2-15,atom,atom);
		gBellek.drawLine(x1,son-tr_kollektor-15,x1+30,son-tr_kollektor-15);
		gBellek.drawOval(x1+30,son-tr_kollektor-atom/2-15,atom,atom);
		
		//çıkış gerilimi ölçeğinin okları çiziliyor
		gBellek.drawLine(x1+38,son-tr_kollektor,x1+35,son-tr_kollektor+5);
		gBellek.drawLine(x1+38,son-tr_kollektor,x1+41,son-tr_kollektor+5);
		gBellek.drawLine(x1+38,son,x1+35,son-5);
		gBellek.drawLine(x1+38,son,x1+41,son-5);
		
		
		gBellek.drawString("Vçıkış = ",x1+40,son-40);
		gBellek.setColor(Color.decode(atomrenk));
		
		if(kollektor && !emetor) gBellek.fillOval(kollektor_x,kollektor_y,atom,atom);
		if(baz && !emetor) gBellek.fillOval(baz_x,baz_y,atom,atom);
		if(emetor) gBellek.fillOval(emetor_x,emetor_y,atom,atom);
		
		//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 update(Graphics g){
		paint(g);
	}
}

class  Sarj extends Canvas implements Runnable{
	float Vout_t[] = new float[250];
	float zaman_eksen[] = new float[250];
	int Vout_t_int[] = new int[250];
	int zaman_eksen_int[] = new int[250];
	float Vout;
	int VCC;
	int yukseklik, genislik;
	int eksen_y = 60, eksen_x = 5, k=0;
	float zaman=0;
	boolean akis=false;
	String renk;
	
	Image winBellek;
	Graphics gBellek;
	Thread dolum;
	
	public Sarj(String renk, float Vout, boolean akis, Thread dolum){
		this.renk = renk;
		setBackground(Color.decode("#"+renk));
		
		this.Vout = Vout;
		this.akis = akis;
		this.dolum = dolum;
		
		VCC = 5;
		Vout_t[0] = -VCC*25;
		
		for(int i=0;i<250;i++){
			Vout_t[i] = -(float)((VCC-(VCC-Vout)*Math.exp(-zaman))*25);
			zaman_eksen[i] = zaman*50;
			zaman += 0.02;
		}
		for(int i=0;i<250;i++){
			Vout_t_int[i] = (int)Vout_t[i];
			zaman_eksen_int[i] = (int)zaman_eksen[i];
		}
	}
	
	public void guncelle(float Vout, boolean akis){ 
		k=0;
		this.akis = akis;
		this.Vout = Vout;
		zaman = 0;
		for(int i=0;i<250;i++){
			Vout_t[i] = -(float)((VCC-(VCC-Vout)*Math.exp(-zaman))*25);
			zaman_eksen[i] = zaman*50;
			zaman += 0.02;
		}
		for(int i=0;i<250;i++){
			Vout_t_int[i] = (int)Vout_t[i];
			zaman_eksen_int[i] = (int)zaman_eksen[i];
		}
		
		if(akis){ 
			dolum = new Thread(this);
			dolum.start();
			repaint();
		}
		else
		{
		//	dolum.stop();
			repaint();
		}
	}
	
	public void run(){
		while(akis){
			if(k == 250) akis = false;
			repaint();
			try{dolum.sleep(50);}
			catch(InterruptedException e){}
			k++;
		}
		k=0;
	}
	public void paint(Graphics g){
		setBackground(Color.decode("#"+renk));
		yukseklik = this.getSize().height;
		genislik = this.getSize().width;
		
		winBellek = createImage(genislik,yukseklik);
		gBellek = winBellek.getGraphics();
		
		gBellek.drawString("Vçıkış (V)",eksen_x+10,15);
		gBellek.drawString("zaman (ns)",genislik-70,yukseklik-eksen_y-10);
		gBellek.setColor(Color.blue);
		gBellek.setFont(new Font("Courier",Font.PLAIN, 12));
		gBellek.drawString("Yük kapasitansı",30,30);
		gBellek.drawString("dolma eğrisi",30,45);
		if(akis){
			gBellek.setColor(Color.blue);
			for(int i=0;i<=k;i++){
				gBellek.drawLine(zaman_eksen_int[i]+eksen_x,yukseklik+Vout_t_int[i]-eksen_y,
					   zaman_eksen_int[i+1]+eksen_x,yukseklik+Vout_t_int[i+1]-eksen_y);
				gBellek.drawLine(zaman_eksen_int[i]+eksen_x+1,yukseklik+Vout_t_int[i]-eksen_y,
					   zaman_eksen_int[i+1]+eksen_x+1,yukseklik+Vout_t_int[i+1]-eksen_y);
			}	
		}
		
		gBellek.setColor(Color.black);
		gBellek.drawString(Float.toString(-Vout_t[k]/25)+"V",0,205);
		
		//eksenler çiziliyor
		gBellek.drawLine(eksen_x,yukseklik-eksen_y,genislik-10,yukseklik-eksen_y);
		gBellek.drawLine(eksen_x,yukseklik-eksen_y+1,genislik-10,yukseklik-eksen_y+1);
		gBellek.drawLine(eksen_x,yukseklik-eksen_y,eksen_x,10);
		gBellek.drawLine(eksen_x+1,yukseklik-eksen_y,eksen_x+1,10);
		gBellek.drawLine(eksen_x-3,15,eksen_x,10);
		gBellek.drawLine(eksen_x+4,15,eksen_x+1,10);
		gBellek.drawLine(genislik-15,yukseklik-eksen_y-3,genislik-10,yukseklik-eksen_y);
		gBellek.drawLine(genislik-15,yukseklik-eksen_y+4,genislik-10,yukseklik-eksen_y+1);
		
		gBellek.setColor(Color.blue);
		gBellek.drawLine(eksen_x,yukseklik-eksen_y,eksen_x,yukseklik-(int)(Vout*25)-eksen_y);
		gBellek.drawLine(eksen_x+1,yukseklik-eksen_y,eksen_x+1,yukseklik-(int)(Vout*25)-eksen_y);

		g.drawImage(winBellek,0,0,this);
	}
	
	public void update(Graphics g){
		paint(g);
	}
	
	public Dimension getPreferredSize(){
		return new Dimension(260,250);
	}	
}