import java.awt.*;
import java.awt.event.*;

public class NewGuideCanvas2 extends Canvas {
    private static final Color ccolor1 = new Color(50,204,153);
    private static final Color bgcolor = Color.white;
    private static final Color bgcolor2 = new Color(255,255,250);
    private static final Color medium1Color = Color.yellow;
    private static final Color medium2Color = Color.cyan;

    private static final Color colore1 = new Color(230,230,230);
    private static final Color colore2 = new Color(120,120,120);
    private static final Color colore3 = new Color(250,10,10);
    private static final Color colore4 = new Color(250,190,190);
    private static final Color colore5 = Color.red;
    private static final Color colore6 = new Color(190,190,190);
    private static final Color colore7 = new Color(200,255,255);
    private static final Color colore8 = new Color(220,255,255);
    private static final Color colore9 = new Color(155,155,255);
    private static final Color colore10 = new Color(255,220,0);
    private static final Color colore11 = new Color(200,200,200);
    
    
    private int LeftMargin=20, RightMargin=10, TopMargin=10, BottomMargin=10;
    private Font labfont = new Font("SanSerif",Font.PLAIN,10);
    private Font symbolfont= new Font("Serif",Font.PLAIN,16);
    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 yBottom;
    private int x[], y[];
    private double frequency, epsilon_r, epsilon_r0, mu_r, phase_velocity, phase_velocity0;
    private double wavelength, distance, point_distance, theta_angle, phi_angle;
    
    private static final double epsilon0 = 8.841941286E-12; // approximate value
    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 Image im;
    private Graphics buf;
    private String stmp;
    private double temp;
    private boolean IsFocusOn, IsTopoOn;
    public boolean Is3D;
    NewGuide_State state;
    
    public NewGuideCanvas2(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);
        symbolfont= new Font("Serif",Font.PLAIN,state.font16);
        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(bgcolor2);
	x = new int[5];
	y = new int[5];
		
	epsilon_r = 1.0;
	epsilon_r0 = 1.0;
	mu_r = 1.0;
	frequency = 1.0E9;
	phi_angle = 45.0;//degrees
	theta_angle = 45.0;//degrees
	point_distance = 10.0;//wavelengths
	
	Is3D = true;
		
