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

class
DrawCanvas extends Canvas implements MouseListener{
	Antenna ant;
	Rectangle r;
	
	protected Image im;
	protected Graphics buf;
	private static final Color bgcolor = new Color(236,236,221);
	private static final Font labfont0 = new Font("SanSerif",Font.PLAIN,9);
	private static final Font labfont = new Font("SanSerif",Font.PLAIN,10);
	private static final Font labfontS = new Font("Serif",Font.PLAIN,11);
	private static final Font labfont2 = new Font("SanSerif",Font.PLAIN,11);
        private static final Font labfont4 = new Font("Serif",Font.PLAIN,12);
	private static final Font labfont3 = new Font("SanSerif",Font.PLAIN,12);
        private static final Font labfontIT = new Font("Serif",Font.ITALIC,14);
	private int x[], y[];
	private static final Font symbfont= new Font("Serif",Font.PLAIN,12);
	private static final Font symbfont2= new Font("Serif",Font.PLAIN,14);

	private boolean IsFocusOn, IsTopoOn;
	
	public DrawCanvas(Antenna ant){
		super();
		this.ant=ant;
		setBackground(bgcolor);
		IsFocusOn = false;
		IsTopoOn = false;
		
		x = new int[5];
		y = new int[5];

		//Listeners
		this.addMouseListener(this);
	}
	
	public void paint(Graphics g){
	    if(im == null){
		im = createImage(getSize().width,getSize().height);
		buf = im.getGraphics();
		drawGraph(buf);
	    }
	    drawGraph(buf);
	    g.drawImage(im,0,0,null);
	}

	//Addition to reduce flicker new routine
	public void update(Graphics g){		// added to avoid clearing
		paint(g);
	}

	public void drawGraph(Graphics g){	
	//public void paint(Graphics g){
		double distancia, escala;
		int i, numpointsA, numpointsB, array_length, idistancia;
		int x1, y1, x2, y2, x3, y3;
		
		
		r=getBounds();
		g.setColor(Color.white);
		g.fill3DRect(0,0,r.width-1,r.height-1,true);
		
		Graphics2D g2d = (Graphics2D)g;
            	
	 if(IsFocusOn){
		
		g.setColor(Color.black);	
		escala=r.width*0.07;
		if(ant.number_dipoles < 21){
		    distancia=(r.width-20)/20;
		    array_length = (int)( distancia * ant.number_dipoles);	
		}
		else{
		    distancia=(r.width-20)/ant.number_dipoles_max;
		    array_length = (int)( distancia * ant.number_dipoles);	
		}
		
		int shift = 15;
		int shift2 = 20;
		
	    for(i=0;i<ant.number_dipoles;i++){
		//Left Dipole Wires
		idistancia = ((r.width/2 - array_length/2)+(i+1)*(int)(distancia))-6;
		
		if(i==0){
		    g.setColor(Color.red);
		    g.drawLine(idistancia,(int)(r.height*0.88)-shift,idistancia,(int)(r.height*0.82)-shift);
		    g.drawLine(idistancia,(int)(r.height*0.92)-shift,idistancia,(int)(r.height*0.98)-shift);
		    
		    g.drawLine(idistancia-1,(int)(r.height*0.88)-shift,idistancia-1,(int)(r.height*0.82)-shift);
		    g.drawLine(idistancia-1,(int)(r.height*0.92)-shift,idistancia-1,(int)(r.height*0.98)-shift);
		}
		else if(i==(ant.number_dipoles-1)){
		    g.setColor(Color.green);
		    g.drawLine(idistancia,(int)(r.height*0.88)-shift,idistancia,(int)(r.height*0.82)-shift);
		    g.drawLine(idistancia,(int)(r.height*0.92)-shift,idistancia,(int)(r.height*0.98)-shift);
		    
		    g.drawLine(idistancia+1,(int)(r.height*0.88)-shift,idistancia+1,(int)(r.height*0.82)-shift);
		    g.drawLine(idistancia+1,(int)(r.height*0.92)-shift,idistancia+1,(int)(r.height*0.98)-shift);
		}	
		else{
		    g.setColor(Color.gray);
		    g.drawLine(idistancia,(int)(r.height*0.88)-shift,idistancia,(int)(r.height*0.82)-shift);
		    g.drawLine(idistancia,(int)(r.height*0.92)-shift,idistancia,(int)(r.height*0.98)-shift);
		}
		g.setColor(Color.black);
		g.setFont(labfont0);
		
		    if(i==0 || i == (ant.number_dipoles-1)){
			if(i == (ant.number_dipoles-1) && i > 8){
			    g.drawString(""+(i),idistancia-4,(int)(r.height*0.92)+14);
			}
			else if(i == (ant.number_dipoles-1) && i <= 8 && i!=0){
			    g.drawString(""+(i),idistancia-1,(int)(r.height*0.92)+14);
			}
			else if(i == 0){
			    g.drawString(""+(i),idistancia-2,(int)(r.height*0.92)+14);
			}
		    }		
	    }
		int x1a = ((r.width/2 - array_length/2))-8+(int)(distancia);
		int x2a = ((r.width/2 + array_length/2))-4;
		int ya = ((int)(r.height*0.88)+(int)(r.height*0.92))/2-shift;
		int yb = (int)(r.height*0.82)-shift2;
		
		// draw the axis
		g.setColor(Color.black);
		g.drawLine(x1a,ya,x2a,ya);
		
		g.setColor(Color.blue);
		if(ant.number_dipoles < 4){
		    if(ant.number_dipoles == 2){
			g.drawLine(x1a+1,yb,x2a-1,yb);
			g.drawLine(x1a+1,yb+3,x1a+1,yb-3);
			g.drawLine(x2a,yb+3,x2a,yb-3);
		
			MaestroG.drawArrow(x1a-8,yb,7,g);
			MaestroG.drawArrow(x2a+9,yb,8,g);
			g.setFont(labfontS);
			g.drawString("d",(x1a+x2a)/2-2,yb-3);
		    }
		    if(ant.number_dipoles == 3){
			g.drawLine(x1a+1,yb,x2a-1,yb);
			g.drawLine(x1a+1,yb+3,x1a+1,yb-3);
			g.drawLine(x2a,yb+3,x2a,yb-3);
		
			MaestroG.drawArrow(x1a-8,yb,7,g);
			MaestroG.drawArrow(x2a+9,yb,8,g);
			g.setFont(labfontS);
			g.drawString("2 d",(x1a+x2a)/2-6,yb-3);
		    }
		}
		else{
		    g.drawLine(x1a+1,yb,x2a-1,yb);
		    g.drawLine(x1a+1,yb+3,x1a+1,yb-3);
		    g.drawLine(x2a,yb+3,x2a,yb-3);
		
		    MaestroG.drawArrow(x1a+10,yb,8,g);
		    MaestroG.drawArrow(x2a-9,yb,7,g);
		    g.setFont(labfontS);
		    g.drawString(""+(ant.number_dipoles - 1)+" d",(x1a+x2a)/2-6,yb-3);
		}
		
		
		g.setColor(Color.black);
		
		numpointsA=(int)(r.height*0.30*ant.dipolelengthA/(ant.dipolelengthmaxA));

		g.setColor(Color.blue);
		int cshift = 5;
		
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		
                if(ant.dipolelengthA>=0.05){
		  for(i=-numpointsA;i<numpointsA;i++){
			y2=(int)(r.height*(0.35)+i);
			y1=y2-1;
			x2=(int)(r.width*0.25+50*ant.scalingA*Math.sin(Math.PI*ant.dipolelengthA 
                                                       -2.0*Math.PI*Math.abs(i+1)*ant.dipolelengthA/(2.0*numpointsA)))- cshift;
			x1=(int)(r.width*0.25+50*ant.scalingA*Math.sin(Math.PI*ant.dipolelengthA 
  						       -2.0*Math.PI*Math.abs(i)*ant.dipolelengthA/(2.0*numpointsA)))- cshift;
		  	g.drawLine(x1, y1, x2, y2);
		  }
		}
		else{
			x1=(int)(r.width*0.25) - cshift ;
			x2=x1+50 - cshift;
			y1=(int)(r.height*0.35);
			y2=y1;
			g.drawLine(x1,y1,x2,y2);
		}
                
                //g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
                
		//draw the axis
		g.setColor(Color.black);		
		y2=(int)(r.height*(0.35)+numpointsA);
		y1=(int)(r.height*(0.35)-numpointsA-2);
		x2=(int)(r.width*0.25) - cshift;
		x1=(int)(r.width*0.10) - cshift;
		g.drawLine(x2,y1,x2,y2);
		
		g.setColor(Color.red.darker());	
                g.setFont(labfontIT);
		g.drawString("l",(int)(r.width*0.25+50)+8,(y1+y2)/2+4);
		g.drawLine((int)(r.width*0.25+50),y1,(int)(r.width*0.25+50),y2);
		g.drawLine((int)(r.width*0.25+50)-3,y1,(int)(r.width*0.25+50)+3,y1);
		g.drawLine((int)(r.width*0.25+50)-3,y2,(int)(r.width*0.25+50)+3,y2);
		if(ant.dipolelengthA >= 0.5){
		    MaestroG.drawArrow((int)(r.width*0.25+50),y1+9,5,g);
		    MaestroG.drawArrow((int)(r.width*0.25+50),y2-9,6,g);
		}
		else{
		    MaestroG.drawArrow((int)(r.width*0.25+50),y1-9,6,g);
		    MaestroG.drawArrow((int)(r.width*0.25+50),y2+9,5,g);
		}
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		g.setColor(Color.black);
		//g.setColor(Color.white);
		g.setFont(labfont);
		g.drawString("Dipole",x1-10,y1+2);
		g.drawString("current",x1-10,y1+12);
		
		g.setFont(labfont2);
		x1 = (int)(r.width*0.55);
		y1 = 30;
		int dy = 12;
		int dyy = 16;
		
		g.setColor(Color.red);
		g.drawString("Assumptions",x1,y1);
		y1+=dyy;
		g.setColor(Color.blue);
		g.drawString("-  Far Field",x1,y1);
		y1+=dyy;
		g.drawString("-  Identical Dipoles",x1,y1);
		y1+=dyy;
		g.drawString("-  Uniform spacing d",x1,y1);
		y1+=dyy;
		g.drawString("-  Uniform incremental",x1,y1);
		y1+=dy;
		g.drawString("    phase delay between",x1,y1);
		y1+=dy;
		g.drawString("    dipoles",x1,y1);
		
		if(IsTopoOn){
		    g.setFont(labfont);
		    g.setColor(new Color(150,0,0));
		    g.drawString("Click to show coordinates",(int)(r.width/2),12);
		    g.drawLine((int)(r.width/2),16,(int)(r.width-10),16);
		}
		
	    }
	    else{		
		
		//set the arrays
		x[0] = getSize().width/2-30;
		x[1] = x[0] - 7;
		x[2] = getSize().width-50;
		
		y[0] = getSize().height-20;
		y[1] = getSize().height/2;

		String lambda, rho, psi, deg;
		g.setFont(symbfont2);
		g.getFontMetrics();
		lambda="\u03bb";
		rho ="\u03c1";
		psi ="\u03c8";
		deg="\u00ba";
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		g.setColor(Color.black);
		//MaestroG.subscripterS("I","1"," =",g,11,x[0]+10,30);
		//MaestroG.subscripterS(" I","0","",g,11,x[0]+30,30);
		
		MaestroG.subscripterS("I","i"," =",g,12,x[0]+10,50);
		MaestroG.subscripterS(" I","0"," exp[ - j ( i \u03b4 ) ]",g,12,x[0]+35,50);
		
		int xCenter = x[0];
		int yCenter = y[1];
		int Radius = 15;
		int beginAngle = 28;
		int Angle = 62;
		int raio = 2*Radius;
                
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		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);
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                
                g.setColor(Color.blue);
		g.setFont(new Font("Serif",Font.PLAIN,15));
		g.drawString("\u03b8",x[0]+5,y[1]-16);
		g.setFont(new Font("SanSerif",Font.PLAIN,12));
		g.setColor(Color.black);
		
		//Arc for phi
		xCenter = x[0];
		yCenter = y[1];
		Radius = 15;
		beginAngle = 225;
		Angle = 87;
		raio = 2*Radius;
                
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		g.setColor(Color.yellow);
		g.fillArc(xCenter-Radius,yCenter-Radius,raio,raio,beginAngle,Angle);
		g.setColor(Color.black);
		g.drawArc(xCenter-Radius,yCenter-Radius,raio,raio,beginAngle,Angle);
		//g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
                
                g.setColor(Color.blue);
		g.setFont(new Font("Serif",Font.PLAIN,15));
		g.drawString("\u03c6",x[0]-14,y[1]+25);
		g.setFont(new Font("SanSerif",Font.PLAIN,12));
		
		//dipoles
		
		int xshift = 20;
		g.setColor(Color.lightGray);
		g.drawLine(x[0]+xshift,y[1]-5,x[0]+xshift,y[1]-35);
		g.drawLine(x[0]-1+xshift,y[1]-5,x[0]-1+xshift,y[1]-35);
		
		g.drawLine(x[0]+xshift,y[1]+5,x[0]+xshift,y[1]+35);
		g.drawLine(x[0]-1+xshift,y[1]+5,x[0]-1+xshift,y[1]+35);
		
		g.setColor(Color.gray);
		g.drawLine(x[0]+1+xshift,y[1]-5,x[0]+1+xshift,y[1]-35);
		g.drawLine(x[0]+1+xshift,y[1]+5,x[0]+1+xshift,y[1]+35);
		
		xshift = 40;
		g.setColor(Color.lightGray);
		g.drawLine(x[0]+xshift,y[1]-5,x[0]+xshift,y[1]-35);
		g.drawLine(x[0]-1+xshift,y[1]-5,x[0]-1+xshift,y[1]-35);
		
		g.drawLine(x[0]+xshift,y[1]+5,x[0]+xshift,y[1]+35);
		g.drawLine(x[0]-1+xshift,y[1]+5,x[0]-1+xshift,y[1]+35);
		
		g.setColor(Color.gray);
		g.drawLine(x[0]+1+xshift,y[1]-5,x[0]+1+xshift,y[1]-35);
		g.drawLine(x[0]+1+xshift,y[1]+5,x[0]+1+xshift,y[1]+35);
		
		xshift = 60;
		g.setColor(Color.lightGray);
		g.drawLine(x[0]+xshift,y[1]-5,x[0]+xshift,y[1]-35);
		g.drawLine(x[0]-1+xshift,y[1]-5,x[0]-1+xshift,y[1]-35);
		
		g.drawLine(x[0]+xshift,y[1]+5,x[0]+xshift,y[1]+35);
		g.drawLine(x[0]-1+xshift,y[1]+5,x[0]-1+xshift,y[1]+35);
		
		g.setColor(Color.gray);
		g.drawLine(x[0]+1+xshift,y[1]-5,x[0]+1+xshift,y[1]-35);
		g.drawLine(x[0]+1+xshift,y[1]+5,x[0]+1+xshift,y[1]+35);
		
		xshift = 80;
		g.setColor(Color.lightGray);
		g.drawLine(x[0]+xshift,y[1]-5,x[0]+xshift,y[1]-35);
		g.drawLine(x[0]-1+xshift,y[1]-5,x[0]-1+xshift,y[1]-35);
		
		g.drawLine(x[0]+xshift,y[1]+5,x[0]+xshift,y[1]+35);
		g.drawLine(x[0]-1+xshift,y[1]+5,x[0]-1+xshift,y[1]+35);
		
		g.setColor(Color.gray);
		g.drawLine(x[0]+1+xshift,y[1]-5,x[0]+1+xshift,y[1]-35);
		g.drawLine(x[0]+1+xshift,y[1]+5,x[0]+1+xshift,y[1]+35);
		
		xshift = 100;
		g.setColor(Color.green);
		g.drawLine(x[0]+xshift,y[1]-5,x[0]+xshift,y[1]-35);
		g.drawLine(x[0]-1+xshift,y[1]-5,x[0]-1+xshift,y[1]-35);
		
		g.drawLine(x[0]+xshift,y[1]+5,x[0]+xshift,y[1]+35);
		g.drawLine(x[0]-1+xshift,y[1]+5,x[0]-1+xshift,y[1]+35);
		
		g.setColor(Color.gray);
		g.drawLine(x[0]+1+xshift,y[1]-5,x[0]+1+xshift,y[1]-35);
		g.drawLine(x[0]+1+xshift,y[1]+5,x[0]+1+xshift,y[1]+35);
		
		g.setColor(Color.black);
		g.drawLine(x[0]+8+xshift,y[1]-2,x[0]+8+xshift,y[1]-15);
		MaestroG.drawArrow(x[0]+8+xshift,y[1]-15,5,g);
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		MaestroG.subscripterS("I","N-1","",g,12,x[0]+15+xshift,y[1]-10);
		
		//draw axes 
		g.setColor(Color.black);
		g.drawLine(x[0],20,x[0],y[1]+25); 
		MaestroG.drawArrow(x[0],20,5,g);
		g.setColor(new Color(210,210,210));
		g.drawLine(x[0],y[1],x[0],y[1]+15);
		g.setColor(Color.black); 
		g.drawString("z",x[0]-12,20);
		
		
		g.drawLine(x[1]-15,y[1],x[2]+30,y[1]);
		MaestroG.drawArrow(x[2]+30,y[1],7,g);
		g.drawString("y",x[2]+30,y[1]+16);
		
		int tip = 87;
		g.drawLine(x[0],y[1],x[0]-tip,y[1]+tip);
		g.drawString("x",x[0]-(tip-12),y[1]+tip);
		//draw oblique arrow head
                MaestroG.drawArrow(x[0]-tip+5,y[1]+tip-5,10,g);
		
		Polygon p = new Polygon();
		p.addPoint(x[0]-tip,y[1]+tip);
		p.addPoint(x[0]-(tip-2),y[1]+(tip-6));
		p.addPoint(x[0]-(tip-6),y[1]+(tip-2));
		//g.drawPolygon(p);
		//g.fillPolygon(p);
	    
		g.setColor(Color.black);
		//radial line to point P
		g.drawLine(x[0],y[1],x[0]+50,y[1]-30);
		g.setColor(Color.blue);
		//label R
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		MaestroG.subscripter2("R","","",g,13,x[0]+25,y[1]-22);
		//line down to x-y plane
		g.drawLine(x[0]+50,y[1]-30,x[0]+50,y[1]+70);
		//lines to x- and y-axis
		g.setColor(Color.gray);
		g.drawLine(x[0]+50,y[1]+70,x[0]-70,y[1]+70);
		g.drawLine(x[0]+50,y[1]+70,x[0]+120,y[1]);
						
		g.setColor(Color.black);
		g.drawLine(x[0]+50,y[1]+70,x[0],y[1]);
		
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		//point P
		g.setColor(Color.green);
		g.fillOval(x[0]+48,y[1]-32,5,5);
		g.setColor(Color.black);
		g.drawOval(x[0]+48,y[1]-32,5,5);
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
		//Left Dipole (red)
		
		g.drawLine(x[0]-7,y[1]-2,x[0]-7,y[1]-15);
		MaestroG.drawArrow(x[0]-7,y[1]-15,5,g);
		MaestroG.subscripterS("I","0","",g,12,x[0]-21,y[1]-10);
                
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		
		g.setColor(Color.red);
		g.drawLine(x[0],y[1]-5,x[0],y[1]-35);
		g.drawLine(x[0]-1,y[1]-5,x[0]-1,y[1]-35);
		g.drawLine(x[0]+1,y[1]-5,x[0]+1,y[1]-35);
		
		g.drawLine(x[0],y[1]+16,x[0],y[1]+35);
		g.drawLine(x[0]-1,y[1]+16,x[0]-1,y[1]+35);
		g.drawLine(x[0]+1,y[1]+16,x[0]+1,y[1]+35);
		
		g.setFont(labfont4);
		g.setColor(Color.black);
		g.drawString("0",x[0]-2,y[1]+47);
		g.drawString("1",x[0]+18,y[1]+47);
		g.drawString("i",x[0]+58,y[1]+47);
		
		g.setColor(Color.black);
		g.drawString("N-1",x[0]+98,y[1]+47);
		
		//part or red dipole under angle (shows orange)
		Color orange = new Color(255,175,0);
		g.setColor(orange);
		
		g.drawLine(x[0],y[1]+14,x[0],y[1]+5);
		g.drawLine(x[0]-1,y[1]+14,x[0]-1,y[1]+5);
		g.drawLine(x[0]+1,y[1]+14,x[0]+1,y[1]+5);
		
		g.setColor(new Color(150,0,0));
		
		if((ant.fase == 0.0 || ant.fase == 2.0*Math.PI) && ant.distancia == 0.5){g.drawString("Broadside Pattern",50,240);}
		else if((ant.fase == Math.PI || ant.fase == -Math.PI) && ant.distancia == 0.5){g.drawString("Endfire Pattern",50,240);}
		else if((ant.fase == 0.5*Math.PI || ant.fase == -0.5*Math.PI) && ant.distancia == 0.25){g.drawString("Cardioid Pattern",50,240);}
		else if((ant.fase == 0.0 || ant.fase == 2.0*Math.PI) && ant.distancia == 1.0){g.drawString("Combined Broadside-Endfire Pattern",30,240);}
		else{}
		
		if(IsTopoOn){
		    g.setFont(labfont);
		    g.setColor(new Color(150,0,0));
		    g.drawString("Click to show details",(int)(r.width/2),12);
		    g.drawLine((int)(r.width/2),16,(int)(r.width-33),16);
		}
	    }
		
	}
	public void redraw(){
		repaint();
	}
	
	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){}

}
