//NewGuideCanvas
/* A Java class for
 * Coaxial.java
 * Electromagnetic Transmission Line Applet
 * Applet without Smith Chart - Prepared by Umberto Ravaioli 
 * for 6th edition of Fundamentals of Applied Electromagnetics Book
 * May 2009 - All Rights Reserved
 */   

import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.net.*;
import java.awt.event.*;

public class NewGuideCanvas extends Canvas implements MouseListener{
    //private static final Color bgcolor = new Color(236,236,221);
    private static final Color bgcolor = Color.white;
    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 symbfont= new Font("Serif",Font.PLAIN,12);
    public static Font labfont;
    public static Font symbfont;
    public static Font normalfont;
    private int yBottom;
    private double frequency, a, b, w, epsilon_r, epsilon_r0, mu_r, phase_velocity, phase_velocity0;
    private double a_maximum, w_maximum, b_maximum, sigma2, sigma_metal;
    
    // use approximate epsilon for approximate phase velocity
    //private static final double epsilon0 = 8.8541878176E-12; //Units: F/m
    private static final double epsilon0 = 8.841941286E-12; //Units: F/m
    private static final double mu0 = 1.25663706144E-6; //Units H/m
    
    
    private Image im;
    private Graphics buf;
    private String stmp;
    private double temp;
    private boolean IsFocusOn;
    
    public NewGuideCanvas(){
	super();
	IsFocusOn = false;
	setBackground(bgcolor);
	//Listeners
	this.addMouseListener(this);
	
	a = 10.0; // mm
	a_maximum = 11.0; //mm
	b = 0.005; //mm
	b_maximum = 0.5; //mm
	w = 1.5; //mm
	w_maximum = 11.0; //mm
	epsilon_r = 2.3;
	epsilon_r0 = 1.0;
	mu_r = 1.0;
	frequency = 1.0E9;
	sigma2 = 0.0;
	sigma_metal = 5.8E7 ;
	
    }

    public void drawCanvas(Graphics g){
	g.clearRect(0,0,getSize().width,getSize().height);
	g.setColor(Color.black);
	
 	//if(IsFocusOn){drawBackLabels(g);}
	
	drawGuide(g);
        drawAxis(g);
    }
    
    private void drawAxis(Graphics g){
	double theta = Math.PI/4.0;
	int ArrowPos1, ArrowPos2;
	int Lsize = 30;
	Graphics2D g2d = (Graphics2D)g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        g.setColor(Color.black);
	//Vertical axis
	g.drawLine(LeftMargin,getSize().height-BottomMargin,LeftMargin,getSize().height-BottomMargin-Lsize);
	MaestroG.drawArrow(LeftMargin,getSize().height-BottomMargin-Lsize,5,g);
	//Horizontal axis
	g.drawLine(LeftMargin,getSize().height-BottomMargin,LeftMargin+Lsize,getSize().height-BottomMargin);
	//Draw up arrow
	MaestroG.drawArrow(LeftMargin+Lsize,getSize().height-BottomMargin,7,g);
	//Third axis
	g.drawLine(LeftMargin,getSize().height-BottomMargin,
		   LeftMargin+(int)(Lsize*Math.cos(theta)),getSize().height-BottomMargin-(int)(Lsize*Math.sin(theta)));
	g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        
        g.setColor(Color.black);
		// draw line
		int tipH = -25;
		int horizH = LeftMargin;
		int verticH = getSize().height-BottomMargin;
		//g.drawLine(horizH,verticH,horizH-tipH,verticH+tipH);
		//draw oblique arrow head
		Polygon pH = new Polygon();
		pH.addPoint(horizH - tipH,verticH + tipH);
		pH.addPoint(horizH - (tipH + 2),verticH +(tipH + 6));
		pH.addPoint(horizH - (tipH + 6),verticH + (tipH + 2));
		//g.drawPolygon(pH);
		//g.fillPolygon(pH);
        MaestroG.drawArrow(LeftMargin+(int)(Lsize*Math.cos(theta)),getSize().height-BottomMargin-(int)(Lsize*Math.sin(theta)),9,g);
	g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        //Draw labels for axes
	g.setFont(normalfont);
	FontMetrics fm = g.getFontMetrics();
	g.drawString("x",LeftMargin-fm.stringWidth("x")/2,getSize().height-BottomMargin-Lsize-10);
	g.drawString("y",LeftMargin+Lsize+10+fm.stringWidth("y"),
		getSize().height-BottomMargin+fm.getHeight()/3);
	
	g.drawString("z",LeftMargin+(int)(Lsize*Math.cos(theta))+10,getSize().height-BottomMargin-(int)(Lsize*Math.sin(theta))+2);
    }
    
