// 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 int LeftMargin, RightMargin, TopMargin, BottomMargin;
    private Font labfont;
    private Font symbfont;
    private Font symbfont2;
    private Font labfont2;
    private Font labfont4;
    private Font labfont3;
    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 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;
    public boolean Is3D;
    NewGuide_State state;
    
    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;
	
	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;
	
	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.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);
        
	//Draw the background	
            g.setColor(Color.black);
            //set the arrays
            x[0] = getSize().width/2 - state.s30;
            x[1] = x[0] - state.s7;
            x[2] = getSize().width - state.s50;

            y[0] = getSize().height - state.s20;
            y[1] = getSize().height/2;

            g.clearRect(0,0,getSize().width-1,getSize().height-1);

            //----------------------------------------------------------
            g.setColor(Color.black);
            g.setFont(new Font("SanSerif",Font.PLAIN,state.font12));
            int xf = x[0] + state.s10;
            int yf = getSize().height - state.s15;
            double f_normalized;
            int fonto = state.font14;

            if(frequency < 1.0E3){
                f_normalized = frequency;
                MaestroG.special("","f","  =  "+MaestroA.rounder(f_normalized,6)+"   [ Hz ]","",g,fonto,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,fonto,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,fonto,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,fonto,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,fonto,xf,yf);
            }
            else{
                f_normalized = frequency/1.0E12;
                MaestroG.special("","f","  =  "+MaestroA.rounder(f_normalized,6)+"   [ THz ]","",g,fonto,xf,yf);
            }
            //-----------------------------------------------------------------------------------
            String lambda, rho;
            g.setFont(symbfont2);
            g.getFontMetrics();
            lambda="\u03bb";
            rho ="\u03c1";

            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
            g.setColor(Color.blue);
            g.setFont(new Font("Serif",Font.ITALIC,state.font16));

            g.getFontMetrics();
            g.drawString("d",x[0] + state.s30,state.s25);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
            g.setFont(new Font("Serif",Font.PLAIN,state.font16));
            g.getFontMetrics();
            g.drawString("   = "+MaestroA.rounder(DipoleLength_lambda,4)+"  "+lambda,x[0]+state.s30,state.s25);
		
	    if(IsFocusOn){
                // this is disabled here
	    }
	    else{	
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        
		//Arc for theta
		int xCenter = x[0];
		int yCenter = y[1];
		int Radius = state.s25;
		int beginAngle = 0;
		int Angle = -30;
		int raio = 2*Radius;
		
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                
                // theta angle arc
                g.setColor(Color.cyan);
		g.fillArc(xCenter-Radius,yCenter-Radius,raio,raio,beginAngle,Angle);
		g.setColor(Color.black);
		g.drawArc(xCenter-Radius,yCenter-Radius,raio,raio,beginAngle,Angle);
		
                // theta angle symbol
                g.setColor(Color.blue);
		g.setFont(new Font("Serif",Font.ITALIC,state.font18));
		g.drawString("\u03b8",x[0]+state.s40,y[1]+state.s18);
		g.setFont(new Font("SanSerif",Font.PLAIN,state.font12));
		g.setColor(Color.black);
                
                int endpoint = state.s75;
                //draw antenna  ----------------------------------------------------
		//draw paraboloid profile - just paint an arc
		//drawArcThick(g, (double)(xCenter-endpoint/3), (double)(yCenter-endpoint), (double)(2*endpoint)*5.0/10.0, (double)(2*endpoint), 110.0, 140.0, state.s3, Color.lightGray);
                
                //Better parapoloid profile with arc + lines
                int xforw = -state.s20;
                int xmid = x[1];
                int ymid = yCenter; //(double)(50*getSize().height/100);
                int Raggio = state.s100;
                int Raggio3 = state.s122;
                int Raggio2 = state.s70;
                
                MaestroG.drawArcThick(g, (double)(xmid+xforw-state.s2), (double)(ymid-Raggio3/2), 
                      (double)Raggio2, (double)Raggio3, 133.0, 92.0, state.s2, Color.gray.brighter());
                
                g.setColor(Color.white);
                // remove unwanted part of arc
                //g.fillRect(30*getSize().width/100+state.s37+xforw, ymid-44*Raggio/100-state.s30, state.s19, state.s150);
                // short lines tangent to arc to simulate paraboloid shape
                MaestroG.drawLineThick(g, xmid+state.s7+xforw, (double)ymid-44*Raggio/100,
                        xmid+state.s25+xforw, (double)ymid-44*Raggio/100 - state.s30, state.s2, Color.gray.brighter());
                MaestroG.drawLineThick(g, xmid+state.s7+xforw, (double)ymid+44*Raggio/100,
                        xmid+state.s25+xforw, (double)ymid+44*Raggio/100 + state.s30, state.s2, Color.gray.brighter());
                //g.setColor(Color.pink);
                //g.fillRect(30*getSize().width/100+state.s18+xforw, y[0]-state.s20, state.s50, state.s180);
                
                //draw axes
		g.setColor(Color.black);
		g.drawLine(x[0],state.s20,x[0],y[0]); 
		//MaestroG.drawArrow(x[0],state.s20,5,g);
                MaestroG.drawArrowScaled(x[0],state.s22, 1, 1.4*state.sfactor, g);
                
		g.drawLine(x[0],y[1],x[0],y[1]+state.s15);
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                g.setColor(Color.black);
		MaestroG.subscripterSymbol3B("r","a","",g,state.font16,x[0]-state.s26,state.s22);
		
                g.setColor(Color.black);
		MaestroG.subscripter("0","","",g,state.font16,x[1]-state.s10,yCenter+state.s5);
                MaestroG.subscripter("z","","",g,state.font16,x[2]+state.s10,y[1]-state.s9);
                MaestroG.subscripterSymbol4B("a","","",g,state.font16,x[1]-state.s15,yCenter-endpoint+state.s5);
                
                g.drawLine(x[1]+state.s2,y[1],x[2]+state.s10,y[1]);
		//MaestroG.drawArrow(x[2]+state.s10,y[1],7,g);
                MaestroG.drawArrowScaled(x[2]+state.s8,y[1], 3, 1.4*state.sfactor, g);
		g.drawLine(x[1]+state.s2,yCenter-endpoint,xCenter,yCenter-endpoint);
		
                //draw measurement arrows
		g.setColor(Color.gray);
		int xarrow = x[0] - state.s70;
		
		g.drawLine(xarrow,y[1]-endpoint,xarrow,y[1]+endpoint);
		//MaestroG.drawArrow(xarrow,y[1]-(endpoint-state.s10),5,g);
                MaestroG.drawArrowScaled(xarrow,y[1]-(endpoint-state.s12), 1, 1.4*state.sfactor, g);
		
                //MaestroG.drawArrow(xarrow,y[1]+(endpoint-state.s10),6,g);
		MaestroG.drawArrowScaled(xarrow,y[1]+(endpoint-state.s12), 2, 1.4*state.sfactor, g);
		
                //MaestroG.drawArrow(xarrow,y[1]-state.s10,6,g);
		MaestroG.drawArrowScaled(xarrow,y[1]-state.s12, 2, 1.4*state.sfactor, g);
		
                //MaestroG.drawArrow(xarrow,y[1]+state.s10,5,g);
		MaestroG.drawArrowScaled(xarrow,y[1]+state.s12, 1, 1.4*state.sfactor, g);
		
                g.drawLine(xarrow-state.s5,y[1],xarrow + state.s5,y[1]);
		g.drawLine(xarrow-state.s5,y[1]-endpoint,xarrow + state.s5,y[1]-endpoint);
		g.drawLine(xarrow-state.s5,y[1]+endpoint,xarrow + state.s5,y[1]+endpoint);
		
                g.setColor(Color.blue);
		g.setFont(new Font("Serif",Font.ITALIC + Font.BOLD,state.font16));
		g.drawString("d",xarrow + state.s10,y[1]-endpoint/2);
                g.setFont(new Font("Serif",Font.PLAIN + Font.BOLD,state.font14));
                g.drawString("__",xarrow + state.s7,y[1]-endpoint/2);
		g.setFont(new Font("Serif",Font.PLAIN + Font.BOLD,state.font16));
                g.drawString("2",xarrow + state.s10,y[1]-endpoint/2 + state.s16);
		g.setFont(new Font("Serif",Font.ITALIC + Font.BOLD,state.font16));
		g.drawString("d",xarrow + state.font10,y[1]+endpoint/2);
                g.setFont(new Font("Serif",Font.PLAIN + Font.BOLD,state.font14));
		g.drawString("__",xarrow + state.s7,y[1]+endpoint/2);
                g.setFont(new Font("Serif",Font.PLAIN + Font.BOLD,state.font16));
                g.drawString("2",xarrow + state.s10,y[1]+endpoint/2 + state.s14);
		g.setFont(new Font("SanSerif",Font.PLAIN + Font.BOLD,state.font15));
		
		g.setColor(Color.red);
		
                int xtip, ytip;
                xtip = x[0] + state.s75;
                ytip = y[1] + state.s45;
                
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                
                //radial line to point P
		g.drawLine(x[0],y[1],xtip,ytip);
		
		//draw Field vectors
		g.setColor(Color.red);
		//E_theta
		g.drawLine(xtip,ytip,xtip - state.s12,ytip + state.s20);
		g.drawLine(xtip - state.s12,ytip + state.s20,xtip - state.s10,ytip + state.s10);
		g.drawLine(xtip - state.s12,ytip + state.s20,xtip - state.s4,ytip + state.s13);
		
		MaestroG.subscripterSymbol2("E","\u03b8","",g,state.font16,xtip,ytip+state.s20);
		
                //point P
		g.setColor(Color.green);
		MaestroG.fillCircle(xtip,ytip,state.s6,g);
		g.setColor(Color.black);
		MaestroG.drawCircle(xtip,ytip,state.s6,g);
		
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
	    }
    }
    
    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);
}

    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 setAntennaRadius(double radius_lambda){
	this.radius_lambda = radius_lambda;
    }
    
    @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){}
}
