//StateVars.java

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import java.applet.*;
import java.awt.font.*;
import java.net.URL;
import java.text.*;
import java.util.Map;
import java.util.Hashtable;
import java.util.jar.Attributes;

public class StateVars{
    public Complex ZL, YL;
    public double Z0, Z0old;
    public Complex Zin, Yin, GammaL;
    public Complex Zin1, Zin2, Gammain1, Gammain2;
    
    private int stepnumber, MaxSteps;
    public int sleeptime;
    public double xpos, lineLength = 0.9;
    public double d1, d2, dmax, dmin; //positions of transformer
    public double Z_transformer1, Z_transformer2;
    public boolean paintY, drawTransformer1, drawTransformer2, AtInput,IsTraceOn, IsBig;
    public boolean LicenseExpired;
    public boolean BigBand1 = false; 
    public boolean BigBand2 = false;

    //new for frequency response
    public double frequency, frequency_minimum, frequency_maximum, delta_frequency, frequency_scan;
    public double F1, F2, G1, G2;
    public int fpos1, fpos2, gpos1, gpos2, scanpoint;
    public double epsilon_r1, epsilon_r2, wavelength1, wavelength2;
    public static final int NPoints = 1001;//Should be an odd number !!!  
					   //Change NumPoints in GraphCanvas and ScrollMax in PhiControls
    
    public double t1, t2;
    public double d1_meters, d2_meters; //locations of transformer
    public double L1, L2, L1_meters, L2_meters; //length of transformer 
    public double Bs1, Bs2; //stub susceptances
    public double x_freq[], F_array[], G_array[];
    
    
    private static final double epsilon0 = 8.8541878176E-12; // Units: F/m
    private static final double mu0 = 1.25663706144E-6; //      Units H/m
    //private static final double light_velocity = Math.sqrt(1.0/(epsilon0*mu0)); //  Units m/s
    private static final double light_velocity = 3.0E8; //  Units m/s
    
    public int this_month, today_week, this_year, this_hour, this_minute, today_month, 
	       today_year,this_zone, saving_time;
	       
    GregorianCalendar Greg = new GregorianCalendar();
    
    public Font ttfFont, sanSerifFont, serifFont, symbolFont, italicFont;
        
    StateVars(){
	ZL = new Complex(100.0,80.0);
	Z0 = 50.0;
	Z0old = 50.0;
	YL = EMF.Inv(ZL);
	Zin = (Complex)ZL.clone();
	Yin = (Complex)YL.clone();
	xpos = 0.0;
	Z_transformer1 = 50.0;
	Z_transformer2 = 50.0;
	
	frequency = 1.0E9; //Hertz
	frequency_minimum = 0.0;
	frequency_maximum = 2.0E9;
	frequency_scan = frequency;
	delta_frequency = (frequency_maximum - frequency_minimum)/(NPoints - 1); 
	epsilon_r1 = 1.0;
	epsilon_r2 = 1.0;
	
	x_freq = new double[NPoints];
	F_array = new double[NPoints];
	G_array = new double[NPoints];
	
	wavelength1 = light_velocity/(Math.sqrt(epsilon_r1) * frequency);
	wavelength2 = light_velocity/(Math.sqrt(epsilon_r2) * frequency);
	
	L1 = 0.25;
	L2 = 0.25;
	
	sleeptime = 100;
	stepnumber = 0;
	MaxSteps = 13;
	paintY = false;
	drawTransformer1 = false;
	drawTransformer2 = false;
	AtInput = false;
	IsTraceOn = true;
	IsBig = false;
	
	this_month = Greg.get(Calendar.MONTH);
	//System.out.println("  This is the month = "+this_month);
	today_week = Greg.get(Calendar.DAY_OF_WEEK);
	//System.out.println("  This is the day_week = "+today_week);
	this_year = Greg.get(Calendar.YEAR);
	this_hour = Greg.get(Calendar.HOUR_OF_DAY);
	//System.out.println("  This is the year = "+this_year);
	this_minute = Greg.get(Calendar.MINUTE);
	//System.out.println("  This is the minute = "+this_minute);
	today_month = Greg.get(Calendar.DAY_OF_MONTH);
	//System.out.println("  This is the day_month = "+today_month);
	today_year = Greg.get(Calendar.DAY_OF_YEAR);
	//System.out.println("  This is the day_year = "+today_year);
	this_zone = Greg.get(Calendar.ZONE_OFFSET);
	//System.out.println("  This is the zone_offset = "+this_zone/3600000);
	saving_time = Greg.get(Calendar.DST_OFFSET);
	//System.out.println("  This is the dst_offset = "+saving_time/3600000);
    }
    
