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

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

public class ileri_kutuplama extends Applet
{	
	String baslik = new String("Kontrol Panelini Göster");
	String zeminRenk, onRenk;
	KontrolPaneli kontrolPaneli;
	Button kontrolButon = new Button(baslik);
	KontrolDialog kontrol;
	Panel buton = 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 BorderLayout(10,10));
		CizimAlani cizimAlani = new CizimAlani();
		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 = ileri_kutuplama.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 Panelini Gizle");
					kontrol.setLocation(konum.x + 550, 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;
	
	final int kelvin = 273;
	final int ilk_sicaklik = 25;
	final double Is_ilk=2E-13;
	final double boltzman = 1.38E-23;
	final double coulomb = 1.6E-19;
	double isil_gerilim, Is;
	int sicaklik, dizi_boyutu=80;
	double us;
	
	double diyot_gerilim[] = new double[80];
	double diyot_akim[] = new double[80];
	int diyot_gerilim_int[] = new int[80];
	int diyot_akim_int[] = new int[80];
	
	double vd=0;
	
	double sinus[] = new double[360];
	int integerSinus[] = new int[360];
	double sinusGerilim[] = new double[360];
	int integerSinusGerilim[] = new int[360];
	
	int n=2,yukseklik,genislik,referans,sinus_eksen,ac_referans,ac_sinus_eksen;
	int eksen_y=200, eksen_x=50, genlik;	
	double E,R,yuk_akim,yuk1_akim,yuk2_akim,egim,A,pi;
	
	public CizimAlani(){
	//	setBackground(Color.decode("#ffffd0"));
		
		E=2;
		R=500;
		A=0.2;
		sicaklik = 25;
	//	if(sicaklik > 15 && sicaklik <=40) dizi_boyutu = 70;
	//	else if(sicaklik <= 15) dizi_boyutu = 65;
	//	else if(sicaklik>40) dizi_boyutu = 80;
		
		yuk_akim  = -(E/R)*20000;
		yuk1_akim = -((E-A)/R)*20000;
		yuk2_akim = -((E+A)/R)*20000;

		egim    = -yuk_akim/(E*100);
		
		pi = Math.PI;
		integerSinus[0] = 0;
		integerSinusGerilim[0] = 0;
		referans = 300;
		sinus_eksen = 0;
		ac_sinus_eksen=0;
		ac_referans=eksen_y;
		
		us = (sicaklik -ilk_sicaklik)/10;
		Is = Is_ilk*Math.pow(2,us);
		isil_gerilim = boltzman*(kelvin + sicaklik)/coulomb;
	}
	
	public void cizimAlaniGuncelle(int dc_genlik, int ac_genlik, int R, int sicaklik ){
		this.E = (double)dc_genlik/10;
		this.A = (double)ac_genlik/1000;
		this.R = (double)R;
		this.sicaklik = sicaklik;
		
	//	if(sicaklik > 15 && sicaklik <=40) dizi_boyutu = 70;
	//	else if(sicaklik <= 15) dizi_boyutu = 65;
	//	else if(sicaklik>40) dizi_boyutu = 80;
		
		yuk_akim  = -(E/R)*20000;    //yük eğrisinin akım eksenini kestiği noktanın tespiti
		yuk1_akim = -((E-A)/R)*20000;//alt yük eğrisinin akım eksenini kestiği noktanın tespiti
		yuk2_akim = -((E+A)/R)*20000;//üst yük eğrisinin akım eksenini kestiği noktanın tespiti
		
	//	genlik1 = yuk_akim-yuk1_akim;
	//	genlik2 = yuk2_akim-yuk_akim;
		egim    = -yuk_akim/(E*100);//yük eğrisinin eğimi
		vd=0;
		
		us = (sicaklik -ilk_sicaklik)/10;
		Is = Is_ilk*Math.pow(2,us);
		isil_gerilim = boltzman*(kelvin + sicaklik)/coulomb;
		
		repaint();
	}
	
	public void paint(Graphics g){
		yukseklik = this.getSize().height;
		genislik = this.getSize().width;
		
		winBellek = createImage(genislik,yukseklik);
		gBellek = winBellek.getGraphics();
		
		//grafik bilgileri yazılıyor
		gBellek.setColor(Color.decode("#007ff0"));
		gBellek.drawLine(10,yukseklik-120,30,yukseklik-120);
		gBellek.setColor(Color.green);
		gBellek.drawLine(10,yukseklik-100,30,yukseklik-100);
		gBellek.setColor(Color.red);
		gBellek.drawLine(10,yukseklik-80,30,yukseklik-80);
		gBellek.setColor(Color.lightGray);
		gBellek.drawLine(10,yukseklik-60,30,yukseklik-60);
		gBellek.setColor(Color.blue);
		gBellek.drawLine(10,yukseklik-40,30,yukseklik-40);
		gBellek.setColor(Color.black);
		gBellek.drawLine(10,yukseklik-20,30,yukseklik-20);
		
		gBellek.setColor(Color.black);
		gBellek.drawString("AC gerilim",40,yukseklik-120);
		gBellek.drawString("DC yük eğrisi",40,yukseklik-100);
		gBellek.drawString("diyot karakteristik eğrisi",40,yukseklik-80);
		gBellek.drawString("tepe AC yük eğrileri",40,yukseklik-60);
		gBellek.drawString("AC akım i(t) - Asinwt/(R+rd)",40,yukseklik-40);
		gBellek.drawString("DC akım seviyesi (I)",40,yukseklik-20);
		//dikey ve yatay eksenler çiziliyor.
		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,yukseklik-eksen_y+1,eksen_x+515,yukseklik-eksen_y+1);
		gBellek.drawLine(eksen_x,yukseklik-eksen_y+2,eksen_x+515,yukseklik-eksen_y+2);
		
		gBellek.drawLine(eksen_x-4,15,eksen_x-1,10);// dikey ok çiziliyor
		gBellek.drawLine(eksen_x+3,15,eksen_x,10);
		
		// yatay ok çiziliyor
		gBellek.drawLine(eksen_x+510, yukseklik-eksen_y-2, eksen_x+515, yukseklik-eksen_y+1);
		gBellek.drawLine(eksen_x+510, yukseklik-eksen_y+5, eksen_x+515, yukseklik-eksen_y+2);
		
		gBellek.drawString("I (mA)",eksen_x+10,20);
		gBellek.drawString("V (Volt)",500,yukseklik-eksen_y-10);
		
		for(int i=1;i<=10;i++){//akım ekseninde akım cetveli yazdırılıyor.
			gBellek.drawString(Integer.toString(i),eksen_x+10,
							   -(int)(i*20)+yukseklik-eksen_y+5);
			gBellek.drawLine(eksen_x-6,-(int)(i*20)+yukseklik-eksen_y,eksen_x+5,
							 -(int)(i*20)+yukseklik-eksen_y);
		}
		for(double i=0;i<=5;i+=0.5){//gerilim ekseninde gerilim cetveli yazdırılıyor
			gBellek.drawLine((int)(i*100)+eksen_x,yukseklik-eksen_y-4,
							 (int)(i*100)+eksen_x,yukseklik-eksen_y+7);
			gBellek.drawString(Double.toString(i),(int)(i*100)+eksen_x-7,yukseklik-eksen_y+20);
		}
		
		gBellek.setColor(Color.red);
		
		for(int i=0;i<dizi_boyutu;i++){
			if(vd>=0.5) n=1;
			else n=2;
			//diyodun 'ileri-kutuplama' eğrisini çizdirmek için gerekli
			//diyot akımı hesabı yapılıyor
			diyot_akim[i] = -(Is*(Math.exp(vd/(n*isil_gerilim))-1));
			diyot_gerilim[i] = vd*100;
			vd = vd + 0.01;
		}
		vd=0;
		for(int i=0;i<dizi_boyutu;i++){
			diyot_akim_int[i] = (int)(diyot_akim[i]*1000);
			diyot_gerilim_int[i] = (int)diyot_gerilim[i];
		}
		//hesap neticesinde elde edilen değerler kullanılarak
		//ileri kutuplama bölgesi eğrisi çizdiriliyor
		for(int i=0;i<dizi_boyutu-1;i++){
			gBellek.drawLine(diyot_gerilim_int[i]+eksen_x,diyot_akim_int[i]+yukseklik-eksen_y,
							 diyot_gerilim_int[i+1]+eksen_x,diyot_akim_int[i+1]+yukseklik-eksen_y);
		}
		
		for(int i=1;i<360;i++){
			sinus[i] = Math.sin((pi/180)*i);
		}
		for(int i=1;i<360;i++){
			sinusGerilim[i] = Math.sin((pi/180)*i);
			integerSinusGerilim[i] = (int)(sinusGerilim[i]*A*100);
		}
		
		//yük eğrileri çizdiriliyor
		gBellek.setColor(Color.green);
		gBellek.drawLine(eksen_x,(int)yuk_akim+yukseklik-eksen_y,
						 (int)(E*100)+eksen_x,yukseklik-eksen_y);
		gBellek.drawLine((int)(E*100)+eksen_x,yukseklik-eksen_y,
						 (int)(E*100)+eksen_x,yukseklik-10);
		gBellek.setColor(Color.lightGray);
		gBellek.drawLine(eksen_x,(int)yuk1_akim+yukseklik-eksen_y,
						 (int)((E-A)*100)+eksen_x,yukseklik-eksen_y);
		gBellek.drawLine(eksen_x,(int)yuk2_akim+yukseklik-eksen_y,
						 (int)((E+A)*100)+eksen_x,yukseklik-eksen_y);
		gBellek.drawLine((int)((E+A)*100)+eksen_x,yukseklik-eksen_y,
						 (int)((E+A)*100)+eksen_x,yukseklik-10);
		gBellek.drawLine((int)((E-A)*100)+eksen_x,yukseklik-eksen_y,
						 (int)((E-A)*100)+eksen_x,yukseklik-10);
		
		//ac gerilim çizdiriliiyor
		gBellek.setColor(Color.decode("#007ff0"));
		for(int f=1;f<=2;f++){
			for(int a=0;a<360;++a){
				ac_sinus_eksen = (int)a/4;
				gBellek.drawLine(integerSinusGerilim[a]+eksen_x+(int)(E*100),yukseklik+ac_sinus_eksen-ac_referans,
								 integerSinusGerilim[a]+eksen_x+(int)(E*100),yukseklik+ac_sinus_eksen-ac_referans);
			}
			ac_referans = ac_referans - ac_sinus_eksen;
		}  
		ac_referans = eksen_y;
		ac_sinus_eksen = 0;
		
		for(int i=0;i<dizi_boyutu;i++){
			
			//AC tepe değerlerini izleyen yük eğrilerinin kesişim noktaları
			//ve sinusoidal akım dalgasının tepelerini izleyen doğrular çizdiriliyor
			if(egim*i+yuk1_akim <= diyot_akim_int[i] && egim*i+yuk1_akim >= (diyot_akim_int[i+1])-1){
			    gBellek.setColor(Color.orange);
				gBellek.fillOval(i+eksen_x-2,yukseklik+(int)(egim*i+yuk1_akim)-eksen_y-2,5,5);
				gBellek.drawLine(eksen_x+i,yukseklik+(int)(egim*i+yuk1_akim)-eksen_y,eksen_x+450,
								 yukseklik+(int)(egim*i+yuk1_akim)-eksen_y);
			}
			if(egim*i+yuk2_akim <= diyot_akim_int[i] && egim*i+yuk2_akim >= (diyot_akim_int[i+1])-1){
			    gBellek.setColor(Color.orange);
				gBellek.fillOval(i+eksen_x-2,yukseklik+(int)(egim*i+yuk2_akim)-eksen_y-2,5,5);
				gBellek.drawLine(eksen_x+i,yukseklik+(int)(egim*i+yuk2_akim)-eksen_y,eksen_x+450,
								 yukseklik+(int)(egim*i+yuk2_akim)-eksen_y);
			}
			if(egim*i+yuk_akim <= diyot_akim_int[i] && egim*i+yuk_akim >= (diyot_akim_int[i+1])-1){
				gBellek.setColor(Color.black);
				//diyot eğrisi ile yük eğrisinin kesişim noktası belirleniyor
				gBellek.fillOval(i+eksen_x-2,yukseklik+(int)(egim*i+yuk_akim)-eksen_y-2,5,5);
				//Iq akım doğrusu(devrenin dc akımı) çizdiriliyor
				gBellek.drawLine(eksen_x,yukseklik+(int)(egim*i+yuk_akim)-eksen_y,eksen_x+450,
								 yukseklik+(int)(egim*i+yuk_akim)-eksen_y);
				gBellek.drawString("Iq",eksen_x-15,yukseklik+(int)(egim*i+yuk_akim)-eksen_y);
				
				genlik = (int)((-((i+A)/R)*20000)-(-(i/R)*20000))+1;
				//akım sinus dalgası çizdiriliyor
				gBellek.setColor(Color.blue);
				for(int f=1;f<=2;f++){
					for(int a=0;a<360;++a){
						sinus_eksen = (int)a/4;
						gBellek.drawLine(sinus_eksen+referans,(int)(sinus[a]*genlik) + yukseklik+(int)(egim*i+yuk_akim-eksen_y),
										 sinus_eksen+referans,(int)(sinus[a]*genlik)+ yukseklik+(int)(egim*i+yuk_akim)-eksen_y);
					}
					referans = referans + sinus_eksen;
				}  
				referans = 300;
				sinus_eksen = 0;
			}
		}
		
				//imza
		gBellek.setFont(new Font("Courier",Font.ITALIC,14));
		gBellek.setColor(Color.red);
		gBellek.drawString("H.G.",genislik-50,20);
		g.drawImage(winBellek,0,0,this);
	}
	
	public void update(Graphics g){
		paint(g);
	}
	
	public Dimension getPreferredSize(){
		return new Dimension(550,350);
	}
}

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(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 Slider extends CerceveliPanel implements AdjustmentListener{
	int direnc, dc_genlik, ac_genlik, ortam_isisi;
	Scrollbar direncCubugu, dckaynak, ackaynak, sicaklik;
	Label direnc_baslik, dc_baslik, ac_baslik, sicaklik_baslik;
	Label direncEtiketi, dcEtiketi, acEtiketi, sicaklikEtiketi;
	Panel panel1, panel2, panel3, panel4;
	Panel butun1, butun2, butun3, butun4;
	private CizimAlani cizimAlani;
	
	public Slider(CizimAlani cizimAlani){
		this.cizimAlani = cizimAlani;
		
		direncCubugu = new Scrollbar(Scrollbar.HORIZONTAL,500,100,500,1100);
		dckaynak = new Scrollbar(Scrollbar.HORIZONTAL,20,5,20,45);
		ackaynak = new Scrollbar(Scrollbar.HORIZONTAL,200,200,200,1000);
		sicaklik = new Scrollbar(Scrollbar.HORIZONTAL,0,5,25,85);
		
		direnc_baslik = new Label("Direnç (Ohm)     =");
		dc_baslik = new Label("dc Gerilim (V)   =");
		ac_baslik = new Label("ac Gerilim (mV)  =");
		sicaklik_baslik = new Label("Ortam sıcaklığı(C°) =");
	
		direncEtiketi = new Label("500");
		dcEtiketi = new Label("2.0");
		acEtiketi = new Label("200");
		sicaklikEtiketi = new Label("25°");
		
		direnc_baslik.setFont(new Font("Courier",Font.BOLD,12));
		dc_baslik.setFont(new Font("Courier",Font.BOLD,12));
		ac_baslik.setFont(new Font("Courier",Font.BOLD,12));
		sicaklik_baslik.setFont(new Font("Courier",Font.BOLD,12));
		
		direncEtiketi.setFont(new Font("Courier",Font.BOLD,12));
		acEtiketi.setFont(new Font("Courier",Font.BOLD,12));
		dcEtiketi.setFont(new Font("Courier",Font.BOLD,12));
		sicaklikEtiketi.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(direnc_baslik,"West");
		panel1.add(direncEtiketi,"East");
		
		panel2.setLayout(new BorderLayout());
		panel2.add(dc_baslik,"West");
		panel2.add(dcEtiketi,"East");
		
		panel3.setLayout(new BorderLayout());
		panel3.add(ac_baslik,"West");
		panel3.add(acEtiketi,"East");
		
		panel4.setLayout(new BorderLayout());
		panel4.add(sicaklik_baslik,"West");
		panel4.add(sicaklikEtiketi,"East");
		
		butun1.setLayout(new GridLayout(2,1));
		butun1.add(panel1);
		butun1.add(direncCubugu);
		
		butun2.setLayout(new GridLayout(2,1));
		butun2.add(panel2);
		butun2.add(dckaynak);
		
		butun3.setLayout(new GridLayout(2,1));
		butun3.add(panel3);
		butun3.add(ackaynak);
		
		butun4.setLayout(new GridLayout(2,1));
		butun4.add(panel4);
		butun4.add(sicaklik);
		
		setLayout(new GridLayout(4,1));
		add(butun1);
		add(butun2);
		add(butun3);
		add(butun4);
		
		direncCubugu.addAdjustmentListener(this);
		dckaynak.addAdjustmentListener(this);
		ackaynak.addAdjustmentListener(this);
		sicaklik.addAdjustmentListener(this);
		
		direncCubugu.setBlockIncrement(100);
		direncCubugu.setUnitIncrement(100);
		direncCubugu.setMaximum(1100);
		direncCubugu.setMinimum(500);
	
		dckaynak.setBlockIncrement(5);
		dckaynak.setUnitIncrement(5);
		dckaynak.setMaximum(45);
		dckaynak.setMinimum(20);
	
		ackaynak.setBlockIncrement(200);
		ackaynak.setUnitIncrement(200);
		ackaynak.setMaximum(1000);
		ackaynak.setMinimum(200);
		
		sicaklik.setBlockIncrement(5);
		sicaklik.setUnitIncrement(5);
		sicaklik.setMaximum(85);
		sicaklik.setMinimum(0);
	}
	
	public void adjustmentValueChanged(AdjustmentEvent olay){
		direnc = direncCubugu.getValue();
		direncEtiketi.setText(Integer.toString(direnc));
		dc_genlik = dckaynak.getValue();
		dcEtiketi.setText(Double.toString((double)dc_genlik/10));
		ac_genlik = ackaynak.getValue();
		acEtiketi.setText(Integer.toString(ac_genlik));
		ortam_isisi = sicaklik.getValue();
		sicaklikEtiketi.setText(Integer.toString(ortam_isisi)+"°");
		
		cizimAlani.cizimAlaniGuncelle(dc_genlik,ac_genlik,direnc,ortam_isisi);
	}
}

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;
    }
}
