//Trans_State.java
//
/* A Java class for
 * LineImpedance.java
 * Electromagnetic Transmission Line Applet
 * Applet without Smith Chart - Prepared by Umberto Ravaioli 
 * for 6th edition of Fundamentals of Applied Electromagnetics Book
 * May 2009 - All Rights Reserved
 */ 
import java.io.*;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.font.*;
import java.net.URL;
import java.text.*;
import java.util.*;
import java.util.Map;
import java.util.Hashtable;
import java.util.jar.Attributes;

public class Trans_State{
    public double xpos, xpos_meters;
    public double lineLength, lineLength_meters, lineLength_part1, lineLength_part2;
    public double frequency, frequency_maximum, frequency_minimum, f_top, f_bottom;
    public int linecounter1 = 1667, linecounter2 = 820;
    public double epsilon_r,mu_r;
    public double lineZ0;
    //Vin and Iin are voltage and current at the cursor
    public Complex Zin, Yin, Gammain, GammaL, Vin, Iin, VPlus;
    public double VSWR,wavelength;
    public Complex ZL;
    public Complex YL;
    public Generator generator;
    public double Pw[];
    public Stub stub[];
    public double maxR=0.0;
    public double maxX=0.0;
    public double minX=0.0;
    public boolean is_Load_Ztype, Is_Wavelength;
    //Plot Parameters
    Complex Voltage[], Current[], Impedance[], Admittance[];
    Complex RefCoef[], Power[];
    double x[];
    double y1[];
    double y2[];
    public static final int NPoints=1001;
    public boolean IsLoadShort, IsLoadOpen, IsLoadRegular, IsLoadImaginary, IsLengthTooLarge, IsLengthTooSmall;
    public boolean IsLengthTooLarge2, IsLengthTooSmall2, OptionOne, OptionTwo, OptionThree, UseExactLight;
    
    public int NTime, ctime, dtime;
    Complex timeFactor; //jwt is the time factor.
    Complex Gamma0, Gamma1, Gamma2; //Reflection Coefficients at the Stubs
    Complex Y0, Y1, Y2; //Admittances at each stub
    Complex Zinput, Yinput; //Impedance and Admittance at the input terminals 
    int SPos0, SPos1, SPos2; //Integer representation of the position of the three stubs
    int iarray[];
    Complex  VPP[];  // VPP[0] is between load and stub0, VPP[1] is between stub1 and stub0, VPP[2] between stub1 and stub2
    private static final Complex one = new Complex(1.0,0.0);
    private static final double epsilon0 = 8.8541878176E-12; // Units: F/m
    private static final double mu0 = 1.25663706144E-6; //      Units H/m
    
    public double light_velocity;//  Units m/s
    
    public static final double exact_light_velocity = Math.sqrt(1.0/(epsilon0*mu0)); //  Units m/s
    public static final double approximate_light_velocity = 3.0e8; // Units m/s
    public boolean LicenseExpired;
    
    
    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;
  
    public Trans_State(){ //main constructor
	xpos_meters = 0.0;
	frequency=1.0E9;
	frequency_minimum = 0.0;
	frequency_maximum = 200.0e9;
	epsilon_r=1.0;
	mu_r=1.0;
        f_top = 1.0;
        f_bottom = 1.0;
        UseExactLight = false;
        
        if(UseExactLight){
            light_velocity = exact_light_velocity;
        }
        else{
            light_velocity = approximate_light_velocity;
        }
        //System.out.println(light_velocity);
        
        // line initialization
        lineLength = 1.66782;
        lineLength_part1 = 1.667;
        lineLength_part2 = 8.2e-4; 
        linecounter1 = 1667;
        linecounter2 = 820;
      
	lineLength_meters =0.50;
	
        lineZ0 = 50.0;
	ZL = new Complex(25.0,-50.0);
	YL = new Complex(0.008,0.016000000000000004);
	generator = new Generator();
	stub = new Stub[3];
	
	stub[0] = new Stub(0.25,0.0,lineZ0,true,false,false);
	stub[1] = new Stub(0.25,0.5,lineZ0,true,false,false);
	stub[2] = new Stub(0.25,1.0,lineZ0,true,false,false);
	wavelength = light_velocity/(Math.sqrt(epsilon_r*mu_r)*frequency);
	lineLength = lineLength_meters / wavelength;
	xpos = xpos_meters / wavelength;
	
	Pw = new double[3];
	is_Load_Ztype = true;
	Is_Wavelength = false;
        IsLengthTooLarge = false;
        IsLengthTooSmall = false;
	IsLengthTooLarge2 = false;
        IsLengthTooSmall2 = false;
        
        OptionOne = true;
        OptionTwo = false;
        OptionThree = false;
	
	Zin = EMF.computeZinAt(ZL, lineZ0, lineLength, false);
	Yin = EMF.computeYinAt(YL, lineZ0, lineLength, false);
	GammaL = EMF.computeGamma(ZL, lineZ0);
	Gammain = EMF.computeGammaAt(GammaL, lineLength);
	VPlus = EMF.computeVPlus(generator,ZL,lineZ0,lineLength);
	Vin = EMF.computeVat(ZL,lineZ0,VPlus,xpos);
	Iin = EMF.computeIat(ZL,lineZ0,VPlus,xpos);
	VSWR = EMF.computeSWR(GammaL);
	Pw = EMF.PowerDelivered(generator,VPlus,ZL,0.0,lineZ0,lineLength);
	//Plot Parameters Initialization
	Voltage = new Complex[NPoints];
	Current = new Complex[NPoints];
	Impedance = new Complex[NPoints];
	Admittance = new Complex[NPoints];
	RefCoef = new Complex[NPoints];
	Power = new Complex[NPoints];
	x = new double[NPoints];
	y1 = new double[NPoints];
	y2 = new double[NPoints];
	
	NTime=360;
	ctime=0;
	dtime=10;
	timeFactor = new Complex(Math.cos(2.0*Math.PI*ctime/NTime),
				 Math.sin(2.0*Math.PI*ctime/NTime));
	iarray = new int[3];
	VPP = new Complex[3];
	
	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);
        
