/**
 * NewGuideCanvas2.java
 *
 *
*/
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
//import java.lang.*;

public class NewGuideCanvas2 extends Canvas implements MouseListener{
    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 int LeftMargin=20, RightMargin=10, TopMargin=10, BottomMargin=10;
    private static final Font labfont = new Font("SanSerif",Font.PLAIN,10);
    private static final Font symbolfont= new Font("Serif",Font.PLAIN,16);
    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 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.8541878176E-12; //Units: F/m
    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;
   
    
    public NewGuideCanvas2(){
	super();
	IsFocusOn = false;
	IsTopoOn = false;
	setBackground(bgcolor2);
	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;
	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){
	
	//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){
		//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);
		g.drawLine(0,getSize().height-1,getSize().width-1,getSize().height-1);
		//g.drawLine(getSize().width-1,0,getSize().width-1,getSize().height-1);
		//g.setColor(Color.white);
		
		//g.drawLine(0,0,getSize().width-1,0);
		//g.drawLine(0,0,0,getSize().height-1);

		//set the arrays
		x[0] = getSize().width/2-40;
		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(Color.red);
		g.setColor(new Color(150,0,0));
		g.setFont(symbolfont);
		g.getFontMetrics();
		lambda="\u03bb";
		theta="\u03b8";
		phi="\u03c6";
		deg="\u00ba";
		g.setFont(labfont4);
		g.getFontMetrics();
		
		int xc = x[0]+x[0]*3/4;
		int yc = 30;
				
		g.setFont(new Font("Serif",Font.PLAIN,14));
		g.drawString("R",xc-12,15);
		g.setFont(new Font("SanSerif",Font.PLAIN,12));
		
		g.drawString("= "+point_distance+" "+lambda,xc,15);
				
		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+20;
		
		g.setColor(Color.blue);
		g.drawString("= "+theta_angle+" "+deg,xc,53);
		g.drawString("= "+phi_angle+" "+deg,xc,68);
		
		g.setFont(new Font("Serif",Font.PLAIN,15));
		g.drawString("\u03b8",xc-12,53);
		g.drawString("\u03c6",xc-12,68);
		g.setFont(new Font("SanSerif",Font.PLAIN,12));
		g.setColor(Color.black);
                
                g.setFont(new Font("SanSerif",Font.PLAIN,12));
                //------------------------------------------------------- Area of spherical front
                int y_area = 192;
                int x_area = 185;
                
                g.drawString("Area of spherical front",x_area-25,y_area-13);
                g.drawString("S =",x_area - 16,y_area);

                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,11,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,11,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,11,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,11,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,11,x_area,y_area);
                }
                else if(test >= 1.0 && test < 1.0e3){
                    testprint = test;
                    MaestroG.superscripter("  "+MaestroA.rounder(testprint,4)+"",""," [m\u00b2]",g,11,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,11,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,11,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,11,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,11,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,11,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,11,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,11,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,11,x_area,y_area);
                }

		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
    
		int radius = getSize().height/2-20;
		int radius1 = radius;
		int axis = getSize().height/2+20;
		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+2,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,3,Color.green,g);
		    drawCircle(x2,y2,3,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]-23,y[0]-10,46,20,-108,108+(int)(phinew));
		g.setColor(new Color(155,5,155));
		g.drawArc(x[0]-23,y[0]-10,46,20,-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]-27,2*radius1,2*27,180,180);
		
		int tip = y[0]*5/6;
		g.setColor(Color.gray);
		
		//draw z axis
		g.drawLine(x[0],15,x[0],y[0]); 
		MaestroG.drawArrow(x[0],15,5,g);
		g.drawLine(x[0],y[0]+10,x[0],y[0]+radius+10); 
		
		//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);
		
		// 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);
                
		Polygon p = new Polygon();
		p.addPoint(x[0]-tip,y[0]+tip);
		p.addPoint(x[0]-(tip-2),y[0]+(tip-6));
		p.addPoint(x[0]-(tip-6),y[0]+(tip-2));
		//g.drawPolygon(p);
		//g.fillPolygon(p);
		
		//Scanned point P (green circle)
		if(phi_angle <=90 || phi_angle >=270){
		    fillCircle(x2,y2,3,Color.green,g);
		    drawCircle(x2,y2,3,Color.black,g);
		}
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
                
                g.setColor(Color.black);
                g.drawString("z",x[0]-12,15);
		g.drawString("y",x[0]+axis,y[0]-10);
		g.drawString("x",x[0]-(tip-12),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);
    }
    
    
    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){}
}