    public void ignition2(){
	
	YL = EMF.Inv(ZL);
	Zin = (Complex)ZL.clone();
	Yin = (Complex)YL.clone();
	GammaL = EMF.computeGamma(ZL, Z0);
	ignition();
	BigBand1 = false; BigBand2 = false;
	scanfrequency();

	
    }
    
    public void ignition(){
    
	frequency_minimum = 0.0;
	frequency_maximum = 2.0*frequency;
	
	
	//frequency_minimum = frequency - 0.5*frequency;
	//frequency_maximum = frequency + 0.5*frequency;
	
	delta_frequency = (frequency_maximum - frequency_minimum)/(NPoints - 1); 
	wavelength1 = light_velocity/(Math.sqrt(epsilon_r1) * frequency);
	wavelength2 = light_velocity/(Math.sqrt(epsilon_r2) * frequency);
       
	
	if(ZL.Real() >= Z0 && ZL.Imaginary() == 0.0){
	    
	    dmax = 0.0;
	    dmin = 0.25;
	    d1 = dmax;
	    d2 = dmin;
	    Zin1 = EMF.computeZinAt(GammaL,Z0,dmax,true);
	    Zin2 = EMF.computeZinAt(GammaL,Z0,dmin,true);
	    Gammain1 = EMF.computeGammaAt(GammaL,dmax);
	    Gammain2 = EMF.computeGammaAt(GammaL,dmin);
	}
	else if(ZL.Real() < Z0 && ZL.Real() != 0.0 && ZL.Imaginary() == 0.0){
	    
	    dmin = 0.0;
	    dmax = 0.25;
	    d1 = dmin;
	    d2 = dmax;
	    
	    Zin1 = EMF.computeZinAt(GammaL,Z0,dmin,true);
	    Zin2 = EMF.computeZinAt(GammaL,Z0,dmax,true);
	    Gammain1 = EMF.computeGammaAt(GammaL,dmin);
	    Gammain2 = EMF.computeGammaAt(GammaL,dmax);
	}
	else if(ZL.Real() != 0.0 && ZL.Imaginary() > 0.0){
	   		
	    dmax=(float)((GammaL.Arg2())/(4.0*Math.PI));
	    dmin=dmax+0.25f;
	    d1 = dmax;
	    d2 = dmin;
		
	    while(dmax>0.5f) dmax=dmax-0.5f;
	    while(dmin>0.5f) dmin=dmin-0.5f; 
	    
	    Zin1 = EMF.computeZinAt(GammaL,Z0,dmax,true);
	    Zin2 = EMF.computeZinAt(GammaL,Z0,dmin,true);
	    Gammain1 = EMF.computeGammaAt(GammaL,dmax);
	    Gammain2 = EMF.computeGammaAt(GammaL,dmin);
	}
	else if(ZL.Real() != 0.0 && ZL.Imaginary() < 0.0){
	    
	    dmax=(float)((GammaL.Arg2())/(4.0*Math.PI))+0.5f;
	    dmin=(float)((GammaL.Arg2())/(4.0*Math.PI))+0.25f;
	    d1 = dmin;
	    d2 = dmax;
	    
	    while(dmax>0.5f) dmax=dmax-0.5f;
	    while(dmin>0.5f) dmin=dmin-0.5f;
		
	    Zin1 = EMF.computeZinAt(GammaL,Z0,dmin,true);
	    Zin2 = EMF.computeZinAt(GammaL,Z0,dmax,true);
	    Gammain1 = EMF.computeGammaAt(GammaL,dmin);
	    Gammain2 = EMF.computeGammaAt(GammaL,dmax);
	}
	else if(ZL.Real() == 0.0){
	    dmax=(float)((GammaL.Arg2())/(4.0*Math.PI))+0.5f;
	    dmin=(float)((GammaL.Arg2())/(4.0*Math.PI))+0.25f;
	    d1 = dmin;
	    d2 = dmax;
	    
	    while(dmax>0.5f) dmax=dmax-0.5f;
	    while(dmin>0.5f) dmin=dmin-0.5f;
		
	    Zin1 = new Complex(0.0,0.0);
	    Zin2 = new Complex(0.0,0.0);
	    Gammain1 = new Complex(0.0,0.0);
	    Gammain2 = new Complex(0.0,0.0);
	}
	
	Z_transformer1 = Math.sqrt(Complex.Real(Zin1)*Z0);
	Z_transformer2 = Math.sqrt(Complex.Real(Zin2)*Z0);
	
	d1_meters = d1 * wavelength1;
	d2_meters = d2 * wavelength1;
	
	L1_meters = L1*wavelength2;
	L2_meters = L2*wavelength2;   
	
    }
    
    
    public void scanfrequency(){
	double wavelen1, wavelen2, d1new, d2new, L1new, L2new;
	Complex Z1, Z2, Zinput1, Zinput2;
	Complex ZL_freq;
	ZL_freq = ZL;
	
	F1 = frequency;
	F2 = frequency;
	fpos1 = NPoints/2;
	fpos2 = NPoints/2;
	
	for(int i=0;i<NPoints;i++){
	    x_freq[i] = frequency_minimum+(double)i*delta_frequency;
	    //System.out.println(i+"     "+x_freq[i]);
	}
		
	for(int i=1;i<NPoints;i++){ // use this if frquency_minimum is zero
	//for(int i=0;i<NPoints;i++){   // use this if frequency_minimum is not zero
	  
	    wavelen1 = light_velocity/(Math.sqrt(epsilon_r1) * x_freq[i]);
	    wavelen2 = light_velocity/(Math.sqrt(epsilon_r2) * x_freq[i]);
	    
	    // Rescale imaginary part of load impedance with frequency
	    if(Complex.Imaginary(ZL) > 0.0){
		// Assume Im(ZL) = jwL
		ZL_freq = new Complex(Complex.Real(ZL),Complex.Imaginary(ZL)*x_freq[i]/frequency);
	    }
	    else if(Complex.Imaginary(ZL) < 0.0){
		//Assume Im(ZL) = -j/(wC)
		ZL_freq = new Complex(Complex.Real(ZL),Complex.Imaginary(ZL)*frequency/x_freq[i]);
	    }
	    else{
	
	    }
	    
	    d1new = d1_meters/wavelen1;
	    d2new = d2_meters/wavelen1;
	    
	    L1new = L1_meters/wavelen2;
	    L2new = L2_meters/wavelen2;
	    
	    Z1 = EMF.computeZinAt(ZL_freq,Z0,d1new,false);
	    Z2 = EMF.computeZinAt(ZL_freq,Z0,d2new,false);
	    
	    Zinput1 = EMF.computeZinAt(Z1,Z_transformer1,L1new,false);
	    Zinput2 = EMF.computeZinAt(Z2,Z_transformer2,L2new,false);
	    
	    F_array[i] = Complex.Magnitude(EMF.computeGamma(Zinput1,Z0,true));
	    G_array[i] = Complex.Magnitude(EMF.computeGamma(Zinput2,Z0,true));
	    
	    //System.out.println(x_freq[i]+"     "+F_array[i]+"    "+d2new+"     "+L2new);//+"       "+G_array[i]);
	    //System.out.println(i+"   "+x_freq[i]+"     "+Complex.Divide(new Complex(1.0,0.0),Yinput1));//+"       "+G_array[i]);
	}
        //System.out.println("  F = "+F_array[0]+"   G = "+G_array[0]);
	F_array[0] = F_array[1];
        G_array[0] = G_array[1];
        
	// Find Bandwidth for |Gamma| = 0.2 or VSWR = 1.5
	
	int Nlim = NPoints/2;
	for(int i=1;i<Nlim;i++){
		F1 = x_freq[Nlim-i];
		fpos1 = Nlim - i;
	    if(F_array[Nlim-i] >= 0.2){
		break;
	    }
	}
	for(int i=1;i<Nlim;i++){
		F2 = x_freq[Nlim+i];
		fpos2 = Nlim + i;
	    if(F_array[Nlim+i] >= 0.2){
		break;
	    }
	}
	for(int i=1;i<Nlim;i++){
		G1 = x_freq[Nlim-i];
		gpos1 = Nlim - i;
	    if(G_array[Nlim-i] >= 0.2){
		break;
	    }
	}
	for(int i=1;i<Nlim;i++){
		G2 = x_freq[Nlim+i];
		gpos2 = Nlim + i;
	    if(G_array[Nlim+i] >= 0.2){
		break;
	    }
	}
	if(F_array[NPoints-1] < 0.2){BigBand1 = true;}
	if(G_array[NPoints-1] < 0.2){BigBand2 = true;}

	//System.out.println(fpos1+"   "+F1+"   "+fpos2+"    "+F2);
	//System.out.println(gpos1+"   "+G1+"   "+gpos2+"    "+G2);
	
    }
    
    
    