        IsLoadRegular = true;
        IsLoadShort = false;
        IsLoadOpen = false;
        IsLoadImaginary = false;
	
	ignition();
    }
    
    public synchronized void ignition(){
	
        if(UseExactLight){
            light_velocity = exact_light_velocity;
        }
        else{
            light_velocity = approximate_light_velocity;
        }
        
        wavelength = light_velocity/(Math.sqrt(epsilon_r*mu_r)*frequency);
	if(Is_Wavelength){
	    lineLength_meters = lineLength*wavelength;
	    xpos_meters = xpos*wavelength;
	}
	else{
	    lineLength = lineLength_meters/wavelength;
	    xpos = xpos_meters/wavelength;
	}
                
        f_bottom = light_velocity/(Math.sqrt(epsilon_r*mu_r))*1.0E-4/lineLength_meters;
        
	f_top = light_velocity/(Math.sqrt(epsilon_r*mu_r))*1.0E5/lineLength_meters;
       
        //System.out.println("Fb = "+f_bottom+"  Ft = "+f_top);
                
        if(is_Load_Ztype){
	    
		GammaL = EMF.computeGamma(ZL,lineZ0,true);
		if(Complex.Real(ZL) ==0.0 && Complex.Imaginary(ZL)!=0.0){
		    YL = new Complex(0.0, - 1.0/Complex.Imaginary(ZL));
		}
		else{
		    YL =  EMF.computeYinAt(GammaL,lineZ0,0.0,true);
		}
                
                if(Complex.Real(ZL)==0.0 && Complex.Imaginary(ZL)==0.0){
                    IsLoadShort = true;
                    IsLoadOpen = false;
                    IsLoadImaginary = false;
                    IsLoadRegular = false;
                }
                else if((Complex.Real(ZL)==0.0 && Complex.Imaginary(ZL)<-1.0E130)||Complex.Magnitude(ZL)>1.0E130){
                    IsLoadOpen = true;
                    IsLoadShort = false;
                    IsLoadImaginary = false;
                    IsLoadRegular = false;
                }
                else if(Complex.Real(ZL)==0.0 && Complex.Imaginary(ZL)!=0.0){
                    IsLoadImaginary = true;
                    IsLoadShort = false;
                    IsLoadOpen = false;
                    IsLoadRegular = false;
                }
                else if((Complex.Real(ZL)!=0.0 && Complex.Imaginary(ZL)!=0.0) ||
                    (Complex.Real(ZL)!=0.0 && Complex.Imaginary(ZL)==0.0))
                {
                    IsLoadRegular = true;
                    IsLoadShort = false;
                    IsLoadOpen = false;
                    IsLoadImaginary = false;
                }
	}
	else{
		GammaL = EMF.computeGamma(YL,lineZ0,false);
		if(Complex.Real(YL) ==0.0 && Complex.Imaginary(YL)!=0.0){
		    ZL = new Complex(0.0, - 1.0/Complex.Imaginary(YL));
		}
		else{
		    ZL = EMF.computeZinAt(GammaL,lineZ0,0.0,true);
		}
                
                if(Complex.Real(YL)==0.0 && Complex.Imaginary(YL)==0.0){
                    IsLoadShort = false;
                    IsLoadOpen = true;
                    IsLoadImaginary = false;
                    IsLoadRegular = false;
                }
                else if((Complex.Real(YL)==0.0 && Complex.Imaginary(YL)<-1.0E130)||Complex.Magnitude(YL)>1.0E100 ||
                    Complex.Magnitude(ZL)==0.0){
                    IsLoadOpen = false;
                    IsLoadShort = true;
                    IsLoadImaginary = false;
                    IsLoadRegular = false;
                }
                else if(Complex.Real(YL)==0.0 && Complex.Imaginary(YL)!=0.0){
                    IsLoadImaginary = true;
                    IsLoadShort = false;
                    IsLoadOpen = false;
                    IsLoadRegular = false;
                }
                else if((Complex.Real(YL)!=0.0 && Complex.Imaginary(YL)!=0.0) ||
                    (Complex.Real(YL)!=0.0 && Complex.Imaginary(YL)==0.0))
                {
                    IsLoadRegular = true;
                    IsLoadShort = false;
                    IsLoadOpen = false;
                    IsLoadImaginary = false;
                }
	}
      
	
	if(stub[0].isEnable() || stub[1].isEnable() || stub[2].isEnable()){
	    
	    //Sort the stubs in position
	    sortStubs();
	    
	    //Y0 is admittance of the stub closest to the load
	    Y0 = EMF.computeYinAt(YL,lineZ0,stub[iarray[0]].getPosition(),false);
	    Y0.Add(stub[iarray[0]].getYstub());
	    Gamma0 = EMF.computeGamma(Y0,lineZ0,false);
	    
	    //Y1 is admittance of the second closest stub to the load
	    Y1 = EMF.computeYinAt(Y0,lineZ0,stub[iarray[1]].getPosition()-stub[iarray[0]].getPosition(),false);
	    Y1.Add(stub[iarray[1]].getYstub());
	    Gamma1 = EMF.computeGamma(Y1,lineZ0,false);
	    
	    //Y2 is admittance of the third closest stub to the load
	    Y2 = EMF.computeYinAt(Y1,lineZ0,stub[iarray[2]].getPosition()-stub[iarray[1]].getPosition(),false);
	    Y2.Add(stub[iarray[2]].getYstub());
	    Gamma2 = EMF.computeGamma(Y2,lineZ0,false);
	    
	    SPos0 = (int)((NPoints-1)*stub[iarray[0]].getPosition()/lineLength);
	    SPos1 = (int)((NPoints-1)*stub[iarray[1]].getPosition()/lineLength);
	    SPos2 = (int)((NPoints-1)*stub[iarray[2]].getPosition()/lineLength);
	    
	    //Find impedance and admittance looking from the input terminals of the transmission line
	    Zinput = EMF.computeZinAt(Gamma2,lineZ0,lineLength-stub[iarray[2]].getPosition(),true);
	    Yinput = EMF.computeYinAt(Gamma2,lineZ0,lineLength-stub[iarray[2]].getPosition(),true);
	    
	    //Find VPlus
	    Complex tempc;
	    tempc = new Complex(Math.cos(EMF.beta*lineLength-stub[iarray[2]].getPosition()),
				Math.sin(EMF.beta*lineLength-stub[iarray[2]].getPosition()));
	    VPlus = Complex.Divide(EMF.voltageDivider(generator,Zinput),
				Complex.Multiply(tempc,
				   Complex.Add(1.0,EMF.computeGammaAt(Gamma2,lineLength-stub[iarray[2]].getPosition())
				   )
				)
		    );
	    
		VPP[2] = Complex.Divide(
			  EMF.computeVat(Gamma2,lineZ0,VPlus,0.0,true),
			  EMF.computeVat(Gamma1,lineZ0,one,stub[iarray[2]].getPosition()-stub[iarray[1]].getPosition(),true)
		);
	    
		VPP[1] = Complex.Divide(
			  EMF.computeVat(Gamma1,lineZ0,VPP[2],0.0,true),
			  EMF.computeVat(Gamma0,lineZ0,one,stub[iarray[1]].getPosition()-stub[iarray[0]].getPosition(),true)
		);
	    
		VPP[0] = Complex.Divide(
			  EMF.computeVat(Gamma0,lineZ0,VPP[1],0.0,true),
			  EMF.computeVat(GammaL,lineZ0,one,stub[iarray[0]].getPosition(),true)
		);
	   
	    //Compute Yin and Zin with the stubs
	    if(xpos < stub[iarray[0]].getPosition()){
		if(is_Load_Ztype){
		    Yin = EMF.computeYinAt(GammaL,lineZ0,xpos,true);
		    Zin = EMF.Inv(Yin);
		}
		else { 
		    Zin = EMF.computeZinAt(GammaL,lineZ0,xpos,true); 
		    Yin = EMF.Inv(Zin);
		}
		Gammain = EMF.computeGammaAt(GammaL,xpos);
		Vin = EMF.computeVat(GammaL,lineZ0,VPP[0],xpos,true);
		Iin = EMF.computeIat(GammaL,lineZ0,VPP[0],xpos,true);    
	    }
	    else if(xpos < stub[iarray[1]].getPosition()){
		if(is_Load_Ztype){
		    Yin = EMF.computeYinAt(Gamma0,lineZ0,xpos-stub[iarray[0]].getPosition(),true);
		    Zin = EMF.Inv(Yin);
		}
		else { 
		    Zin = EMF.computeZinAt(Gamma0,lineZ0,xpos-stub[iarray[0]].getPosition(),true);
		    Yin = EMF.Inv(Zin);
		}
	        Gammain = EMF.computeGammaAt(Gamma0,xpos-stub[iarray[0]].getPosition());
		Vin = EMF.computeVat(Gamma0,lineZ0,VPP[1],xpos-stub[iarray[0]].getPosition(),true);
		Iin = EMF.computeIat(Gamma0,lineZ0,VPP[1],xpos-stub[iarray[0]].getPosition(),true);    
	    }
	    else if(xpos < stub[iarray[2]].getPosition()){
		if(is_Load_Ztype){
		    Yin = EMF.computeYinAt(Gamma1,lineZ0,xpos-stub[iarray[1]].getPosition(),true);
		    Zin = EMF.Inv(Yin);
		}
		else { 
		    Zin = EMF.computeZinAt(Gamma1,lineZ0,xpos-stub[iarray[1]].getPosition(),true);
		    Yin = EMF.Inv(Zin);
		}
		Gammain = EMF.computeGammaAt(Gamma1,xpos-stub[iarray[1]].getPosition());
		Vin = EMF.computeVat(Gamma1,lineZ0,VPP[2],xpos-stub[iarray[1]].getPosition(),true);
		Iin = EMF.computeIat(Gamma1,lineZ0,VPP[2],xpos-stub[iarray[1]].getPosition(),true); 
	    }
	    else {
		if(is_Load_Ztype){
		    Yin = EMF.computeYinAt(Gamma2,lineZ0,xpos-stub[iarray[2]].getPosition(),true);
		    Zin = EMF.Inv(Yin);
		}
		else { 
		    Zin = EMF.computeZinAt(Gamma2,lineZ0,xpos-stub[iarray[2]].getPosition(),true);
		    Yin = EMF.Inv(Zin);
		}
		Gammain = EMF.computeGammaAt(Gamma2,xpos-stub[iarray[2]].getPosition());
		    Vin = EMF.computeVat(Gamma2,lineZ0,VPlus,xpos-stub[iarray[2]].getPosition(),true);
		    Iin = EMF.computeIat(Gamma2,lineZ0,VPlus,xpos-stub[iarray[2]].getPosition(),true); 
	    }
	}
	else{ //All stubs are off
	    //Compute Yin and Zin without the stubs
	    if(is_Load_Ztype){
		Gammain = EMF.computeGammaAt(GammaL,xpos);
		Zin = EMF.computeZinAt(GammaL,lineZ0,xpos,true);
		
		if(ZL.Real() == 0.0 && Math.abs(Zin.Imaginary()) > lineZ0 && Math.abs(Gammain.Imaginary()) < 1.0e-10){
		   Zin = new Complex(0.0,-2.0E140);
		   Yin = new Complex(0.0,0.0);
		}
		else if(ZL.Real() == 0.0 && Math.abs(Zin.Imaginary()) < lineZ0 && Math.abs(Gammain.Imaginary()) < 1.0e-10){
		   Yin = new Complex(0.0,-2.0E140);
		   Zin = new Complex(0.0,0.0);
		}
		else{
		   Zin = EMF.computeZinAt(GammaL,lineZ0,xpos,true);
		   Yin = EMF.Inv(Zin);
		}
	    }
	    else{
		Gammain = EMF.computeGammaAt(GammaL,xpos);
		Yin = EMF.computeYinAt(GammaL,lineZ0,xpos,true);
		if(YL.Real() == 0.0 && Math.abs(Yin.Imaginary()) > (1.0/lineZ0) && Math.abs(Gammain.Imaginary()) < 1.0e-10){
		   Yin = new Complex(0.0,-2.0E140);
		   Zin = new Complex(0.0,0.0);
		}
		else if(YL.Real() == 0.0 && Math.abs(Yin.Imaginary()) < (1.0/lineZ0) && Math.abs(Gammain.Imaginary()) < 1.0e-10){
		   Zin = new Complex(0.0,-2.0E140);
		   Yin = new Complex(0.0,0.0);
		}
		else{
		   Yin = EMF.computeYinAt(GammaL,lineZ0,xpos,true);
		   Zin = EMF.Inv(Yin);
		}
	    }
	    
	    //Gammain = EMF.computeGammaAt(GammaL,xpos);
	    VPlus = EMF.computeVPlus(generator,ZL,lineZ0,lineLength);
	    Vin = EMF.computeVat(ZL,lineZ0,VPlus,xpos);
	    Iin = EMF.computeIat(ZL,lineZ0,VPlus,xpos);
	    VSWR = EMF.computeSWR(GammaL);
	    Pw = EMF.PowerDelivered(generator,VPlus,ZL,0.0,lineZ0,lineLength);
	    /*if(is_Load_Ztype){
		Yin = EMF.computeYinAt(GammaL,lineZ0,xpos,true);
		Zin = EMF.Inv(Yin);
		//Should write this one.
		//Yin = EMF.computeYinAt(GammaL,lineZ0,xpos,true,stub);
	    }
	    else{
		Yin = EMF.computeYinAt(GammaL,lineZ0,xpos,true);
		Zin = EMF.Inv(Yin);
	    }
	
	    Gammain = EMF.computeGammaAt(GammaL,xpos);
	    VPlus = EMF.computeVPlus(generator,ZL,lineZ0,lineLength);
	    Vin = EMF.computeVat(ZL,lineZ0,VPlus,xpos);
	    Iin = EMF.computeIat(ZL,lineZ0,VPlus,xpos);
	    VSWR = EMF.computeSWR(GammaL);
	    Pw = EMF.PowerDelivered(generator,VPlus,ZL,0.0,lineZ0,lineLength);
	    */
	}
        
         //System.out.println(lineLength_part1+"   "+lineLength_part2+"   "+linecounter1+"   "+linecounter2);
    }
    
    public synchronized void increment(){
	ctime+=dtime;
	if(ctime>NTime){ ctime -= NTime; }
    }
    
    public synchronized void reset(){
	ctime=0;
    }
    
    public void ScanImpedance(){
	int i;
	if(!stub[0].isEnable() && !stub[1].isEnable() && !stub[2].isEnable()){
	    ScanImpedanceWithoutStubs();
	    return;
	}
	
	for(i = 0; i < SPos0; i++){
	    x[i]  = i * lineLength/(NPoints-1);
	    Admittance[i] = EMF.computeYinAt(YL,lineZ0,x[i],false);
	}
	for(i = SPos0; i < SPos1; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    Admittance[i] = EMF.computeYinAt(Y0,lineZ0,x[i]-stub[iarray[0]].getPosition(),false);
	}
	
	for(i = SPos1; i < SPos2; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    Admittance[i] = EMF.computeYinAt(Y1,lineZ0,x[i]-stub[iarray[1]].getPosition(),false);
	}
	
	for(i = SPos2; i < NPoints; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    Admittance[i] = EMF.computeYinAt(Y2,lineZ0,x[i]-stub[iarray[2]].getPosition(),false);
	}
	
	for(i = 0; i < NPoints; i++){
	    Impedance[i] = EMF.Inv(Admittance[i]);
	    y1[i] = Impedance[i].Real();
	    y2[i] = Impedance[i].Imaginary();
	}	
    } 
    /*
    public void ScanImpedanceWithoutStubs(){
	double maxBound=3000.0;
	
	for(int i = 0; i < NPoints; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    Impedance[i] = EMF.computeZinAt(ZL,lineZ0,x[i],false);
	    
	    y1[i] = Impedance[i].Real();
	    y2[i] = Impedance[i].Imaginary();
	    
	    // FIX to limit the values on plots (7/31/97) - Umberto
	    if(y1[i]>maxBound){  y1[i] =  maxBound;}
	    if(y2[i]>maxBound){  y2[i] =  maxBound;}
	    if(y2[i]<-maxBound){ y2[i] = -maxBound;}
			     
	}
    } 
    */
    public void ScanImpedanceWithoutStubs(){
	double maxBound=20*lineZ0;
	double minBound=1.0/maxBound;
	maxR=0.0;
	maxX=0.0;
	minX=0.0;
	
	for(int i = 0; i < NPoints; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    Impedance[i] = EMF.computeZinAt(ZL,lineZ0,x[i],false);
	    
	    if(Complex.Real(ZL)==0.0 && Complex.Imaginary(ZL)==0.0){
		y1[i] = 0.0;
	    }
	    else{
		y1[i] = Impedance[i].Real();
	    }
	    
	    y2[i] = Impedance[i].Imaginary();
	    
	    // FIX to limit the values on plots (7/31/97) - Umberto
	    if(y1[i]<minBound){  y1[i] = 0.0;}
	    if(y1[i]>maxBound){  y1[i] =  maxBound;}
	    if(y2[i]>maxBound){  y2[i] =  maxBound;}
	    if(y2[i]<-maxBound){ y2[i] = -maxBound;}
	    if(y1[i]>maxR){maxR=y1[i];}
	    
	    if(Math.abs(y2[i])>maxX){maxX=Math.abs(y2[i]);}
	    if(y2[i]<minX){minX=y2[i];}
            
            if(maxX > 0.0 && minX > 0.0){
                minX = 0.0;
            }
            if((maxX > 0.0 && minX > 0.0)||(maxX < 0.0 && minX < 0.0)){
                maxX = 0.0;
            }
        }
    } 
    
    public void ScanAdmittance(){	
	int i;
	if(!stub[0].isEnable() && !stub[1].isEnable() && !stub[2].isEnable()){
	    ScanAdmittanceWithoutStubs();
	    return;
	}
		
	for(i = 0; i < SPos0; i++){
	    x[i]  = i * lineLength/(NPoints-1);
	    Admittance[i] = EMF.computeYinAt(YL,lineZ0,x[i],false);
	}
	for(i = SPos0; i < SPos1; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    Admittance[i] = EMF.computeYinAt(Y0,lineZ0,x[i]-stub[iarray[0]].getPosition(),false);
	}
	
	for(i = SPos1; i < SPos2; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    Admittance[i] = EMF.computeYinAt(Y1,lineZ0,x[i]-stub[iarray[1]].getPosition(),false);
	}
	
	for(i = SPos2; i < NPoints; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    Admittance[i] = EMF.computeYinAt(Y2,lineZ0,x[i]-stub[iarray[2]].getPosition(),false);
	}
	
	for(i = 0; i < NPoints; i++){
	    y1[i] = Admittance[i].Real();
	    y2[i] = Admittance[i].Imaginary();
	}	
    }
    
    public void ScanAdmittanceWithoutStubs(){
	double maxBound = 300.0;
	for(int i = 0; i < NPoints; i++){
	    x[i ] = i * lineLength/(NPoints-1);
	    Admittance[i] = EMF.computeYinAt(YL,lineZ0,x[i],false);
	    y1[i] = Admittance[i].Real();
	    y2[i] = Admittance[i].Imaginary();
	    
	    // FIX to limit the values on plots (7/31/97) - Umberto
	    
	    if(y1[i]>maxBound){  y1[i] = maxBound;}
	    if(y2[i]>maxBound){  y2[i] =  maxBound;}
	    if(y2[i]<-maxBound){ y2[i] = -maxBound;}	     
	}
    }
    
    public void ScanReflectionCoefficient(){
	int i;
	if(!stub[0].isEnable() && !stub[1].isEnable() && !stub[2].isEnable()){
	    ScanReflectionCoefficientWithoutStubs();
	    return;
	}
	
	for(i = 0; i < SPos0; i++){
	    x[i]  = i * lineLength/(NPoints-1);
	    RefCoef[i] = EMF.computeGammaAt(GammaL,x[i]);
	}
	
	for(i = SPos0; i < SPos1; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    RefCoef[i] = EMF.computeGammaAt(Gamma0,x[i]-stub[iarray[0]].getPosition());
	}
	
	for(i = SPos1; i < SPos2; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    RefCoef[i] = EMF.computeGammaAt(Gamma1,x[i]-stub[iarray[1]].getPosition());
	}
	
	for(i = SPos2; i < NPoints; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    RefCoef[i] = EMF.computeGammaAt(Gamma2,x[i]-stub[iarray[2]].getPosition());
	}
	
	
	for(i = 0; i < NPoints; i++){
	    y1[i] = RefCoef[i].Real();
	    y2[i] = RefCoef[i].Imaginary();
	}	
    }
        
    
    public void ScanReflectionCoefficientWithoutStubs(){
	Complex GammaL = EMF.computeGamma(ZL,lineZ0);
	for(int i = 0; i < NPoints; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    RefCoef[i] = EMF.computeGammaAt(GammaL,x[i]);
	    y1[i] = RefCoef[i].Real();
	    y2[i] = RefCoef[i].Imaginary();
	}
    }
   
   public void ScanVoltage(){
	int i;
	if(!stub[0].isEnable() && !stub[1].isEnable() && !stub[2].isEnable()){
	    ScanVoltageWithoutStubs();
	    return;
	}
	
	for(i = 0; i < SPos0; i++){
	    x[i]  = i * lineLength/(NPoints-1);
	    Voltage[i] = EMF.computeVat(GammaL,lineZ0,VPP[0],x[i],true);
	}
	
	for(i = SPos0; i < SPos1; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    Voltage[i] = EMF.computeVat(Gamma0,lineZ0,VPP[1],x[i]-stub[iarray[0]].getPosition(),true);
	}
	
	for(i = SPos1; i < SPos2; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    Voltage[i] = EMF.computeVat(Gamma1,lineZ0,VPP[2],x[i]-stub[iarray[1]].getPosition(),true);
	}
	
	for(i = SPos2; i < NPoints; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    Voltage[i] = EMF.computeVat(Gamma2,lineZ0,VPlus,x[i]-stub[iarray[2]].getPosition(),true);
	}
		
	for(i = 0; i < NPoints; i++){
	    y1[i] = Voltage[i].Real();
	    y2[i] = Voltage[i].Imaginary();
	}
	
    }
   
    public void ScanVoltageWithoutStubs(){ 
	for(int i = 0; i < NPoints; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    Voltage[i] = EMF.computeVat(ZL,lineZ0,VPlus,x[i]);
	    y1[i] = Voltage[i].Real();
	    y2[i] = Voltage[i].Imaginary();
	}    
    }
     public void ScanCurrent(){
	int i;
	if(!stub[0].isEnable() && !stub[1].isEnable() && !stub[2].isEnable()){
	    ScanCurrentWithoutStubs();
	    return;
	}
	
	for(i = 0; i < SPos0; i++){
	    x[i]  = i * lineLength/(NPoints-1);
	    Current[i] = EMF.computeIat(GammaL,lineZ0,VPP[0],x[i],true);
	}
	
	for(i = SPos0; i < SPos1; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    Current[i] = EMF.computeIat(Gamma0,lineZ0,VPP[1],x[i]-stub[iarray[0]].getPosition(),true);
	}
	
	for(i = SPos1; i < SPos2; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    Current[i] = EMF.computeIat(Gamma1,lineZ0,VPP[2],x[i]-stub[iarray[1]].getPosition(),true);
	}
	
	for(i = SPos2; i < NPoints; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    Current[i] = EMF.computeIat(Gamma2,lineZ0,VPlus,x[i]-stub[iarray[2]].getPosition(),true);
	}
		
	for(i = 0; i < NPoints; i++){
	    y1[i] = Current[i].Real();
	    y2[i] = Current[i].Imaginary();
	}	
    }
    
    public void ScanCurrentWithoutStubs(){ 
	for(int i = 0; i < NPoints; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    Current[i] = EMF.computeIat(ZL,lineZ0,VPlus,x[i]);
	    y1[i] = Current[i].Real();
	    y2[i] = Current[i].Imaginary();
	}    
    }
    
    public void ScanVoltageCurrent(){
	int i;
	if(!stub[0].isEnable() && !stub[1].isEnable() && !stub[2].isEnable()){
	    ScanVoltageCurrentWithoutStubs();
	    return;
	}
	
	for(i = 0; i < SPos0; i++){
	    x[i]  = i * lineLength/(NPoints-1);
	    Voltage[i] = EMF.computeVat(GammaL,lineZ0,VPP[0],x[i],true);
	    Current[i] = EMF.computeIat(GammaL,lineZ0,VPP[0],x[i],true);
	}
	
	for(i = SPos0; i < SPos1; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    Voltage[i] = EMF.computeVat(Gamma0,lineZ0,VPP[1],x[i]-stub[iarray[0]].getPosition(),true);
	    Current[i] = EMF.computeIat(Gamma0,lineZ0,VPP[1],x[i]-stub[iarray[0]].getPosition(),true);
	}
	
	for(i = SPos1; i < SPos2; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    Voltage[i] = EMF.computeVat(Gamma1,lineZ0,VPP[2],x[i]-stub[iarray[1]].getPosition(),true);
	    Current[i] = EMF.computeIat(Gamma1,lineZ0,VPP[2],x[i]-stub[iarray[1]].getPosition(),true);
	}
	
	for(i = SPos2; i < NPoints; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    Voltage[i] = EMF.computeVat(Gamma2,lineZ0,VPlus,x[i]-stub[iarray[2]].getPosition(),true);
	    Current[i] = EMF.computeIat(Gamma2,lineZ0,VPlus,x[i]-stub[iarray[2]].getPosition(),true);
	}
		
	for(i = 0; i < NPoints; i++){
	    y1[i] = Voltage[i].Magnitude();
	    y2[i] = Current[i].Magnitude();
	}	
    }
    
    
     public void ScanVoltageCurrentWithoutStubs(){ 
	for(int i = 0; i < NPoints; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    Voltage[i] = EMF.computeVat(ZL,lineZ0,VPlus,x[i]);
	    Current[i] = EMF.computeIat(ZL,lineZ0,VPlus,x[i]);
	    y1[i] = Voltage[i].Magnitude();
	    y2[i] = Current[i].Magnitude();
	}    
    }
    
    public void ScanTimeAveragePower(){
	ScanVoltageCurrent();
	for(int i = 0; i < NPoints; i++){
	    y1[i] = EMF.TimeAveragedPower(Voltage[i],Current[i]);
	    y2[i] = 0.0;
	}
    }
    
    public void ScanRandom(){
	for(int i = 0; i < NPoints; i++){
	    x[i] = i * lineLength/(NPoints-1);
	    y1[i] = -100.0 + 200.0*Math.random();
	    y2[i] = -100.0 + 200.0*Math.random();
	}
    }
    
    public void ScanTimeDependentVoltage(){
	timeFactor.setReal(Math.cos(2.0*Math.PI*ctime/NTime));
	timeFactor.setImaginary(Math.sin(2.0*Math.PI*ctime/NTime));
	ScanVoltage();
	for(int i = 0; i < NPoints; i++){
	    Voltage[i].Multiply(timeFactor);
	    y1[i] = Voltage[i].Real();
	    y2[i] = 0.0;
	}	
    }
    
    public void ScanTimeDependentCurrent(){
	timeFactor.setReal(Math.cos(2.0*Math.PI*ctime/NTime));
	timeFactor.setImaginary(Math.sin(2.0*Math.PI*ctime/NTime));
	ScanCurrent();
	for(int i = 0; i < NPoints; i++){
	    Current[i].Multiply(timeFactor);
	    y1[i] = Current[i].Real();
	    y2[i] = 0.0;
	}	
    }
    
    public void ScanTimeDependentPower(){
	timeFactor.setReal(Math.cos(2.0*Math.PI*ctime/NTime));
	timeFactor.setImaginary(Math.sin(2.0*Math.PI*ctime/NTime));
	ScanVoltageCurrent();
	for(int i = 0; i < NPoints; i++){
	    Voltage[i].Multiply(timeFactor);
	    Current[i].Multiply(timeFactor);
	    Power[i] = Complex.Multiply(Voltage[i],Current[i]);
	    y1[i] = Power[i].Real();
	    y2[i] = 0.0;
	}	
    }
    
    public double getYRangeMax(int i){//arg=1 for Voltage Max
	Complex VPlus = EMF.computeVPlus(generator,ZL,lineZ0,lineLength);
	double tmp=0.0;
	switch(i){
	    case 1://Voltage
		tmp = 2.0*VPlus.Magnitude();
		break;
	    case 2://Current
		tmp = 2.0*VPlus.Magnitude()/lineZ0;
		break;
	    case 3:
		tmp = 2.0*VPlus.Magnitude2()/lineZ0;
		break;
	}
	return tmp;
    }
  
