/**
 * NewGuideCanvas.java
*/
import java.awt.*;
import java.awt.geom.*;
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 NewGuide_State state;
    private int LeftMargin, RightMargin, TopMargin, BottomMargin;
    private Font labfont = new Font("SanSerif",Font.PLAIN,10);
    private Font symbfont= new Font("Serif",Font.PLAIN,12);
    private Font symbfont2= new Font("Serif",Font.PLAIN,14);
    private Font labfont2= new Font("Serif",Font.BOLD,16);
    private Font labfont4= new Font("Serif",Font.PLAIN,12);
    private 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();
        this.state = state;
	
        LeftMargin = state.s20; 
        RightMargin = state.s10; 
        TopMargin = state.s10; 
        BottomMargin = state.s10;
        labfont = new Font("SanSerif",Font.PLAIN,state.font10);
        symbfont= new Font("Serif",Font.PLAIN,state.font12);
        symbfont2= new Font("Serif",Font.PLAIN,state.font14);
        labfont2= new Font("Serif",Font.BOLD,state.font16);
        labfont4= new Font("Serif",Font.PLAIN,state.font12);
        labfont3 = new Font("SanSerif",Font.PLAIN,state.font12);
        
	IsFocusOn = false;
	IsTopoOn = false;
	IsTE = true;
        
	setBackground(bgcolor);
        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+state.s3;
        int yGamma = getSize().height-state.s27;
        
        Tower1 = state.Tower1_height;
        Tower2 = state.Tower2_height; // meters
        
        Tower_scaling = Math.max(Tower1,Tower2);
        
        //Draw the background	
		g.setColor(Color.black);
		//set the arrays
		//x[0] = getSize().width/2;
                x[0] = state.s33;
		x[1] = x[0] - state.s7;
		x[2] = getSize().width-state.s33;
                x[3] = getSize().width/2;
		
		y[0] = getSize().height-state.s20;
		y[1] = getSize().height/2;
                y[2] = 20;
		g.clearRect(0,0,getSize().width-1,getSize().height-1);
		
                //----------------------------------------------------------
		FontMetrics fm;
                
                g.setColor(Color.black);
		g.setFont(new Font("SanSerif",Font.PLAIN,state.font12));
		int xf = x[3];
		int yf = state.s20;
		double f_normalized;
	
		if(frequency < 1.0E3){
		    f_normalized = frequency;
		    MaestroG.special("","f","  =  "+MaestroA.rounder(f_normalized,6)+"   [ Hz ]","",g,state.font13,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,state.font13,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,state.font13,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,state.font13,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,state.font13,xf,yf);
		}
		else{
		    f_normalized = frequency/1.0E12;
		    MaestroG.special("","f","  =  "+MaestroA.rounder(f_normalized,6)+"   [ THz ]","",g,state.font13,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 = state.s75;
                int xtower1 = x[0] + state.s20;
                int xtower2 = x[2] - state.s20;
                
		// 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] + state.s5;
                int xarrow2 = x[2] - state.s5;
                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 - state.s5, ybase);
                    pH.addPoint(xtower1, (ybase-ytop1));
                    pH.addPoint(xtower1 + state.s5, ybase);
                    g.drawPolygon(pH);
                    g.fillPolygon(pH);
                
                Color tower_color = Color.gray.darker();
                drawLineThick(g, (double)xtower1 - state.s5, (double)ybase, (double)xtower1, (double)(ybase-ytop1), 1, tower_color);
                drawLineThick(g, (double)xtower1 + state.s5, (double)ybase, (double)xtower1, (double)(ybase-ytop1), 1, tower_color);
                
                g.setColor(new Color(240,240,250));
                Polygon pH2 = new Polygon();
                    pH2.addPoint(xtower2 - state.s5, ybase);
                    pH2.addPoint(xtower2, (ybase-ytop2));
                    pH2.addPoint(xtower2 + state.s5, ybase);
                    g.drawPolygon(pH2);
                    g.fillPolygon(pH2);
                drawLineThick(g, (double)xtower2 - state.s5, (double)ybase, (double)xtower2, (double)(ybase-ytop2), 1, tower_color);
                drawLineThick(g, (double)xtower2 + state.s5, (double)ybase, (double)xtower2, (double)(ybase-ytop2), 1, 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 = (double)state.s80;
                double diametro1 = Math.min(diametro,2.0*(double)(xbounce));
                double diametro2 = Math.min(diametro,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,state.font18));
		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,state.font12));
		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);
                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)){
                    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-state.s20),(double)(ybase+state.s10),(double)(xarrow2+state.s20),(double)(ybase+state.s10),state.s20,GroundColor);
                g.setColor(Color.black);
                g.drawLine(xarrow1-state.s20,ybase,xarrow2+state.s20,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 = state.s30, Len = state.s8;
                    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, (double)state.s8, 2, Color.red);
                        fillCircleThick(g, posxD, posyD, (double)state.s6, 2, Color.white);
                        fillCircleThick(g, posxD, posyD, (double)state.s3, 2, Color.red);
                    
                    g.setColor(Color.red);
                    MaestroG.special2("E","","","",g,state.font14,(int)posxD-state.s10,(int)posyD-state.s15);
                    
                    g.setColor(Color.blue);
                    MaestroG.special2("H","","","",g,state.font14,(int)tipxD+state.s10,(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);

                        // Reflected path
                        fillCircleThick(g, posx1, posy1, (double)state.s8, 2, Color.red);
                        fillCircleThick(g, posx2, posy2, (double)state.s8, 2, Color.red);
                        fillCircleThick(g, posx1, posy1, (double)state.s6, 2, Color.white);
                        fillCircleThick(g, posx2, posy2, (double)state.s6, 2, Color.white);
                        fillCircleThick(g, posx1, posy1, (double)state.s3, 2, Color.red);
                        //fillCircleThick(g, posx2, posy2, (double)state.s3, 2, Color.red);
                        
                        // cross for reflected electric field pointing inwards
                        drawLineThick(g, posx2-state.s4, posy2-state.s4,posx2+state.s4, posy2+state.s4,2,Color.red);
                        drawLineThick(g, posx2+state.s4, posy2-state.s4,posx2-state.s4, posy2+state.s4,2,Color.red);
                        
                        g.setColor(Color.red);
                        MaestroG.special2("E","","","",g,state.font14,(int)posx1-state.s10,(int)posy1-state.s15);
                        MaestroG.special2("E","","","",g,state.font14,(int)posx2-state.s23,(int)posy2);

                        g.setColor(Color.blue);
                        MaestroG.special2("H","","","",g,state.font14,(int)tipx1+state.s10,(int)tipy1);
                        MaestroG.special2("H","","","",g,state.font14,(int)tipx2+state.s10,(int)tipy2+state.s10);
                    }
                }
                else{ // Parallel Polarization
                    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                    int leng = state.s30, Len = state.s8;
                    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, (double)state.s8, 2, Color.blue);
                        fillCircleThick(g, posxD, posyD, (double)state.s6, 2, Color.white);
                        fillCircleThick(g, posxD, posyD, (double)state.s3, 2, Color.blue);

                    g.setColor(Color.blue);
                    MaestroG.special2("H","","","",g,state.font14,(int)posxD-state.s20,(int)posyD-state.s10);
                    
                    g.setColor(Color.red);
                    MaestroG.special2("E","","","",g,state.font14,(int)tipxD+state.s10,(int)tipyD+state.s10);
                    
                    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);
                        }
                        
                        // Reflected Path
                        if(state.ReflectionTM.Real() < 0.0){
                            fillCircleThick(g, posx1, posy1, (double)state.s8, 2, Color.blue);
                            fillCircleThick(g, posx2, posy2, (double)state.s8, 2, Color.blue);
                            fillCircleThick(g, posx1, posy1, (double)state.s6, 2, Color.white);
                            fillCircleThick(g, posx2, posy2, (double)state.s6, 2, Color.white);
                            fillCircleThick(g, posx1, posy1, (double)state.s3, 2, Color.blue);
                            drawLineThick(g, posx2-state.s4, posy2-state.s4,posx2+state.s4, posy2+state.s4,2,Color.blue);
                        drawLineThick(g, posx2+state.s4, posy2-state.s4,posx2-state.s4, posy2+state.s4,2,Color.blue);
                        }
                        else{
                            fillCircleThick(g, posx1, posy1, (double)state.s8, 2, Color.blue);
                            fillCircleThick(g, posx2, posy2, (double)state.s8, 2, Color.blue);
                            fillCircleThick(g, posx1, posy1, (double)state.s6, 2, Color.white);
                            fillCircleThick(g, posx2, posy2, (double)state.s6, 2, Color.white);
                            fillCircleThick(g, posx1, posy1, (double)state.s3, 2, Color.blue);
                            fillCircleThick(g, posx2, posy2, (double)state.s3, 2, Color.blue);
                        }
                        g.setColor(Color.blue);
                        MaestroG.special2("H","","","",g,state.font14,(int)posx1-state.s15,(int)posy1-state.s15);
                        MaestroG.special2("H","","","",g,state.font14,(int)posx2-state.s25,(int)posy2);

                        g.setColor(Color.red);
                        MaestroG.special2("E","","","",g,state.font14,(int)tipx1+state.s10,(int)tipy1+state.s10);
                        MaestroG.special2("E","","","",g,state.font14,(int)tipx2+state.s10,(int)tipy2-state.s10);
                    }
                }
                //=======================================================================================
                
                g.setColor(Color.blue);
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		g.setFont(new Font("SanSerif",Font.PLAIN,state.font12));
		g.getFontMetrics();
                int goup, goup2;
                goup = state.s8; 
                goup2 = goup + state.s4;
                
                fm = g.getFontMetrics();
                str = fm.stringWidth("d  = "+MaestroA.rounder(state.dist,4)+" [ m ]");
		MaestroG.special("","d","  = "+MaestroA.rounder(state.dist,4)+" [ m ]","",g,state.font12,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 + state.s10,getSize().height-goup2,8,g);
                //MaestroG.drawArrow(xtower2 - state.s10,getSize().height-goup2,7,g);
                MaestroG.drawArrowScaled(xtower1 + state.s9,getSize().height-goup2,4,state.sfactor,g);
                MaestroG.drawArrowScaled(xtower2 - state.s9,getSize().height-goup2,3,state.sfactor,g);
                
                g.drawLine(xtower1, getSize().height-goup - state.s9, xtower1, getSize().height-goup);
                g.drawLine(xtower2, getSize().height-goup - state.s9, 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,state.font14,whereGamma,yGamma);
                    }
                    else{
                        MaestroG.subscripterSym("\u0393","E","( P ) = "+MaestroA.rounder(state.ReflectionTE.Real(), 5)+
                                " - j "+MaestroA.rounder(Math.abs(state.ReflectionTE.Imaginary()), 6),g,state.font14,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,state.font14,whereGamma,yGamma);
                    }
                    else{
                        MaestroG.subscripterSym("\u0393","H","( P ) = "+MaestroA.rounder(state.ReflectionTM.Real(), 5)+
                                " - j "+MaestroA.rounder(Math.abs(state.ReflectionTM.Imaginary()), 6),g,state.font14,whereGamma,yGamma);
                    }
                }
                g.setColor(Color.black);
                g.drawLine(xarrow1,ybase-ytop1,xarrow1,ybase);
		g.drawLine(xarrow1 - state.s5,ybase-ytop1,xarrow1 + state.s5,ybase-ytop1);
                if(ytop1 < state.s20){
                    //MaestroG.drawArrow(xarrow1,ybase-ytop1 - state.s10,6,g);
                    MaestroG.drawArrowScaled(xarrow1,ybase-ytop1 - state.s9,2,state.sfactor,g);
                    if(ytop1 > 0 && xbounce >= state.s15){
                        //MaestroG.drawArrow(xarrow1,ybase + state.s10,5,g);
                        MaestroG.drawArrowScaled(xarrow1,ybase + state.s9,1,state.sfactor,g);
                    }
                    g.setColor(Color.blue);
                    MaestroG.subscripterSymbol("h","1","",g,state.font15,xarrow1 - state.s22,ybase-ytop1/2 - state.s7);
                }
                else{
                    //MaestroG.drawArrow(xarrow1,ybase-ytop1 + state.s10,5,g);
                    //MaestroG.drawArrow(xarrow1,ybase - state.s10,6,g);
                    
                    MaestroG.drawArrowScaled(xarrow1,ybase-ytop1 + state.s9,1,state.sfactor,g);
                    MaestroG.drawArrowScaled(xarrow1,ybase - state.s9,2,state.sfactor,g);
                    
                    g.setColor(Color.blue);
                    MaestroG.subscripterSymbol("h","1","",g,state.font15,xarrow1 - state.s22,ybase-ytop1/2);
                }
                
                g.setColor(Color.black);
                g.drawLine(xarrow2,ybase-ytop2,xarrow2,ybase);
                g.drawLine(xarrow2 - state.s5,ybase-ytop2,xarrow2 + state.s5,ybase-ytop2);
		if(ytop2 < state.s20){
                    //MaestroG.drawArrow(xarrow2,ybase-ytop2 - state.s10,6,g);
                    MaestroG.drawArrowScaled(xarrow2,ybase-ytop2 - state.s9,2,state.sfactor,g);
                    
                    if(ytop2 != 0 && xbounce < (xtower2-xtower1 - state.s15)){
                        //MaestroG.drawArrow(xarrow2,ybase + state.s10,5,g);
                        MaestroG.drawArrowScaled(xarrow2,ybase + state.s9,1,state.sfactor,g);
                    }
                    g.setColor(Color.blue);
                    MaestroG.subscripterSymbol("h","2","",g,state.font15,xarrow2 + state.s10,ybase-ytop2/2 - state.s7);
                }
                else{
                    //MaestroG.drawArrow(xarrow2,ybase-ytop2 + state.s10,5,g);
                    //MaestroG.drawArrow(xarrow2,ybase - state.s10,6,g);
                    
                    MaestroG.drawArrowScaled(xarrow2,ybase-ytop2 + state.s9,1,state.sfactor,g);
                    MaestroG.drawArrowScaled(xarrow2,ybase - state.s9,2,state.sfactor,g);
                    
                    g.setColor(Color.blue);
                    MaestroG.subscripterSymbol("h","2","",g,state.font15,xarrow2 + state.s10,ybase-ytop2/2);
                }
                
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                g.setColor(Color.yellow);
                MaestroG.fillCircle(xtower1, ybase-ytop1, state.s8, g);
                g.setColor(Color.black);
                MaestroG.drawCircle(xtower1, ybase-ytop1, state.s8, g);
		
                g.setColor(Color.yellow);
                MaestroG.fillCircle(xtower2, ybase-ytop2, state.s8, g);
                g.setColor(Color.black);
                MaestroG.drawCircle(xtower2, ybase-ytop2, state.s8, g);
	
		g.setFont(new Font("SanSerif",Font.PLAIN,state.font12));
		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,state.font14,getSize().width/2 - state.s50,getSize().height - state.s52);
            }
            else if(state.GroundChoose == 2){
                //epsilon_r = 5.0;
                //sigma = 1.0E-3;
                MaestroG.subscripter3("Dry Poor Ground","","",g,state.font14,getSize().width/2 - state.s50,getSize().height - state.s52);
            }
            else if(state.GroundChoose == 3){
                //epsilon_r = 15.0;
                //sigma = 5.0E-3;
                MaestroG.subscripter3("Average Ground","","",g,state.font14,getSize().width/2 - state.s50,getSize().height - state.s52);
            }
            else if(state.GroundChoose == 4){
                //epsilon_r = 30.0;
                //sigma = 2.0E-2;
                MaestroG.subscripter3("Wet Good Ground","","",g,state.font14,getSize().width/2 - state.s50,getSize().height - state.s52);
            }
            else if(state.GroundChoose == 5){
                //epsilon_r = 81.0;
                //sigma = 1.0e-2;
                MaestroG.subscripter3("Fresh Water","","",g,state.font14,getSize().width/2 - state.s50,getSize().height - state.s52);
            }
            else if(state.GroundChoose == 6){
                //epsilon_r = 81.0;
                //sigma = 5.0;
                MaestroG.subscripter3("Sea Water","","",g,state.font14,getSize().width/2 - state.s50,getSize().height - state.s52);
            }
            
                g.setColor(Color.black);
                
            if(state.GroundChoose == 1){
                MaestroG.superscripter("\u03c3 \u2192 ","","\u221e  [S/m]", g, state.font13, getSize().width/2 - state.s50,yGamma);
            }
            else if(state.GroundChoose == 2){
                MaestroG.superscripter("\u03c3 = 10","-3","  [S/m]", g, state.font13, getSize().width/2 - state.s90,yGamma);
                MaestroG.subscripter("\u03b5","r"," = 5.0", g, state.font14, getSize().width/2 + state.s50,yGamma);
            }
            else if(state.GroundChoose == 3){
                MaestroG.superscripter("\u03c3 = 5 \u00b7 10","-3","  [S/m]", g, state.font13, getSize().width/2 - state.s90,yGamma);
                MaestroG.subscripter("\u03b5","r"," = 15.0", g, state.font14, getSize().width/2 + state.s50,yGamma);
            }
            else if(state.GroundChoose == 4){
                MaestroG.superscripter("\u03c3 = 2 \u00b7 10","-2","  [S/m]", g, state.font13, getSize().width/2 - state.s90,yGamma);
                MaestroG.subscripter("\u03b5","r"," = 30.0", g, state.font14, getSize().width/2 + state.s50,yGamma);
            }
            else if(state.GroundChoose == 5){
                MaestroG.superscripter("\u03c3 = 10","-2","  [S/m]", g, state.font13, getSize().width/2 - state.s90,yGamma);
                MaestroG.subscripter("\u03b5","r"," = 81.0", g, state.font14, getSize().width/2 + state.s50,yGamma);
            }
            else if(state.GroundChoose == 6){
                MaestroG.superscripter("\u03c3 = 5.0","","  [S/m]", g, state.font13, getSize().width/2 - state.s90,yGamma);
                MaestroG.subscripter("\u03b5","r"," = 81.0", g, state.font14, getSize().width/2 + state.s50,yGamma);
            }
            
                g.setColor(Color.black);
		// Label POINTS
                MaestroG.special2("A","","","",g,state.font16,xtower1 - state.s5,ybase-ytop1 - state.s15);
                MaestroG.special2("C","","","",g,state.font16,xtower2 - state.s5,ybase-ytop2 - state.s15);
                // Print Label for Point P below ground line
                //if((Tower1 != 0) && (Tower2 != 0)){MaestroG.special2("P","","","",g,state.font16,xtower1+xbounce - state.s5,ybase + state.s15);}
                
                // Print Label for Point P above ground line
                if((Tower1 != 0) && (Tower2 != 0)){MaestroG.special2("P","","","",g,state.font16,xtower1+xbounce - state.s5,ybase - state.s10);}
                
                if(xbounce < 15 && Tower1 !=0){
                    MaestroG.special2("B","","","",g,state.font16,xtower1 - state.s5-(state.s15-xbounce),ybase + state.s15);
                }
                else{
                    MaestroG.special2("B","","","",g,state.font16,xtower1 - state.s5,ybase + state.s15);
                }
                
                if(xbounce > (xtower2-xtower1-15) && (Tower2 != 0)){
                    MaestroG.special2("D","","","",g,state.font16,xtower2 - state.s5+xbounce-(xtower2-xtower1 - state.s15),ybase + state.s15);
                }
                else{
                    MaestroG.special2("D","","","",g,state.font16,xtower2 - state.s5,ybase + state.s15);
                }
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
	    }
            
            g.setColor(Color.black);
            g.setFont(new Font("SanSerif",Font.BOLD,state.font12));
	    g.drawString("Grazing Angle", state.s100,yGamma);
	    MaestroG.special5("\u0398"," = "+MaestroA.rounder(state.bounce_angle,3)+" \u00ba","","",g,state.s13,state.s200,yGamma);
            
            MaestroG.subscripterSym("h","1"," = "+state.Tower1_height+" m", g, state.font13, state.s50, state.s20);
	    MaestroG.subscripterSym("h","2"," = "+state.Tower2_height+" m", g, state.font13,getSize().width - state.s110, state.s20);
    }
    
    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){}
}
