/**
 * NewGuideCanvas.java
 *
 *
*/
//import java.applet.*;
//import java.lang.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.net.*;
import java.awt.event.*;


public class NewGuideCanvas extends Canvas implements MouseListener{
    private static final Color bgcolor2 = new Color(255,255,250);
    private static final Color bgcolor = Color.white;
    //private static final Color bgcolor2 = Color.gray;
    private NewGuide_State state;
    private static final int LeftMargin=20, RightMargin=10, TopMargin=10, BottomMargin=10;
    private static final Font labfont = new Font("SanSerif",Font.PLAIN,10);
    private static final Font symbfont= new Font("Serif",Font.PLAIN,12);
    private static final Font symbfont2= new Font("Serif",Font.PLAIN,14);
    private static final Font labfont2= new Font("Serif",Font.BOLD,16);
    private static final Font labfont4= new Font("Serif",Font.PLAIN,12);
    private static final Font labfont3 = new Font("SanSerif",Font.PLAIN,12);
    private int x[], y[];
    private double frequency, epsilon_r, epsilon_r0, mu_r, phase_velocity, phase_velocity0;
    private double DipoleLength_lambda, wavelength, radius_lambda;
    
    private double Tower1, Tower2, Tower1_max, Tower2_max, Tower_scaling, Distance;
    
    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 - simplified
    
    private Image im;
    private Graphics buf;
    private String stmp;
    private double temp;
    private boolean IsFocusOn, IsTopoOn, IsTE;
    public boolean Is3D;
    
    public NewGuideCanvas(NewGuide_State state){
	super();
	IsFocusOn = false;
	IsTopoOn = false;
	IsTE = true;
        
	setBackground(bgcolor);
        this.state = state;
	x = new int[5];
	y = new int[5];

	//Listeners
	this.addMouseListener(this);
	
	epsilon_r = 1.0;
	epsilon_r0 = 1.0;
	mu_r = 1.0;
	frequency = 1.0E9;
	DipoleLength_lambda = 0.5;
	radius_lambda = 1.0E-5;
	
        Tower1 = state.Tower1_height; // meters
        Tower2 = state.Tower2_height; // meters
        
        Tower1_max = state.Tower_max;// meters
        Tower2_max = state.Tower_max;// meters
        Distance = state.dist; // meters
        
        Tower_scaling = state.Tower_max;
	Is3D = true;
	
	wavelength = light_velocity/frequency/Math.sqrt(epsilon_r);	
    }

    public void drawCanvas(Graphics g){
	
	setBackground(bgcolor2);
	g.clearRect(0,0,getSize().width,getSize().height);
	g.setColor(Color.black);
	
	    draw3D(g);
	    
    }
    
    
    private void drawWire(int x1, int y1, int x2, int y2, int mode, Graphics g){
        Graphics2D g2d = (Graphics2D)g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
    
		//g.setColor(Color.white);
		g.setColor(Color.gray);
		g.drawLine(x1,y1,x2,y2);
		if(mode==1){
			g.setColor(Color.black);
			g.drawLine(x1,y1+1,x2,y2+1);
		}
		else if(mode==2){
			g.setColor(Color.black);
			g.drawLine(x1+1,y1,x2+1,y2);
		}
    }

    private void draw3DRect(int x, int y, int width, int height, Color c, Graphics g){
		g.setColor(c);
		g.fillRect(x-width/2,y-height/2,width,height);
		//g.setColor(Color.white);
		g.setColor(Color.gray);
		g.drawLine(x-width/2,y-height/2,x+width/2,y-height/2);
		g.drawLine(x-width/2,y-height/2,x-width/2,y+height/2);
		g.setColor(Color.black);
		g.drawLine(x-width/2,y+height/2,x+width/2,y+height/2);
		g.drawLine(x+width/2,y-height/2,x+width/2,y+height/2);
	}
	
	private void drawRect(int x, int y, int width, int height, Color c, Graphics g){
		g.setColor(c);
		g.fillRect(x-width/2,y-height/2,width,height);
	}
	