    private void drawGuide(Graphics g){    
	int xLeft, xRight, xCenter, xRef, yCenter;
	int yTop, width, thick, widthmax, amax, thickmax;
	int slabDH;//Thickness of the slab
	int slabDepth; //Depth of the slab
	double theta = Math.PI/4.0;
        
        Graphics2D g2d = (Graphics2D)g;
        
	thickmax = 5;
	widthmax = 100;
	amax =100;
	if( w_maximum >= a_maximum){
	    amax = (int)(a_maximum/w_maximum*widthmax);
	    thickmax = (int)(b_maximum/a_maximum*amax);
	}
	if(w_maximum < a_maximum){
	    amax = 100;
	    widthmax = (int)(w_maximum/a_maximum*amax);
	    thickmax = (int)(b_maximum/a_maximum*amax);
	}
	width = (int)(w/w_maximum*widthmax)+1;
	if(w==0.0){
	    width = 0;
	}
	thick = (int)(b/b_maximum*thickmax)+1;
	if(b==0.0){
	    thick = 0;
	}
	
	Color MetalColor1 = Color.lightGray;
	Color MetalColor2 = new Color(220,220,220);
	Color MetalColor3 = new Color(235,235,235);
	Color graynew = new Color(125,125,125);
            
	xLeft = LeftMargin+20;
	xRight = getSize().width - RightMargin-80;
	xCenter = (xRight+xLeft)/2;
	yCenter = getSize().height/2;
	xRef = xCenter-width/2;
	yBottom = TopMargin+60+(int)(a/a_maximum*amax)+1;
	yTop = TopMargin+60;
	slabDH = 5;
	slabDepth = 90;
	// Draw waveguide
            Color anularcolor = new Color(215,215,215);
            double raggio_out = (a/a_maximum*amax)/2+7;
            double raggio_in = (a/a_maximum*amax)/2;
	g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
            
            int x1 = xCenter+(int)(2*Math.sin(theta)*raggio_out);
            int y1 = yCenter-(int)(3.25*Math.sin(theta)*raggio_out);
            int x2 = xCenter+(int)(3.25*Math.sin(theta)*raggio_out);
            int y2 = yCenter-(int)(2*Math.sin(theta)*raggio_out);
            int far = 150;
            
            //cylinder lines inner conductor
            g.setColor(Color.lightGray);
            g.drawLine(xCenter-(int)(Math.sin(theta)*width/2),yCenter-(int)(Math.sin(theta)*width/2),
                       (x1+x2)/2+2*far,(y1+y2)/2-2*far);
            g.setColor(Color.gray);
            g.drawLine(xCenter+(int)(Math.sin(theta)*width/2)-1,yCenter+(int)(Math.sin(theta)*width/2),
                       (x1+x2)/2+2*far,(y1+y2)/2-2*far);
            
            drawStencil(g, getSize().width, getSize().height, (int)raggio_out+1, xCenter, yCenter, bgcolor);
            
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
            //cylinder lines outer conductor
            g.setColor(Color.lightGray);
            g.drawLine(xCenter-(int)(Math.sin(theta)*raggio_out),yCenter-(int)(Math.sin(theta)*raggio_out),
                       xCenter+(int)(2*Math.sin(theta)*raggio_out)+far,yCenter-(int)(3.25*Math.sin(theta)*raggio_out)-far);
            g.setColor(Color.gray);
            g.drawLine(xCenter+(int)(Math.sin(theta)*raggio_out),yCenter+(int)(Math.sin(theta)*raggio_out),
                       xCenter+(int)(3.25*Math.sin(theta)*raggio_out)+far,yCenter-(int)(2*Math.sin(theta)*raggio_out)-far);
            
            g.setColor(bgcolor);
            g.fillRect(getSize().width/3,0,2*getSize().width/3,10);
            
            drawAnular(g, (int)(raggio_out), (int)(raggio_in), xCenter, yCenter, anularcolor);
            drawCircleThick(g,(double)(xCenter),(double)(yCenter),raggio_out,1,graynew);
            drawCircleThick(g,(double)(xCenter),(double)(yCenter),raggio_in,1,graynew);
            
	    g.setColor(Color.red);
	   
	    g.drawLine(xCenter,yCenter-(int)(raggio_in)-1,xCenter+(int)(raggio_in)+50,yCenter-(int)(raggio_in)-1);
	    g.drawLine(xCenter,yCenter+(int)(raggio_in),xCenter+(int)(raggio_in)+50,yCenter+(int)(raggio_in));
            
	    if((int)(raggio_in) > 10){
		g.drawLine(xCenter+(int)(raggio_in)+45,yCenter-(int)(raggio_in),xCenter+(int)(raggio_in)+45,yCenter+(int)(raggio_in));
		MaestroG.drawArrow(xCenter+(int)(raggio_in)+45,yCenter+(int)(raggio_in)-9,6,g);
		MaestroG.drawArrow(xCenter+(int)(raggio_in)+45,yCenter-(int)(raggio_in)+8,5,g);
	    }
	    else{
		g.drawLine(xCenter+(int)(raggio_in)+45,yCenter-(int)(raggio_in)-12,xCenter+(int)(raggio_in)+45,yCenter+(int)(raggio_in)+12);
		MaestroG.drawArrow(xCenter+(int)(raggio_in)+45,yCenter-(int)(raggio_in)-9,6,g);
		MaestroG.drawArrow(xCenter+(int)(raggio_in)+45,yCenter+(int)(raggio_in)+8,5,g);
	    }
	    
	    Color colorinside = new Color(185,185,185);
            FillCircleSmooth(g,(double)(xCenter),(double)(yCenter),width/2,1,graynew);
	    FillCircleSmooth(g,(double)(xCenter),(double)(yCenter),width/2-1,1,anularcolor);
            //drawCircleThick(g,(double)(xCenter),(double)(yCenter),width/2,1,graynew);
            
            //draw cross on center of structure
            
            g.setColor(Color.white);
            g.drawLine(xCenter-2,yCenter,xCenter+2,yCenter);
            g.drawLine(xCenter,yCenter-2,xCenter,yCenter+2);
            
	    g.setColor(Color.red);
	    g.drawLine(xCenter+(int)(width/2),yCenter,xCenter+(int)(width/2),yCenter-(int)(raggio_in)-30);
	    g.drawLine(xCenter-(int)(width/2)-1,yCenter,xCenter-(int)(width/2)-1,yCenter-(int)(raggio_in)-30);
	    
            if((int)(width/2) > 10){
		g.drawLine(xCenter+(int)(width/2),yCenter-(int)(raggio_in)-25,xCenter-(int)(width/2),yCenter-(int)(raggio_in)-25);
		MaestroG.drawArrow(xCenter+(int)(width/2)-9,yCenter-(int)(raggio_in)-25,7,g);
		MaestroG.drawArrow(xCenter-(int)(width/2)+8,yCenter-(int)(raggio_in)-25,8,g);
	    }
	    else{
		g.drawLine(xCenter+(int)(width/2)+12,yCenter-(int)(raggio_in)-25,xCenter-(int)(width/2)-13,yCenter-(int)(raggio_in)-25);
		MaestroG.drawArrow(xCenter+(int)(width/2)+9,yCenter-(int)(raggio_in)-25,8,g);
		MaestroG.drawArrow(xCenter-(int)(width/2)-10,yCenter-(int)(raggio_in)-25,7,g);
	    }
            
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
	    
	    g.drawString("2a",xCenter-5,yCenter-(int)(raggio_in)-35);
	    g.drawString("2b",xCenter+(int)(raggio_in)+55,yCenter);
	    
	g.setColor(Color.black);
    	int x = 100;
	int y = getSize().height-5;
	double f_normalized;
	
	
	if(frequency < 1.0E3){
		    f_normalized = frequency;
		    g.drawString("    f =  "+MaestroA.rounder(f_normalized,6)+"   [ Hz ]",x,y);	
		}
		else if(frequency < 1.0E6 && frequency >= 1.0E3  ){
		    f_normalized = frequency/1.0E3;
		    g.drawString("    f  =  "+MaestroA.rounder(f_normalized,6)+"   [ kHz ]",x,y);	
		}
		else if(frequency < 1.0E9 && frequency >= 1.0E6 ){
		    f_normalized = frequency/1.0E6;
		    g.drawString("    f  =  "+MaestroA.rounder(f_normalized,6)+"   [ MHz ]",x,y);	
		}
		else if(frequency < 1.0E12 && frequency >= 1.0E9 ){
		    f_normalized = frequency/1.0E9;
		    g.drawString("    f  =  "+MaestroA.rounder(f_normalized,6)+"   [ GHz ]",x,y);	
		}
		else if(frequency < 1.0E15 && frequency >= 1.0E12 ){
		    f_normalized = frequency/1.0E12;
		    g.drawString("    f  =  "+MaestroA.rounder(f_normalized,6)+"   [ THz ]",x,y);	
		}
		else{
		    f_normalized = frequency/1.0E12;
		    g.drawString("    f  =  "+MaestroA.rounder(f_normalized,6)+"   [ THz ]",x,y);
		}
		
        //MaestroG.subscripter("","r","  = 1.0",g,12,18,42);
		MaestroG.subscripter("","r","  = "+MaestroA.rounder(epsilon_r,4),g,12,18,27);
		MaestroG.subscripter("",""," = "+MaestroA.rounder(sigma2,6)+" S/m",g,12,23,13);
		//g.setFont(symbfont);
	//g.drawString("\u03bc",10,42);
		g.drawString("\u03c3",13,13);
		g.drawString("\u03b5",13,27);
		g.setFont(labfont);
		
		int refnew = yTop+30;
		
		//g.setColor(Color.blue);
		//g.drawLine(10,refnew,35,refnew);
		//g.drawLine(10,25,10,refnew);
		//g.drawLine(20,5,20,45);
		//g.drawLine(10,25,20,25);
		//MaestroG.drawArrow(30,refnew,3,g);
		
		g.setColor(Color.blue);
		g.drawLine(15,refnew,xCenter-((int)(a/a_maximum*amax/2)-width/2)/2-width/2-5,refnew);
		//g.drawLine(15,50,15,refnew);
		//g.drawLine(5,50,45,50);
		//g.drawLine(5,5,5,50);
		g.drawLine(15,35,15,refnew);
		g.drawLine(5,35,45,35);
		g.drawLine(5,5,5,35);
		MaestroG.drawArrow(xCenter-((int)(a/a_maximum*amax/2)-width/2)/2-width/2-10,refnew,7,g);
		
		g.setColor(Color.black);
		
		
    }
    
    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 drawStencil(Graphics g, int width, int height, int radius, int xcenter, int ycenter, Color stencilcolor){
	int rule; float alpha;
        rule = AlphaComposite.SRC_OVER;
        alpha = 1.0f;
        
        Graphics2D g2d = (Graphics2D)g;
        g2d.setPaint(stencilcolor);      
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setComposite(AlphaComposite.getInstance(rule, alpha));
        
        Area a1, a2, a3;
        
	Rectangle2D newrect = new Rectangle2D.Double(0.0,0.0,(double)width,(double)height);
        a1 = new Area(newrect);
        Ellipse2D newellipse = new Ellipse2D.Double((double)(xcenter-radius),(double)(ycenter-radius),(double)(radius*2),(double)(radius*2));
        a2 = new Area(newellipse);
        a3 = new Area();
        a3.add(a1);
        a3.subtract(a2);
        g2d.fill(a3);
        
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
}

    
private void FillCircleSmooth(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 drawAnular(Graphics g, int radius1, int radius2, int xcenter, int ycenter, Color stencilcolor){
	int rule; float alpha;
        rule = AlphaComposite.SRC_OVER;
        alpha = 1.0f;
        
        Graphics2D g2d = (Graphics2D)g;
        g2d.setPaint(stencilcolor);      
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setComposite(AlphaComposite.getInstance(rule, alpha));
        
        Area a1, a2, a3;
        
        Ellipse2D newellipse1 = new Ellipse2D.Double((double)(xcenter-radius1),(double)(ycenter-radius1),(double)(radius1*2),(double)(radius1*2));
        a1 = new Area(newellipse1);
        Ellipse2D newellipse2 = new Ellipse2D.Double((double)(xcenter-radius2),(double)(ycenter-radius2),(double)(radius2*2),(double)(radius2*2));
        a2 = new Area(newellipse2);
        a3 = new Area();
        a3.add(a1);
        a3.subtract(a2);
        g2d.fill(a3);
        
        //g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
}

 
    public synchronized void setThick(double b){
	this.b = b;
	repaint();
    }
    
    public synchronized void setThickmax(double b_maximum){
	this.b_maximum = b_maximum;
	repaint();
    }
    
    public synchronized void setStrip(double w){
	this.w = w;
	repaint();
    }
    
    public synchronized void setStripmax(double w_maximum){
	this.w_maximum = w_maximum;
	repaint();
    }
    
    public synchronized void setFrequency(double frequency){
	this.frequency = frequency;
    }
    
    public synchronized void setWidth(double a){
	this.a = a;
    }
    
    public synchronized void setWidthMax(double a_maximum){
	this.a_maximum = a_maximum;
    }
    
    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 setSigma2(double sigma2){
	this.sigma2 = sigma2;
    }
    
    public synchronized void setSigmaMetal(double sigma_metal){
	this.sigma_metal = sigma_metal;
    }
    
    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){}
    public void mouseEntered(MouseEvent evt){
	IsFocusOn = true;
	repaint();
    }
    public void mouseExited(MouseEvent evt){
	IsFocusOn = false;
	repaint();
    }
    public void mousePressed(MouseEvent evt){}
    public void mouseReleased(MouseEvent evt){}
}