	wavelength = light_velocity/frequency/Math.sqrt(epsilon_r);
	distance = point_distance * wavelength;
    }

        public void drawCanvas(Graphics g){
	
            g.clearRect(0,0,getSize().width,getSize().height);
	
                draw3D(g);    
        }
    
	private void drawWire(int x1, int y1, int x2, int y2, int mode, Graphics g){
		//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);
		}
		g.setColor(Color.white);
	}

	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.drawOval(x-radius,y-radius,2*radius,2*radius);
	}
	
        private void fillCircle(int x, int y, int radius, Color c, Graphics g){
		g.setColor(c);
		g.fillOval(x-radius,y-radius,2*radius,2*radius);
	}
	
	private void drawEllipse(int x, int y, int radius1, int radius2, Color c, Graphics g){
		g.setColor(c);
		g.drawOval(x-radius1,y-radius2,2*radius1,2*radius2);
	}
        
	private void draw3D(Graphics g){    
                Graphics2D g2d = (Graphics2D)g;
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		wavelength = light_velocity/frequency/Math.sqrt(epsilon_r);
		distance = point_distance * wavelength;
		
		//Draw the background	
		g.setColor(Color.black);
		
		//set the arrays
		x[0] = getSize().width/2-state.s40;
		y[0] = getSize().height/2;

		g.clearRect(0,0,getSize().width-1,getSize().height-1);
		
		
                //if(IsFocusOn){
		
                //}
                //else
		{	
		
		String phi, theta, deg, lambda;
		
		g.setColor(new Color(150,0,0));
		lambda="\u03bb";
		theta="\u03b8";
		phi="\u03c6";
		deg="\u00ba";
		
                g.setFont(labfont4);
		g.getFontMetrics();
		
		int xc = x[0]+x[0]*3/4;
		int yc = state.s30;
				
		g.setFont(new Font("Serif",Font.PLAIN,state.font14));
		g.drawString("R",xc-state.s12,state.s15);
		g.setFont(new Font("SanSerif",Font.PLAIN,state.font12));
		
		g.drawString("= "+point_distance+" "+lambda,xc,state.s15);
				
		if(distance == 0.0){
		    g.drawString("= 0.0 [ m ]",xc,yc);	
		}
		else if(distance < 1.0E-9 && distance > 0.0){
		    g.drawString("= "+MaestroA.rounder(distance*1.0e9,4)+" [ nm ]",xc,yc);	
		}
		else if(distance < 1.0E-6 && distance >= 1.0E-9){
		    g.drawString("= "+MaestroA.rounder(distance*1.0e9,4)+" [ nm ]",xc,yc);
		}
		else if(distance < 1.0E-3 && distance >= 1.0E-6){
		    g.drawString("= "+MaestroA.rounder(distance*1.0e6,4)+" [ \u00b5m ]",xc,yc);	
		}
		else if(distance < 1.0 && distance >= 1.0E-3){
		    g.drawString("= "+MaestroA.rounder(distance*1.0e3,4)+" [ mm ]",xc,yc);	
		}
		else if((distance < 1000.0 && distance >= 1.0 ) || distance == 0.0){
		    g.drawString("= "+MaestroA.rounder(distance,4)+" [ m ]",xc,yc);		
		}
		else if(distance >= 1000.0 && distance < 1.0E6){
		    g.drawString("= "+MaestroA.rounder(distance/1.0e3,4)+" [ km ]",xc,yc);		
		}
		else if(distance >= 1.0E6 && distance < 1.0E9){
		    g.drawString("= "+MaestroA.rounder(distance/1.0e6,4)+" [ Mm ]",xc,yc);	
		}
		else if(distance >= 1.0E9){
		    g.drawString("= "+MaestroA.rounder(distance/1.0e9,4)+" [ Gm ]",xc,yc);	
		}   
		
		xc = x[0]+x[0]*3/4 + state.s20;
		
		g.setColor(Color.blue);
		g.drawString("= "+theta_angle+" "+deg,xc,state.s53);
		g.drawString("= "+phi_angle+" "+deg,xc,state.s68);
		
		g.setFont(new Font("Serif",Font.PLAIN,state.font15));
		g.drawString("\u03b8",xc-state.s12,state.s53);
		g.drawString("\u03c6",xc-state.s12,state.s68);
		g.setColor(Color.black);
                
                g.setFont(new Font("SanSerif",Font.PLAIN,state.font11));
                //------------------------------------------------------- Area of spherical front
                int y_area = state.s190;
                int x_area = state.s177;
                
                g.drawString("Area of spherical front",x_area-state.s20,y_area-state.s13);
                g.drawString("S =",x_area - state.s20,y_area);
                
                int fonte = state.font11;

                double test, testprint;
                test = distance * distance * 4.0 * Math.PI;
                if(test < 1.0e-12){
                    testprint = test * 1.0E12;
                    MaestroG.superscripter(""+MaestroA.rounder(testprint,4)+" x 10","-12"," [m\u00b2]",g,fonte,x_area,y_area);
                }
                else if(test >= 1.0e-12 && test < 1.0e-9){
                    testprint = test * 1.0E12;
                    MaestroG.superscripter(""+MaestroA.rounder(testprint,4)+" x 10","-12"," [m\u00b2]",g,fonte,x_area,y_area);
                }
                else if(test >= 1.0e-9 && test < 1.0e-6){
                    testprint = test * 1.0E9;
                    MaestroG.superscripter(""+MaestroA.rounder(testprint,4)+" x 10","-9"," [m\u00b2]",g,fonte,x_area,y_area);
                }
                else if(test >= 1.0e-6 && test < 1.0e-3){
                    testprint = test * 1.0E6;
                    MaestroG.superscripter(""+MaestroA.rounder(testprint,4)+" x 10","-6"," [m\u00b2]",g,fonte,x_area,y_area);
                }
                else if(test >= 1.0e-3 && test < 1.0){
                    testprint = test * 1.0E3;
                    MaestroG.superscripter(""+MaestroA.rounder(testprint,4)+" x 10","-3"," [m\u00b2]",g,fonte,x_area,y_area);
                }
                else if(test >= 1.0 && test < 1.0e3){
                    testprint = test;
                    MaestroG.superscripter(""+MaestroA.rounder(testprint,4)+"",""," [m\u00b2]",g,fonte,x_area,y_area);
                }
                else if(test >= 1.0e3 && test < 1.0e6){
                    testprint = test*1.0e-3;
                    MaestroG.superscripter(""+MaestroA.rounder(testprint,4)+" x 10","3"," [m\u00b2]",g,fonte,x_area,y_area);
                }
                else if(test >= 1.0e6 && test < 1.0e9){
                    testprint = test*1.0e-6;
                    MaestroG.superscripter(""+MaestroA.rounder(testprint,4)+" x 10","6"," [m\u00b2]",g,fonte,x_area,y_area);
                }
                else if(test >= 1.0e9 && test < 1.0e12){
                    testprint = test*1.0e-9;
                    MaestroG.superscripter(""+MaestroA.rounder(testprint,4)+" x 10","9"," [m\u00b2]",g,fonte,x_area,y_area);
                }
                else if(test >= 1.0e12 && test < 1.0e15){
                    testprint = test*1.0e-12;
                    MaestroG.superscripter(""+MaestroA.rounder(testprint,4)+" x 10","12"," [m\u00b2]",g,fonte,x_area,y_area);
                }
                else if(test >= 1.0e15 && test < 1.0e18){
                    testprint = test*1.0e-15;
                    MaestroG.superscripter(""+MaestroA.rounder(testprint,4)+" x 10","15"," [m\u00b2]",g,fonte,x_area,y_area);
                }
                else if(test >= 1.0e18 && test < 1.0e21){
                    testprint = test*1.0e-18;
                    MaestroG.superscripter(""+MaestroA.rounder(testprint,4)+" x 10","18"," [m\u00b2]",g,fonte,x_area,y_area);
                }
                else if(test >= 1.0e21 && test < 1.0e24){
                    testprint = test*1.0e-21;
                    MaestroG.superscripter(""+MaestroA.rounder(testprint,4)+" x 10","21"," [m\u00b2]",g,fonte,x_area,y_area);
                }
                else if(test >= 1.0e24){
                    testprint = test*1.0e-24;
                    MaestroG.superscripter(""+MaestroA.rounder(testprint,4)+" x 10","24"," [m\u00b2]",g,fonte,x_area,y_area);
                }

		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
    
		int radius = getSize().height/2-state.s20;
		int radius1 = radius;
		int axis = getSize().height/2+state.s20;
		int radius2 = radius/3;
		/*
		Color colore1 = new Color(230,230,230);
		Color colore2 = new Color(120,120,120);
		Color colore3 = new Color(250,10,10);
		Color colore4 = new Color(250,190,190);
		Color colore5 = Color.red;
		Color colore6 = new Color(190,190,190);
		Color colore7 = new Color(200,255,255);
		Color colore8 = new Color(220,255,255);
		Color colore9 = new Color(155,155,255);
		Color colore10 = new Color(255,220,0);
		Color colore11 = new Color(200,200,200);
		*/
		
		//draw circular meridian (outer circle of picture) 
		drawCircle(x[0],y[0],radius+state.s2,colore2,g);
		
		//draw Equator
		drawEllipse(x[0],y[0],radius1,radius2,colore1,g);
		
		// draw latitude ellipse
		int latitude;
		double costheta = Math.cos(theta_angle*Math.PI/180.);
		double sintheta = Math.sin(theta_angle*Math.PI/180.);
		latitude = getSize().height/2 - (int)(radius * costheta);
		drawEllipse(x[0],latitude,(int)(radius1 * sintheta),(int)(radius2 * sintheta),colore4,g);
		
		// draw longitude
		double phiref0, phiref1, phiref2, phiref3, phinew;
		int newradius1;
		phiref0 = -108.0;
		phiref1 = - 70.0;
		phiref2 = 70.0;
		phiref3 = 180.0;
		phinew = 0.0;
			
		if(phi_angle >= 0.0 && phi_angle <= 90.0){
		    phinew = phiref0 + phi_angle *108.0/90.0;
		}
		
		else if(phi_angle > 90.0 && phi_angle <= 180.0){
		    phinew = (phi_angle-90.0) *70.0/90.0;
		}
		else if(phi_angle > 180.0 && phi_angle <= 270.0){
		    phinew = phiref2 + (phi_angle-180.0) *110.0/90.0;
		}
		else if(phi_angle > 270.0 && phi_angle <= 360.0){
		    phinew = phiref3 + (phi_angle-270.0) *72.0/90.0;
		}
		newradius1 =(int)(radius * Math.cos(phinew*Math.PI/180.));
		
		int x2, y2, x3, y3, x4, y4;
		double phinew_rad = phinew*Math.PI/180.0;
		x2 = (int)(x[0] + radius1 * sintheta * Math.cos(phinew_rad));
		y2 = (int)(latitude + radius2 * sintheta * Math.sin(-phinew_rad));
		x3 = (int)(x[0] + radius1 * Math.cos(phinew_rad));
		y3 = (int)(y[0] + radius2 * Math.sin(-phinew_rad));
		x4 = x2;
		y4 = (int)((double)x4/(double)x3*(double)y3);
		//Scanned point P (green circle)
		if(phi_angle >90 && phi_angle <270){
		    fillCircle(x2,y2,state.s3,Color.green,g);
		    drawCircle(x2,y2,state.s3,Color.black,g);
		}
		if(phi_angle >=270 || phi_angle <=90){
		}
		else{
		    drawEllipse(x[0],latitude,(int)(radius1 * sintheta),(int)(radius2 * sintheta),colore4,g);
		}
		//draw phi angle
		g.setColor(Color.yellow);
		g.fillArc(x[0]-state.s23,y[0]-state.s10,state.s46,state.s20,-108,108+(int)(phinew));
		g.setColor(new Color(155,5,155));
		g.drawArc(x[0]-state.s23,y[0]-state.s10,state.s46,state.s20,-108,108+(int)(phinew));
		
		
		//redraw front arc of latitude ellipse
		g.setColor(Color.red);
		g.drawArc(x[0]-(int)(radius1 * sintheta),latitude-(int)(radius2 * sintheta),
			  2*(int)(radius1 * sintheta),2*(int)(radius2 * sintheta),180,180);
		
		//connect center to scanned point P (green dot)	
		g.setColor(Color.blue);
		g.drawLine(x[0],y[0],x2,y2);
		
		//projection of P on equatorial plane
		int y5 = y2+y[0]-latitude;
		//connect center to equator along edge of phi angle arc
		g.setColor(Color.lightGray);
		g.drawLine(x[0],y[0],x4,y5);
		g.setColor(Color.black);
		g.drawLine(x4,y5,x3,y3);
		
		//perpendicular line from point P to equatorial plane
		g.setColor(Color.lightGray);
		g.drawLine(x2,y2,x4,y5);
			
		g.setColor(colore2);
		g.drawArc(x[0]-radius1,y[0]-state.s27,2*radius1,2*state.s27,180,180);
		
		int tip = y[0]*5/6;
		g.setColor(Color.gray);
		
		//draw z axis
		g.drawLine(x[0],state.s15,x[0],y[0]); 
		//MaestroG.drawArrow(x[0],state.s15,5,g);
                MaestroG.drawArrowScaled(x[0],state.s15,1,state.sfactor,g);
		g.drawLine(x[0],y[0]+10,x[0],y[0]+radius+state.s10); 
		
		//draw vertical axis portion hidden by the yellow arc
		if(phinew < -90.0){
		    g.setColor(Color.black);
		}
		else{
		    g.setColor(colore11);
		}
		
		g.drawLine(x[0],y[0]+10,x[0],y[0]);
		 
		//draw other axes
		g.setColor(Color.gray);
		// y axis
		g.drawLine(x[0],y[0],x[0]+axis,y[0]);	
		//MaestroG.drawArrow(x[0]+axis,y[0],7,g);
		MaestroG.drawArrowScaled(x[0]+axis,y[0],3,state.sfactor,g);
		
		// x axis
		g.drawLine(x[0],y[0],x[0]-tip,y[0]+tip);
		//draw oblique arrow head
                //MaestroG.drawArrow(x[0]-tip+5,y[0]+tip-5,10,g);
                MaestroG.drawArrowScaled(x[0]-tip+state.s5,y[0]+tip-state.s5,6,state.sfactor,g);
                
		Polygon p = new Polygon();
		p.addPoint(x[0]-tip,y[0]+tip);
		p.addPoint(x[0]-(tip-state.s2),y[0]+(tip-state.s6));
		p.addPoint(x[0]-(tip-state.s6),y[0]+(tip-state.s2));
		//g.drawPolygon(p);
		//g.fillPolygon(p);
		
		//Scanned point P (green circle)
		if(phi_angle <=90 || phi_angle >=270){
		    fillCircle(x2,y2,state.s3,Color.green,g);
		    drawCircle(x2,y2,state.s3,Color.black,g);
		}
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
                
                g.setColor(Color.black);
                g.setFont(new Font("SanSerif",Font.PLAIN,state.font12));
                g.drawString("z",x[0]-state.s12,state.s15);
		g.drawString("y",x[0]+axis,y[0]-state.s10);
		g.drawString("x",x[0]-(tip-state.s12),y[0]+tip);
	    }
    }

    
    public synchronized void setFrequency(double frequency){
	this.frequency = frequency;
    }
    
    public synchronized void setEpsilon(double epsilon_r){
	this.epsilon_r = epsilon_r;
	
    }
    
    public synchronized void setWavelength(double wavelength){
	this.wavelength = wavelength;
    }
    
    public synchronized void setTheta(double theta_angle){
	this.theta_angle = theta_angle;
    }
    
    public synchronized void setPhi(double phi_angle){
	this.phi_angle = phi_angle;
    }
    
    public synchronized void setDistance(double point_distance){
	this.point_distance = point_distance;
    }
    
    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);
    }
    
    
    public void update(Graphics g){
	paint(g);
    }
    
    
}