	private void drawCircle(int x, int y, int radius, Color c, Graphics g){
		g.setColor(c);
		g.fillOval(x-radius,y-radius,2*radius,2*radius);
		//g.setColor(Color.white);
		g.setColor(Color.gray);
		g.drawOval(x-radius,y-radius,2*radius,2*radius);
		g.setColor(Color.black);
		g.drawArc(x-radius-1,y-radius-1,2*radius+2,2*radius+2,30,-120);
	}

	
    private void draw3D(Graphics g){    
	Graphics2D g2d = (Graphics2D)g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        int whereGamma = 2*getSize().width/3+3;
        int yGamma = getSize().height-27;
        
        Tower1 = state.Tower1_height;
        Tower2 = state.Tower2_height; // meters
        
        Tower_scaling = Math.max(Tower1,Tower2);
        /*
        double Tower_ref;
        Tower_ref = Math.max(Tower1,Tower2);
        
        if(Tower_ref <= 100.0){Tower_scaling = 100.0;}
        else if(Tower_ref > 100.0 && Tower_ref <= 200.0){Tower_scaling = 200.0;}
        else if(Tower_ref > 200.0 && Tower_ref <= 300.0){Tower_scaling = 300.0;}
        else if(Tower_ref > 300.0 && Tower_ref <= 400.0){Tower_scaling = 400.0;}
        else if(Tower_ref > 400.0 && Tower_ref <= 500.0){Tower_scaling = 500.0;}
	*/
        
        //Draw the background
		
		g.setColor(Color.black);
		//set the arrays
		//x[0] = getSize().width/2;
                x[0] = 33;
		x[1] = x[0] - 7;
		x[2] = getSize().width-33;
                x[3] = getSize().width/2;
		
		y[0] = getSize().height-20;
		y[1] = getSize().height/2;
                y[2] = 20;
		g.clearRect(0,0,getSize().width-1,getSize().height-1);
		
                /*
                if(IsTopoOn){
		    if(!IsFocusOn){
			g.setColor(Color.blue);
			g.drawString("Click to show ",getSize().width*2/3+2,getSize().height*3/4);
			g.drawString("angles reference",getSize().width*2/3+2,getSize().height*3/4+11);
		    }
		    else{
			g.setColor(Color.red);
			g.drawString("Click to show ",getSize().width*2/3+2,getSize().height*3/4);
			g.drawString("dipole diagram",getSize().width*2/3+2,getSize().height*3/4+11);
			
		    }
		}
                 */
		
                //----------------------------------------------------------
		FontMetrics fm;
                
                g.setColor(Color.black);
		g.setFont(new Font("SanSerif",Font.PLAIN,12));
		int xf = x[3];
		//int yf = getSize().height-5;
                int yf = 20;
		double f_normalized;
	
		if(frequency < 1.0E3){
		    f_normalized = frequency;
		    MaestroG.special("","f","  =  "+MaestroA.rounder(f_normalized,6)+"   [ Hz ]","",g,13,xf,yf);	
		}
		else if(frequency < 1.0E6 && frequency >= 1.0E3  ){
		    f_normalized = frequency/1.0E3;
		    MaestroG.special("","f","  =  "+MaestroA.rounder(f_normalized,6)+"   [ kHz ]","",g,13,xf,yf);
		}
		else if(frequency < 1.0E9 && frequency >= 1.0E6 ){
		    f_normalized = frequency/1.0E6;
		    MaestroG.special("","f","  =  "+MaestroA.rounder(f_normalized,6)+"   [ MHz ]","",g,13,xf,yf);
		}
		else if(frequency < 1.0E12 && frequency >= 1.0E9 ){
		    f_normalized = frequency/1.0E9;
		    MaestroG.special("","f","  =  "+MaestroA.rounder(f_normalized,6)+"   [ GHz ]","",g,13,xf,yf);
		}
		else if(frequency < 1.0E15 && frequency >= 1.0E12 ){
		    f_normalized = frequency/1.0E12;
		    MaestroG.special("","f","  =  "+MaestroA.rounder(f_normalized,6)+"   [ THz ]","",g,13,xf,yf);
		}
		else{
		    f_normalized = frequency/1.0E12;
		    MaestroG.special("","f","  =  "+MaestroA.rounder(f_normalized,6)+"   [ THz ]","",g,13,xf,yf);
		}
                
		//-----------------------------------------------------------------------------------
		String lambda, rho;
                int str;
		g.setFont(symbfont2);
                g.getFontMetrics();
		lambda="\u03bb";
		rho ="\u03c1";
                
	    if(IsFocusOn){
                // this is disabled here
	    }
	    else{	
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        
		int endpoint = 75;
                int xtower1 = x[0]+20;
                int xtower2 = x[2]-20;
                
		// Axes through towers
                //DRAW TOWERS
		g.setColor(Color.gray);
                //LEFT TOWER
		//g.drawLine(xtower1,20,xtower1,y[0]);
                //RIGHT TOWER
                //g.drawLine(xtower2,20,xtower2,y[0]);
                
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                
	    //draw antenna  ----------------------------------------------------
		//draw measurement arrows
		g.setColor(Color.gray);
		int xarrow1 = x[0]+5;
                int xarrow2 = x[2]-5;
                int ybase = y[1] + endpoint;
                int ytop1, ytop2;
		
                ytop1 = (int)(2*endpoint * Tower1/Tower_scaling);
                ytop2 = (int)(2*endpoint * Tower2/Tower_scaling);
                
                //drawLineThick(g, (double)xtower1, (double)ybase, (double)xtower1, (double)(ybase-ytop1), 3, Color.red);
                //drawLineThick(g, (double)xtower2, (double)ybase, (double)xtower2, (double)(ybase-ytop2), 3, Color.red);
                g.setColor(new Color(240,240,250));
                Polygon pH = new Polygon();
                    pH.addPoint(xtower1-5, ybase);
                    pH.addPoint(xtower1, (ybase-ytop1));
                    pH.addPoint(xtower1+5, ybase);
                    g.drawPolygon(pH);
                    g.fillPolygon(pH);
                Color tower_color = Color.gray.darker();
                drawLineThick(g, (double)xtower1-5, (double)ybase, (double)xtower1, (double)(ybase-ytop1), 1, tower_color);
                drawLineThick(g, (double)xtower1+5, (double)ybase, (double)xtower1, (double)(ybase-ytop1), 1, tower_color);
                
                g.setColor(new Color(240,240,250));
                Polygon pH2 = new Polygon();
                    pH2.addPoint(xtower2-5, ybase);
                    pH2.addPoint(xtower2, (ybase-ytop2));
                    pH2.addPoint(xtower2+5, ybase);
                    g.drawPolygon(pH2);
                    g.fillPolygon(pH2);
                //drawLineThick(g, (double)xtower1, (double)ybase, (double)xtower1, (double)(ybase-ytop1), 3, tower_color);
                drawLineThick(g, (double)xtower2-5, (double)ybase, (double)xtower2, (double)(ybase-ytop2), 1, tower_color);
                drawLineThick(g, (double)xtower2+5, (double)ybase, (double)xtower2, (double)(ybase-ytop2), 1, tower_color);
                //drawLineThick(g, (double)xtower2, (double)ybase, (double)xtower2, (double)(ybase-ytop2), 3, tower_color);
                
                //  Find reflection point on graph
                int dist_Towers; int xbounce;
                dist_Towers = xtower2 - xtower1;
                
                if(ytop1 == 0 && ytop2 == 0){
                    xbounce = (xtower1 + xtower2)/2;
                }
                else{
                    xbounce = (int)(dist_Towers * ytop1/(ytop1+ytop2));
                }
                
                // Draw propagation paths
                //=====================================================================================
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                double diametro = 80.0;
                double diametro1 = Math.min(80.0,2.0*(double)(xbounce));
                double diametro2 = Math.min(80.0,2.0*(double)(xtower2-xtower1-xbounce));
                double startx1 = (double)(xtower1+xbounce-diametro1/2);
                double starty1 = (double)(ybase-diametro1/2);
                double startx2 = (double)(xtower1+xbounce-diametro2/2);
                double starty2 = (double)(ybase-diametro2/2);
                double angolo;
                if(xbounce < ((xtower2-xtower1)/2)){angolo = Math.atan((double)ytop2/(double)(xtower2-xtower1-xbounce))*180.0/Math.PI*0.95;}
                else{angolo = Math.atan((double)ytop1/(double)xbounce)*180.0/Math.PI*0.95;}
                FillArcTransp(g,startx1,starty1,diametro1,180.0,-angolo,Color.green, 0.5);
                FillArcTransp(g,startx2,starty2,diametro2,0.0,angolo,Color.green, 0.5);
                drawArcThick(g,startx1,starty1,diametro1,diametro1,180.0,-angolo,1,Color.black);
                drawArcThick(g,startx2,starty2,diametro2,diametro2,0.0,angolo,1,Color.black);
                
                // theta angle symbol
                g.setColor(Color.red.darker());
		g.setFont(new Font("Serif",Font.PLAIN,18));
		if(xbounce > diametro){g.drawString("\u0398",xtower1+xbounce-(int)diametro+3,ybase-2);}
                if(xbounce < (xtower2-xtower1-diametro)){g.drawString("\u0398",xtower1+xbounce+(int)diametro-12,ybase-2);}
		g.setFont(new Font("SanSerif",Font.PLAIN,12));
		g.setColor(Color.black);
                                
                //g.setColor(Color.yellow);
		//g.fillArc(xbounce,ybase,radio,radio,180,-30);
                
                //float[] dashPattern = {10,5};// Add these lines to make line dotted
                //g2d.setStroke(new BasicStroke(1.0F,BasicStroke.CAP_BUTT,BasicStroke.JOIN_MITER,10.0F,dashPattern,0));
                
                // Direct path
                g.setColor(Color.red);
                //g.drawLine(xtower1, ybase-ytop1, xtower2, ybase-ytop2);
                drawLineThick(g,(double)(xtower1),(double)(ybase-ytop1),(double)(xtower2),(double)(ybase-ytop2),1,new Color(100,100,255));
                // Reflected path
                //
                g.setColor(Color.gray);
                if(xbounce > 0 && xbounce < (xtower2-xtower1)){
                    //g.drawLine(xtower1, ybase-ytop1, xtower1+xbounce, ybase);
                    //g.drawLine(xtower1+xbounce, ybase, xtower2, ybase-ytop2);
                    //float[] dashPattern2 = {10,5};  // Add these lines to make line dotted
                    //g2d.setStroke(new BasicStroke(1.0F,BasicStroke.CAP_BUTT,BasicStroke.JOIN_MITER,10.0F,dashPattern2,0));
                    drawLineThickDashed(g,(double)(xtower1),(double)(ybase-ytop1),(double)(xtower1+xbounce),(double)(ybase),1,Color.red);
                    drawLineThickDashed(g,(double)(xtower1+xbounce),(double)(ybase),(double)(xtower2),(double)(ybase-ytop2),1,Color.red);
                }
                
                // GROUND BASELINE
                Color GroundColor = Color.white;
                if(state.GroundChoose == 1){
                    GroundColor = new Color(200,200,200);
                }
                else if(state.GroundChoose == 2){
                    GroundColor = new Color(190,140,80);
                }
                else if(state.GroundChoose == 3){
                    GroundColor = new Color(190,140,80);
                }
                else if(state.GroundChoose == 4){
                    GroundColor = new Color(190,140,80);
                }
                else if(state.GroundChoose == 5){
                    GroundColor = new Color(170,190,255);
                }
                else if(state.GroundChoose == 6){
                    GroundColor = new Color(170,190,255);
                }
                MaestroG.drawLineThick(g,(double)(xarrow1-20),(double)(ybase+10),(double)(xarrow2+20),(double)(ybase+10),20,GroundColor);
                g.setColor(Color.black);
                g.drawLine(xarrow1-20,ybase,xarrow2+20,ybase);
                               
                
                // DRAW THE FIELDS
                double posxD, posyD, posx1, posy1, posx2, posy2;
                posxD = xtower1 + (xtower2-xtower1)/4;
                posyD = (ybase-ytop1) + (ytop1-ytop2)/4;
                posx1 = xtower1 + xbounce/2;
                posy1 = ybase - ytop1/2;
                posx2 = xtower2 - (xtower2 - xtower1 - xbounce)/2;
                posy2 = ybase - ytop2/2;;
                
                
                if(IsTE){ // Perpendicular Polarization
                    
                    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                    int leng = 30, Len = 8;
                    double angolone, angolo1, angolo2;
                    
                    // incident wave vector
                    double tipx1,tipy1; 
                    
                    // DIRECT PATH
                    double tipxD, tipyD, angoloD; 
                    angoloD = Math.atan((double)(ytop2-ytop1)/(double)(xtower2-xtower1))*180/Math.PI;
                    tipxD = posxD+leng*Math.cos(angoloD*Math.PI/180);
                    tipyD = posyD-leng*Math.sin(angoloD*Math.PI/180);
                    drawLineThick(g,posxD,posyD,tipxD,tipyD,2,Color.black);
                    angolone = angoloD*Math.PI/180;
                    angolo1 = angolone - 20.0*Math.PI/180.0;
                    angolo2 = angolone + 20.0*Math.PI/180.0;
                    drawLineThick(g,tipxD,tipyD,tipxD-Len*Math.cos(angolo1),tipyD+Len*Math.sin(angolo1),2,Color.black);
                    drawLineThick(g,tipxD,tipyD,tipxD-Len*Math.cos(angolo2),tipyD+Len*Math.sin(angolo2),2,Color.black);
                    // direct magnetic field
                    tipxD = posxD-leng*Math.cos(angoloD*Math.PI/180+Math.PI/2);
                    tipyD = posyD+leng*Math.sin(angoloD*Math.PI/180+Math.PI/2);
                    drawLineThick(g,posxD,posyD,tipxD,tipyD,2,Color.blue);
                    angolone = Math.PI/2 - angoloD*Math.PI/180;
                    angolo1 = angolone - 20.0*Math.PI/180.0;
                    angolo2 = angolone + 20.0*Math.PI/180.0;
                    drawLineThick(g,tipxD,tipyD,tipxD-Len*Math.cos(angolo1),tipyD-Len*Math.sin(angolo1),2,Color.blue);
                    drawLineThick(g,tipxD,tipyD,tipxD-Len*Math.cos(angolo2),tipyD-Len*Math.sin(angolo2),2,Color.blue);
                    
                    // Direct path
                        fillCircleThick(g, posxD, posyD, 8.0, 2, Color.red);
                        fillCircleThick(g, posxD, posyD, 6.0, 2, Color.white);
                        fillCircleThick(g, posxD, posyD, 3.0, 2, Color.red);
                    
                    g.setColor(Color.red);
                    MaestroG.special2("E","","","",g,14,(int)posxD-10,(int)posyD-15);
                    
                    g.setColor(Color.blue);
                    MaestroG.special2("H","","","",g,14,(int)tipxD+10,(int)tipyD);
                    
                    if((Tower1 != 0) && (Tower2 != 0)){
                        // REFLECTED PATH
                        tipx1 = posx1+leng*Math.cos(angolo*Math.PI/180);
                        tipy1 = posy1+leng*Math.sin(angolo*Math.PI/180);

                        drawLineThick(g,posx1,posy1,posx1+leng*Math.cos(angolo*Math.PI/180),posy1+leng*Math.sin(angolo*Math.PI/180),2,Color.black);
                        angolone = Math.PI - angolo*Math.PI/180;
                        angolo1 = angolone - 20.0*Math.PI/180.0;
                        angolo2 = angolone + 20.0*Math.PI/180.0;
                        drawLineThick(g,tipx1,tipy1,tipx1+Len*Math.cos(angolo1),tipy1-Len*Math.sin(angolo1),2,Color.black);
                        drawLineThick(g,tipx1,tipy1,tipx1+Len*Math.cos(angolo2),tipy1-Len*Math.sin(angolo2),2,Color.black);

                        // incident magnetic field
                        tipx1 = posx1+leng*Math.cos(angolo*Math.PI/180+Math.PI/2);
                        tipy1 = posy1+leng*Math.sin(angolo*Math.PI/180+Math.PI/2);
                        drawLineThick(g,posx1,posy1,posx1+leng*Math.cos(angolo*Math.PI/180+Math.PI/2),posy1+leng*Math.sin(angolo*Math.PI/180+Math.PI/2),2,Color.blue);
                        angolone = Math.PI/2 - angolo*Math.PI/180;
                        angolo1 = angolone - 20.0*Math.PI/180.0;
                        angolo2 = angolone + 20.0*Math.PI/180.0;
                        drawLineThick(g,tipx1,tipy1,tipx1+Len*Math.cos(angolo1),tipy1-Len*Math.sin(angolo1),2,Color.blue);
                        drawLineThick(g,tipx1,tipy1,tipx1+Len*Math.cos(angolo2),tipy1-Len*Math.sin(angolo2),2,Color.blue);

                        // reflected wave vector
                        double tipx2,tipy2; 
                        tipx2 = posx2+leng*Math.cos(angolo*Math.PI/180);
                        tipy2 = posy2-leng*Math.sin(angolo*Math.PI/180);
                        drawLineThick(g,posx2,posy2,posx2+leng*Math.cos(angolo*Math.PI/180),posy2-leng*Math.sin(angolo*Math.PI/180),2,Color.black);
                        angolone = angolo*Math.PI/180;
                        angolo1 = angolone - 20.0*Math.PI/180.0;
                        angolo2 = angolone + 20.0*Math.PI/180.0;
                        drawLineThick(g,tipx2,tipy2,tipx2-Len*Math.cos(angolo1),tipy2+Len*Math.sin(angolo1),2,Color.black);
                        drawLineThick(g,tipx2,tipy2,tipx2-Len*Math.cos(angolo2),tipy2+Len*Math.sin(angolo2),2,Color.black);

                        // reflected magnetic field
                        tipx2 = posx2+leng*Math.cos(angolo*Math.PI/180+Math.PI/2);
                        tipy2 = posy2-leng*Math.sin(angolo*Math.PI/180+Math.PI/2);
                        drawLineThick(g,posx2,posy2,posx2+leng*Math.cos(angolo*Math.PI/180+Math.PI/2),posy2-leng*Math.sin(angolo*Math.PI/180+Math.PI/2),2,Color.blue);
                        angolone = angolo*Math.PI/180 + Math.PI/2;
                        angolo1 = angolone - 20.0*Math.PI/180.0;
                        angolo2 = angolone + 20.0*Math.PI/180.0;
                        drawLineThick(g,tipx2,tipy2,tipx2-Len*Math.cos(angolo1),tipy2+Len*Math.sin(angolo1),2,Color.blue);
                        drawLineThick(g,tipx2,tipy2,tipx2-Len*Math.cos(angolo2),tipy2+Len*Math.sin(angolo2),2,Color.blue);

                        //g.setColor(Color.white);
                        //fillCircle(posx1, posy1, 12, g);
                        //fillCircle(posx2, posy2, 12, g);
                        //g.setColor(Color.red);
                        //drawCircle(posx1, posy1, 12, g);
                        //fillCircle(posx1, posy1, 5, g);
                        //drawCircle(posx2, posy2, 12, g);
                        //fillCircle(posx2, posy2, 5, g);

                        // Reflected path
                        fillCircleThick(g, posx1, posy1, 8.0, 2, Color.red);
                        fillCircleThick(g, posx2, posy2, 8.0, 2, Color.red);
                        fillCircleThick(g, posx1, posy1, 6.0, 2, Color.white);
                        fillCircleThick(g, posx2, posy2, 6.0, 2, Color.white);
                        fillCircleThick(g, posx1, posy1, 3.0, 2, Color.red);
                        //fillCircleThick(g, posx2, posy2, 3.0, 2, Color.red);
                        // cross for reflected electric field pointing inwards
                        drawLineThick(g, posx2-4, posy2-4,posx2+4, posy2+4,2,Color.red);
                        drawLineThick(g, posx2+4, posy2-4,posx2-4, posy2+4,2,Color.red);
                        //g.drawLine((int)posx2-4,(int)posy2-4,(int)posx2+4,(int)posy2+4);
                        //g.drawLine((int)posx2+4, (int)posy2-4,(int)posx2-4,(int)posy2+4);

                        g.setColor(Color.red);
                        MaestroG.special2("E","","","",g,14,(int)posx1-10,(int)posy1-15);
                        MaestroG.special2("E","","","",g,14,(int)posx2-23,(int)posy2);

                        g.setColor(Color.blue);
                        MaestroG.special2("H","","","",g,14,(int)tipx1+10,(int)tipy1);
                        MaestroG.special2("H","","","",g,14,(int)tipx2+10,(int)tipy2+10);
                    }
                }
                else{ // Parallel Polarization
                    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                    int leng = 30, Len = 8;
                    double angolone, angolo1, angolo2;
                    
                    // incident wave vector
                    double tipx1,tipy1; 
                    
                    // DIRECT PATH
                    double tipxD, tipyD, angoloD; 
                    angoloD = Math.atan((double)(ytop2-ytop1)/(double)(xtower2-xtower1))*180/Math.PI;
                    tipxD = posxD+leng*Math.cos(angoloD*Math.PI/180);
                    tipyD = posyD-leng*Math.sin(angoloD*Math.PI/180);
                    drawLineThick(g,posxD,posyD,tipxD,tipyD,2,Color.black);
                    angolone = angoloD*Math.PI/180;
                    angolo1 = angolone - 20.0*Math.PI/180.0;
                    angolo2 = angolone + 20.0*Math.PI/180.0;
                    drawLineThick(g,tipxD,tipyD,tipxD-Len*Math.cos(angolo1),tipyD+Len*Math.sin(angolo1),2,Color.black);
                    drawLineThick(g,tipxD,tipyD,tipxD-Len*Math.cos(angolo2),tipyD+Len*Math.sin(angolo2),2,Color.black);
                    // incident magnetic field
                    tipxD = posxD+leng*Math.cos(angoloD*Math.PI/180+Math.PI/2);
                    tipyD = posyD-leng*Math.sin(angoloD*Math.PI/180+Math.PI/2);
                    drawLineThick(g,posxD,posyD,tipxD,tipyD,2,Color.red);
                    angolone = 3*Math.PI/2 - angoloD*Math.PI/180;
                    angolo1 = angolone - 20.0*Math.PI/180.0;
                    angolo2 = angolone + 20.0*Math.PI/180.0;
                    drawLineThick(g,tipxD,tipyD,tipxD-Len*Math.cos(angolo1),tipyD-Len*Math.sin(angolo1),2,Color.red);
                    drawLineThick(g,tipxD,tipyD,tipxD-Len*Math.cos(angolo2),tipyD-Len*Math.sin(angolo2),2,Color.red);
                    
                    // Direct Path
                        fillCircleThick(g, posxD, posyD, 8.0, 2, Color.blue);
                        fillCircleThick(g, posxD, posyD, 6.0, 2, Color.white);
                        fillCircleThick(g, posxD, posyD, 3.0, 2, Color.blue);

                    g.setColor(Color.blue);
                    MaestroG.special2("H","","","",g,14,(int)posxD-20,(int)posyD-10);
                    
                    g.setColor(Color.red);
                    MaestroG.special2("E","","","",g,14,(int)tipxD+10,(int)tipyD+10);
                    
                    if((Tower1 != 0) && (Tower2 != 0)){
                        // REFLECTED PATH
                        tipx1 = posx1+leng*Math.cos(angolo*Math.PI/180);
                        tipy1 = posy1+leng*Math.sin(angolo*Math.PI/180);
                        drawLineThick(g,posx1,posy1,posx1+leng*Math.cos(angolo*Math.PI/180),posy1+leng*Math.sin(angolo*Math.PI/180),2,Color.black);
                        angolone = Math.PI - angolo*Math.PI/180;
                        angolo1 = angolone - 20.0*Math.PI/180.0;
                        angolo2 = angolone + 20.0*Math.PI/180.0;
                        drawLineThick(g,tipx1,tipy1,tipx1+Len*Math.cos(angolo1),tipy1-Len*Math.sin(angolo1),2,Color.black);
                        drawLineThick(g,tipx1,tipy1,tipx1+Len*Math.cos(angolo2),tipy1-Len*Math.sin(angolo2),2,Color.black);

                        // incident electric field
                        tipx1 = posx1-leng*Math.cos(angolo*Math.PI/180+Math.PI/2);
                        tipy1 = posy1-leng*Math.sin(angolo*Math.PI/180+Math.PI/2);
                        drawLineThick(g,posx1,posy1,posx1-leng*Math.cos(angolo*Math.PI/180+Math.PI/2),posy1-leng*Math.sin(angolo*Math.PI/180+Math.PI/2),2,Color.red);
                        angolone = Math.PI/2 - angolo*Math.PI/180;
                        angolo1 = angolone - 20.0*Math.PI/180.0;
                        angolo2 = angolone + 20.0*Math.PI/180.0;
                        drawLineThick(g,tipx1,tipy1,tipx1-Len*Math.cos(angolo1),tipy1+Len*Math.sin(angolo1),2,Color.red);
                        drawLineThick(g,tipx1,tipy1,tipx1-Len*Math.cos(angolo2),tipy1+Len*Math.sin(angolo2),2,Color.red);
                        // reflected wave vector
                        double tipx2,tipy2; 
                        tipx2 = posx2+leng*Math.cos(angolo*Math.PI/180);
                        tipy2 = posy2-leng*Math.sin(angolo*Math.PI/180);
                        drawLineThick(g,posx2,posy2,posx2+leng*Math.cos(angolo*Math.PI/180),posy2-leng*Math.sin(angolo*Math.PI/180),2,Color.black);
                        angolone = angolo*Math.PI/180;
                        angolo1 = angolone - 20.0*Math.PI/180.0;
                        angolo2 = angolone + 20.0*Math.PI/180.0;
                        drawLineThick(g,tipx2,tipy2,tipx2-Len*Math.cos(angolo1),tipy2+Len*Math.sin(angolo1),2,Color.black);
                        drawLineThick(g,tipx2,tipy2,tipx2-Len*Math.cos(angolo2),tipy2+Len*Math.sin(angolo2),2,Color.black);

                        // reflected electric field
                        if(state.ReflectionTM.Real() < 0.0){
                            tipx2 = posx2-leng*Math.cos(angolo*Math.PI/180+Math.PI/2);
                            tipy2 = posy2+leng*Math.sin(angolo*Math.PI/180+Math.PI/2);
                            drawLineThick(g,posx2,posy2,tipx2,tipy2,2,Color.red);
                            angolone = angolo*Math.PI/180 - Math.PI/2;
                            angolo1 = angolone - 20.0*Math.PI/180.0;
                            angolo2 = angolone + 20.0*Math.PI/180.0;
                            drawLineThick(g,tipx2,tipy2,tipx2-Len*Math.cos(angolo1),tipy2+Len*Math.sin(angolo1),2,Color.red);
                            drawLineThick(g,tipx2,tipy2,tipx2-Len*Math.cos(angolo2),tipy2+Len*Math.sin(angolo2),2,Color.red);
                        }
                        else{
                            tipx2 = posx2+leng*Math.cos(angolo*Math.PI/180+Math.PI/2);
                            tipy2 = posy2-leng*Math.sin(angolo*Math.PI/180+Math.PI/2);
                            drawLineThick(g,posx2,posy2,posx2+leng*Math.cos(angolo*Math.PI/180+Math.PI/2),posy2-leng*Math.sin(angolo*Math.PI/180+Math.PI/2),2,Color.red);
                            angolone = angolo*Math.PI/180 + Math.PI/2;
                            angolo1 = angolone - 20.0*Math.PI/180.0;
                            angolo2 = angolone + 20.0*Math.PI/180.0;
                            drawLineThick(g,tipx2,tipy2,tipx2-Len*Math.cos(angolo1),tipy2+Len*Math.sin(angolo1),2,Color.red);
                            drawLineThick(g,tipx2,tipy2,tipx2-Len*Math.cos(angolo2),tipy2+Len*Math.sin(angolo2),2,Color.red);
                        }
                        //g.setColor(Color.white);
                        //fillCircle(posx1, posy1, 12, g);
                        //fillCircle(posx2, posy2, 12, g);
                        //g.setColor(Color.blue);
                        //drawCircle(posx1, posy1, 12, g);
                        //fillCircle(posx1, posy1, 5, g);
                        //drawCircle(posx2, posy2, 12, g);
                        //fillCircle(posx2, posy2, 5, g);

                        // Reflected Path
                        if(state.ReflectionTM.Real() < 0.0){
                            fillCircleThick(g, posx1, posy1, 8.0, 2, Color.blue);
                            fillCircleThick(g, posx2, posy2, 8.0, 2, Color.blue);
                            fillCircleThick(g, posx1, posy1, 6.0, 2, Color.white);
                            fillCircleThick(g, posx2, posy2, 6.0, 2, Color.white);
                            fillCircleThick(g, posx1, posy1, 3.0, 2, Color.blue);
                            drawLineThick(g, posx2-4, posy2-4,posx2+4, posy2+4,2,Color.blue);
                        drawLineThick(g, posx2+4, posy2-4,posx2-4, posy2+4,2,Color.blue);
                        }
                        else{
                            fillCircleThick(g, posx1, posy1, 8.0, 2, Color.blue);
                            fillCircleThick(g, posx2, posy2, 8.0, 2, Color.blue);
                            fillCircleThick(g, posx1, posy1, 6.0, 2, Color.white);
                            fillCircleThick(g, posx2, posy2, 6.0, 2, Color.white);
                            fillCircleThick(g, posx1, posy1, 3.0, 2, Color.blue);
                            fillCircleThick(g, posx2, posy2, 3.0, 2, Color.blue);
                        }
                        g.setColor(Color.blue);
                        MaestroG.special2("H","","","",g,14,(int)posx1-15,(int)posy1-15);
                        MaestroG.special2("H","","","",g,14,(int)posx2-25,(int)posy2);

                        g.setColor(Color.red);
                        MaestroG.special2("E","","","",g,14,(int)tipx1+10,(int)tipy1+10);
                        MaestroG.special2("E","","","",g,14,(int)tipx2+10,(int)tipy2-10);
                    }
                }
                   
                //=======================================================================================
                
                g.setColor(Color.blue);
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		g.setFont(new Font("SanSerif",Font.PLAIN,12));
		g.getFontMetrics();
                int goup, goup2;
                goup = 8; goup2 = goup+4;
                
                fm = g.getFontMetrics();
                str = fm.stringWidth("d  = "+MaestroA.rounder(state.dist,4)+" [ m ]");
		MaestroG.special("","d","  = "+MaestroA.rounder(state.dist,4)+" [ m ]","",g,12,x[3]-str/2,getSize().height-goup);
		
                g.setColor(Color.black);
                g.drawLine(xtower1, getSize().height-goup2, x[3]-2*str/3, getSize().height-goup2);
                g.drawLine(xtower2, getSize().height-goup2, x[3]+2*str/3, getSize().height-goup2);
                MaestroG.drawArrow(xtower1+10,getSize().height-goup2,8,g);
                MaestroG.drawArrow(xtower2-10,getSize().height-goup2,7,g);
                g.drawLine(xtower1, getSize().height-goup-9, xtower1, getSize().height-goup);
                g.drawLine(xtower2, getSize().height-goup-9, xtower2, getSize().height-goup);
                
                if(IsTE){
                    if(state.ReflectionTE.Imaginary() >=0){
                        MaestroG.subscripterSym("\u0393","E","(P) = "+MaestroA.rounder(state.ReflectionTE.Real(), 5)+
                                " + j "+MaestroA.rounder(state.ReflectionTE.Imaginary(), 6),g,13,whereGamma,yGamma);
                    }
                    else{
                        MaestroG.subscripterSym("\u0393","E","(P) = "+MaestroA.rounder(state.ReflectionTE.Real(), 5)+
                                " - j "+MaestroA.rounder(Math.abs(state.ReflectionTE.Imaginary()), 6),g,13,whereGamma,yGamma);
                    }
                }
                else{
                    if(state.ReflectionTM.Imaginary() >=0){
                        MaestroG.subscripterSym("\u0393","H","(P) = "+MaestroA.rounder(state.ReflectionTM.Real(), 5)+
                                " + j "+MaestroA.rounder(state.ReflectionTM.Imaginary(), 6),g,13,whereGamma,yGamma);
                    }
                    else{
                        MaestroG.subscripterSym("\u0393","H","(P) = "+MaestroA.rounder(state.ReflectionTM.Real(), 5)+
                                " - j "+MaestroA.rounder(Math.abs(state.ReflectionTM.Imaginary()), 6),g,13,whereGamma,yGamma);
                    }
                }
                g.setColor(Color.black);
                g.drawLine(xarrow1,ybase-ytop1,xarrow1,ybase);
		g.drawLine(xarrow1-5,ybase-ytop1,xarrow1+5,ybase-ytop1);
                if(ytop1 < 20){
                    MaestroG.drawArrow(xarrow1,ybase-ytop1-10,6,g);
                    if(ytop1 > 0 && xbounce >= 15){MaestroG.drawArrow(xarrow1,ybase+10,5,g);}
                    g.setColor(Color.blue);
                    MaestroG.subscripterSymbol("h","1","",g,15,xarrow1-22,ybase-ytop1/2-7);
                }
                else{
                    MaestroG.drawArrow(xarrow1,ybase-ytop1+10,5,g);
                    MaestroG.drawArrow(xarrow1,ybase-10,6,g);
                    g.setColor(Color.blue);
                    MaestroG.subscripterSymbol("h","1","",g,15,xarrow1-22,ybase-ytop1/2);
                }
                
                g.setColor(Color.black);
                g.drawLine(xarrow2,ybase-ytop2,xarrow2,ybase);
                g.drawLine(xarrow2-5,ybase-ytop2,xarrow2+5,ybase-ytop2);
		if(ytop2 < 20){
                    MaestroG.drawArrow(xarrow2,ybase-ytop2-10,6,g);
                    if(ytop2 != 0 && xbounce < (xtower2-xtower1-15)){MaestroG.drawArrow(xarrow2,ybase+10,5,g);}
                    g.setColor(Color.blue);
                    MaestroG.subscripterSymbol("h","2","",g,15,xarrow2+10,ybase-ytop2/2-7);
                }
                else{
                    MaestroG.drawArrow(xarrow2,ybase-ytop2+10,5,g);
                    MaestroG.drawArrow(xarrow2,ybase-10,6,g);
                    g.setColor(Color.blue);
                    MaestroG.subscripterSymbol("h","2","",g,15,xarrow2+10,ybase-ytop2/2);
                }
                
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                g.setColor(Color.yellow);
                MaestroG.fillCircle(xtower1, ybase-ytop1, 8, g);
                g.setColor(Color.black);
                MaestroG.drawCircle(xtower1, ybase-ytop1, 8, g);
		
                g.setColor(Color.yellow);
                MaestroG.fillCircle(xtower2, ybase-ytop2, 8, g);
                g.setColor(Color.black);
                MaestroG.drawCircle(xtower2, ybase-ytop2, 8, g);
	
		g.setFont(new Font("SanSerif",Font.PLAIN,12));
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                
                
                g.setColor(Color.white);
                
            if(state.GroundChoose == 1){
                //epsilon_r = 1.0;
                //sigma = 1.0E130;
                MaestroG.subscripter3("Perfect Conductor","","",g,14,getSize().width/2-50,getSize().height-52);
            }
            else if(state.GroundChoose == 2){
                //epsilon_r = 5.0;
                //sigma = 1.0E-3;
                MaestroG.subscripter3("Dry Poor Ground","","",g,14,getSize().width/2-50,getSize().height-52);
            }
            else if(state.GroundChoose == 3){
                //epsilon_r = 15.0;
                //sigma = 5.0E-3;
                MaestroG.subscripter3("Average Ground","","",g,14,getSize().width/2-50,getSize().height-52);
            }
            else if(state.GroundChoose == 4){
                //epsilon_r = 30.0;
                //sigma = 2.0E-2;
                MaestroG.subscripter3("Wet Good Ground","","",g,14,getSize().width/2-50,getSize().height-52);
            }
            else if(state.GroundChoose == 5){
                //epsilon_r = 81.0;
                //sigma = 1.0e-2;
                MaestroG.subscripter3("Fresh Water","","",g,14,getSize().width/2-50,getSize().height-52);
            }
            else if(state.GroundChoose == 6){
                //epsilon_r = 81.0;
                //sigma = 5.0;
                MaestroG.subscripter3("Sea Water","","",g,14,getSize().width/2-50,getSize().height-52);
            }
            
                g.setColor(Color.black);
                
            if(state.GroundChoose == 1){
                MaestroG.superscripter("\u03c3 \u2192 ","","\u221e  [S/m]", g, 13, getSize().width/2-50,getSize().height-30);
            }
            else if(state.GroundChoose == 2){
                MaestroG.superscripter("\u03c3 = 10","-3","  [S/m]", g, 13, getSize().width/2-90,getSize().height-30);
                MaestroG.subscripter("\u03b5","r"," = 5.0", g, 14, getSize().width/2+50,getSize().height-30);
            }
            else if(state.GroundChoose == 3){
                MaestroG.superscripter("\u03c3 = 5 \u00b7 10","-3","  [S/m]", g, 13, getSize().width/2-90,getSize().height-30);
                MaestroG.subscripter("\u03b5","r"," = 15.0", g, 14, getSize().width/2+50,getSize().height-30);
            }
            else if(state.GroundChoose == 4){
                MaestroG.superscripter("\u03c3 = 2 \u00b7 10","-2","  [S/m]", g, 13, getSize().width/2-90,getSize().height-30);
                MaestroG.subscripter("\u03b5","r"," = 30.0", g, 14, getSize().width/2+50,getSize().height-30);
            }
            else if(state.GroundChoose == 5){
                MaestroG.superscripter("\u03c3 = 10","-2","  [S/m]", g, 13, getSize().width/2-90,getSize().height-30);
                MaestroG.subscripter("\u03b5","r"," = 81.0", g, 14, getSize().width/2+50,getSize().height-30);
            }
            else if(state.GroundChoose == 6){
                MaestroG.superscripter("\u03c3 = 5.0","","  [S/m]", g, 13, getSize().width/2-90,getSize().height-30);
                MaestroG.subscripter("\u03b5","r"," = 81.0", g, 14, getSize().width/2+50,getSize().height-30);
            }
            
                g.setColor(Color.black);
		// Label POINTS
                MaestroG.special2("A","","","",g,16,xtower1-5,ybase-ytop1-15);
                MaestroG.special2("C","","","",g,16,xtower2-5,ybase-ytop2-15);
                if((Tower1 != 0) && (Tower2 != 0)){MaestroG.special2("P","","","",g,16,xtower1+xbounce-5,ybase+17);}
                
                if(xbounce < 15 && Tower1 !=0){
                    MaestroG.special2("B","","","",g,16,xtower1-5-(15-xbounce),ybase+17);
                }
                else{
                    MaestroG.special2("B","","","",g,16,xtower1-5,ybase+17);
                }
                
                if(xbounce > (xtower2-xtower1-15) && (Tower2 != 0)){
                    MaestroG.special2("D","","","",g,16,xtower2-5+xbounce-(xtower2-xtower1-15),ybase+17);
                }
                else{
                    MaestroG.special2("D","","","",g,16,xtower2-5,ybase+17);
                }
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
	    }
            
            g.setColor(Color.black);
            g.setFont(new Font("SanSerif",Font.BOLD,12));
	    g.drawString("Grazing Angle", 100,yGamma);
	    MaestroG.special5("\u0398"," = "+MaestroA.rounder(state.bounce_angle,3)+" \u00ba","","",g,13,200,yGamma);
            
            MaestroG.subscripterSym("h","1"," = "+state.Tower1_height+" m", g, 13, 50, 20);
	    MaestroG.subscripterSym("h","2"," = "+state.Tower2_height+" m", g, 13,getSize().width-110, 20);
            
            
    }
    