    public synchronized void setxpos(double xpos){
	this.xpos = xpos;
    }
    
    public synchronized void setZL(Complex ZL){
	this.ZL = ZL;
    }
    
    public synchronized void setZL(double Zreal, double Zimag){
	ZL.setReal(Zreal);
	ZL.setImaginary(Zimag);
    }
    
    public synchronized void setZin(Complex Zin){
	this.Zin = Zin;
    }
    
    public Complex getZin(){
	 return Zin;
    }
    
    public synchronized void setYin(Complex Yin){
	this.Yin = Yin;
    }
    
    public Complex getYin(){
	return Yin;
    }
    
    public Complex getZL(){
	return ZL;
    }	
    
    public Complex getYL(){
	return YL;
    }
    
    public synchronized void setPaintY(boolean x){
	this.paintY = x;
    }
    
    public boolean getPaintY(){
	return paintY;
    }
    
    public synchronized void setZ0(double Z0){
	this.Z0 = Z0;
    }
    
    public synchronized void setZ0old(double Z0){
	this.Z0old = Z0;
    }
    
    public synchronized void setSleep(int x){
	this.sleeptime = x;
    }
    
    public int getSleep(){
	return sleeptime;
    }
    
    public synchronized void setDrawTransformer1(boolean x){
	this.drawTransformer1 = x;
    }
    
    public boolean getDrawTransformer1(){
	return drawTransformer1;
    }
    
    public synchronized void setDrawTransformer2(boolean x){
	this.drawTransformer2 = x;
    }
    
    public boolean getDrawTransformer2(){
	return drawTransformer2;
    }
    
    public synchronized void setAtInput(boolean x){
	this.AtInput = x;
    }
    
    public boolean getAtInput(){
	return AtInput;
    }
    
    public boolean getTrace(){
	return IsTraceOn;
    }
    
    public synchronized void setTrace(boolean x){
	this.IsTraceOn = x;
    }

    
    public double getZ0(){
	return Z0;
    }
    
    public double getZ0old(){
	return Z0old;
    }
    
    public int getStepNumber(){
	return stepnumber;
    }
    
    public synchronized void setStepNumber(int stepnumber){
	this.stepnumber = stepnumber;
    }
    
    public synchronized void StepIncrement(){
	stepnumber ++;
	if(stepnumber>MaxSteps) stepnumber=MaxSteps;
    }
    
    public synchronized void StepDecrement(){
	stepnumber --;
	if(stepnumber<1) stepnumber = 1;
    }
}