/** 
    Sorts stubs and returns the results in an integer array iarray[].
    The sort is perfrom in increasing stub's distance from the load
    iarray[0] is first stub (closest to the load)
    iarray[1] is second stub
    iarray[3] is third stub	(farthest from the load)
*/
private void sortStubs(){
	double tmp;
	iarray[0]=-1;
	iarray[1]=-1;
	iarray[2]=-1;
	
	iarray[0]=0;
	tmp=stub[iarray[0]].getPosition();
	for(int j=0;j<3;j++){
		if(tmp > stub[j].getPosition()){
			tmp=stub[j].getPosition();
			iarray[0]=j;
		}
	}

	if(iarray[0]!=0) {iarray[1]=0;}
	else{iarray[1]=1;}
	tmp=stub[iarray[1]].getPosition();
	for(int j=0;j<3;j++){
		if(j != iarray[0] && tmp > stub[j].getPosition()){
			tmp=stub[j].getPosition();
			iarray[1]=j;
		}
	}

	if(iarray[0] !=0 && iarray[1] !=0) { iarray[2]=0; }
	else if(iarray[0] !=1 && iarray[1] !=1) { iarray[2]=1; }
	else {iarray[2]=2;}
	/*
	tmp=stub[iarray[2]].getPosition();
	for(int j=0;j<3;j++){
		if(j != iarray[0] && j !=iarray[1] && tmp > stub[j].getPosition()){
			tmp=stub[j].getPosition();
			iarray[2]=j;
		}
	}
	*/
	
}



}/*State.java*/