    public static void drawLineThick(Graphics g, double x1, double y1, double x2, double y2, int thick, Color color){
	
        Graphics2D g2d = (Graphics2D)g;
        g2d.setPaint(color);
        g2d.setStroke(new BasicStroke(thick,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
        
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        
        Line2D.Double line = new Line2D.Double(x1,y1,x2,y2);
        g2d.draw(line);
  
        g2d.setStroke(new BasicStroke(1));
        //g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
    }
    
    public static void drawLineThickDashed(Graphics g, double x1, double y1, double x2, double y2, int thick, Color color){
	
        Graphics2D g2d = (Graphics2D)g;
        g2d.setPaint(color);
        float[] dashPattern = {10,5};// Add these lines to make line dotted
        g2d.setStroke(new BasicStroke(1.0F,BasicStroke.CAP_BUTT,BasicStroke.JOIN_MITER,10.0F,dashPattern,0));
        
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        
        Line2D.Double line = new Line2D.Double(x1,y1,x2,y2);
        g2d.draw(line);
  
        g2d.setStroke(new BasicStroke(1));
        //g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
    }
    
    public static void drawCircle(int x, int y, int radius, Graphics g){
		g.drawOval(x-radius/2,y-radius/2,radius,radius);
    }
    
    public static void fillCircle(int x, int y, int radius, Graphics g){
		g.fillOval(x-radius/2,y-radius/2,radius,radius);
    }
    
    private void drawArcThick(Graphics g, double xCenter, double yCenter, double Radius, double Radius2, double startangle, double endangle, int thick, Color color){
	
        Graphics2D g2d = (Graphics2D)g;
        g2d.setPaint(color);
        g2d.setStroke(new BasicStroke(thick));
        
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        Arc2D.Double arc_one = new Arc2D.Double(xCenter,yCenter,Radius,Radius2,startangle,endangle,0);
        g2d.draw(arc_one);
  
        g2d.setStroke(new BasicStroke(1));
        //g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
    }
    
    private void drawCircleThick(Graphics g, double xCenter, double yCenter, double Radius, int thick, Color color){
	
        Graphics2D g2d = (Graphics2D)g;
        g2d.setPaint(color);
        g2d.setStroke(new BasicStroke(thick, BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL));
        
        //g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        
        Ellipse2D.Double circle = new Ellipse2D.Double(xCenter-Radius,yCenter-Radius,2*Radius,2*Radius);
        g2d.draw(circle);
        g2d.setStroke(new BasicStroke(1));
        //g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
    }
    
    private void fillCircleThick(Graphics g, double xCenter, double yCenter, double Radius, int thick, Color color){
	
        Graphics2D g2d = (Graphics2D)g;
        g2d.setPaint(color);
        g2d.setStroke(new BasicStroke(thick, BasicStroke.CAP_BUTT,BasicStroke.JOIN_BEVEL));
        
        //g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        
        Ellipse2D.Double circle = new Ellipse2D.Double(xCenter-Radius,yCenter-Radius,2*Radius,2*Radius);
        g2d.fill(circle);
        g2d.setStroke(new BasicStroke(1));
        //g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
    }
    
    private void FillArcTransp(Graphics g, double xCenter, double yCenter, double Radius, double startangle, double endangle, Color color, double alphachan){
	int rule; float alpha;
        rule = AlphaComposite.SRC_OVER;
        alpha = (float)alphachan;
        
        Graphics2D g2d = (Graphics2D)g;
        g2d.setPaint(color);
        //g2d.setStroke(new BasicStroke(thick));
        g2d.setComposite(AlphaComposite.getInstance(rule, alpha));
                
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        
        Arc2D.Double arc_one = new Arc2D.Double(xCenter,yCenter,Radius,Radius,startangle,endangle,2);
        g2d.fill(arc_one);
  
        //g2d.setStroke(new BasicStroke(1));
        //g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
        g2d.setComposite(AlphaComposite.getInstance(rule, 1.0f));
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
}


    
    public synchronized void setFrequency(double frequency){
	this.frequency = frequency;
    }
    
    public synchronized void setEpsilon(double epsilon_r){
	this.epsilon_r = epsilon_r;
    }
    
    public synchronized void setEpsilon0(double epsilon_r0){
	this.epsilon_r0 = epsilon_r0;
    }
    
    public synchronized void setMu(double mu){
	this.mu_r = mu;
    }
    
    public synchronized void set3D(boolean Is3D){
	this.Is3D = Is3D;
    }
    
    public synchronized void setAntennaLength(double DipoleLength_lambda){
	this.DipoleLength_lambda = DipoleLength_lambda;
    }
    
    public synchronized void setAntennaHeights(double Tower1, double Tower2){
	this.Tower1 = Tower1;
        this.Tower2 = Tower2;
    }
    
    public synchronized void setAntennaRadius(double radius_lambda){
	this.radius_lambda = radius_lambda;
    }
    
    public void setPolarization(boolean IsTE){
        this.IsTE = IsTE;
    }

    
    @Override
    public void paint(Graphics g){
	    if(im == null){
		im = createImage(getSize().width,getSize().height);
		buf = im.getGraphics();
		drawCanvas(buf);
	    }
	    else{
		drawCanvas(buf);
	    }
	    g.drawImage(im,0,0,null);
    }
    
    
    @Override
    public void update(Graphics g){
	paint(g);
    }
    
    public void mouseClicked(MouseEvent evt){
	//if(IsFocusOn){
	  //  IsFocusOn = false;
	  //  repaint();
	//}
	
	//else{
	  //  IsFocusOn = true;
	  //  repaint();
	//}
    }
    
    public void mouseEntered(MouseEvent evt){
	//IsTopoOn = true;
	//repaint();
    }
    public void mouseExited(MouseEvent evt){
	//IsTopoOn = false;
	//repaint();
    }
    
    public void mousePressed(MouseEvent evt){}
    public void mouseReleased(MouseEvent evt){}
}
