//CircuitCanvas.java

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

public class CircuitCanvas extends Canvas implements MouseListener{
	private int x[], y[];
	private StateVars state;
	private Image im;
	private Graphics buf;
	private double frequency;
	
	//private static final Color bgcolor = new Color(24,188,185);
	private static final Color bgcolor = Color.gray;
	private static final Color ccolor1 = new Color(50,204,153);
	private boolean IsFocusOn;
	private int xtr;
	public CircuitCanvas(StateVars state){
		super();
		this.state = state;
		setBackground(bgcolor);
		x = new int[5];
		y = new int[6];
		this.addMouseListener(this);
		IsFocusOn = false;
	}

	public void update(Graphics g){
		paint(g);
	}

	public void paint(Graphics g){
		if(im == null){
			im = createImage(getSize().width,getSize().height);
			buf = im.getGraphics();
			drawCircuit(buf);
		}
		else{
			drawCircuit(buf);
		}
		g.drawImage(im,0,0,null);
	}
	
	public void drawCircuit(Graphics g){
		Graphics2D g2d = (Graphics2D)g;
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
            
                //Draw the background
		//g.setColor(bgcolor.darker());
		//g.fillRect(0,getSize().height-2,getSize().width,2);
		//g.fillRect(getSize().width-2,0,2,getSize().height);
		//g.setColor(bgcolor.brighter());
		//g.fillRect(0,0,2,getSize().height-1);
		//g.fillRect(0,0,getSize().width-2,2);
	
		//set the arrays
		x[0] = 20;
		x[4] = getSize().width-20;
		x[2] = x[0] + 50;
		x[3] = x[4] - 20;
		x[1] = (x[0]+x[2])/2;
		xtr = x[2];

		y[4] = 30;
		y[0] = getSize().height-115;
		y[2] = (y[4]+y[0])/2;
		y[3] = (y[4]+y[2])/2;
		y[1] = (y[0]+y[2])/2;
		y[5] = getSize().height;

		//drawGrid(x,y,g);

		//g.clearRect(x[0],y[4]-10,x[4]-x[0],y[0]-y[4]+20);
		g.clearRect(0,0,getSize().width-1,getSize().height-1);
		
		//Draw Transformer
		if(state.getDrawTransformer1() || state.getDrawTransformer2()){
		    drawTransf(g);
                    drawTransf(g);
		}
		
		//Reference
		drawRef(g);
		
		//Wires
		drawWire(x[0],y[4],x[4]+5,y[4],1,g);
		drawWire(x[0],y[0],x[4]+5,y[0],1,g);
		drawWire(x[0],y[4]+1,x[0],y[0]-2,2,g);
		drawWire(x[4]+5,y[4]+1,x[4]+5,y[0]-1,2,g);

		//Horizontal axis
		drawAxis(g);
		
      		//ZL
		draw3DRect(x[4]+5,y[2],18,y[1]-y[3],ccolor1,g);
		g.setColor(Color.white);
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                MaestroG.subscripter("Z","L","",g,11,x[4]+5-6,y[2]+2); // print twice smoothed letters on dark
                MaestroG.subscripter("Z","L","",g,11,x[4]+5-6,y[2]+2);
                
		//Zg
		draw3DRect(x[1],y[4],x[2]-x[0]-20,18,ccolor1,g);	
		g.setColor(Color.white);
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                MaestroG.subscripter("Z","g","",g,11,x[1]-5,y[4]+2); // print twice smoothed letters on dark
                MaestroG.subscripter("Z","g","",g,11,x[1]-5,y[4]+2);
                
		//Vg
                drawCircle(x[0],y[2],12,ccolor1,g);
                g.setColor(Color.white);
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                MaestroG.subscripter("V","g","",g,11,x[0]-6,y[2]+1); // print twice smoothed letters on dark
                MaestroG.subscripter("V","g","",g,11,x[0]-6,y[2]+1);
                
		//Connections
		drawConnect(x[2],y[4],g);
		drawConnect(x[2],y[0],g);
		drawConnect(x[3],y[4],g);
		drawConnect(x[3],y[0],g);

		//Draw parameter strings
		//if(IsFocusOn){drawStrings(g);}
		
		drawStrings(g); // print twice, smoothed characters wash out on dark background
		drawStrings(g);
		
	}

	private void drawGrid(int [] x,int [] y,Graphics g){
		g.setColor(Color.yellow);
		for(int i = 0 ; i< 5; i++){
			g.drawLine(x[0],y[i],x[4],y[i]);
			g.drawLine(x[i],y[0],x[i],y[4]);
		}
	}


	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.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.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);
		/*
		g.setColor(c.brighter());
		g.drawArc(x-radius,y-radius,2*radius,2*radius,60,120);
		*/
	}

	private void drawConnect(int x, int y, Graphics g){
		int tmp1, tmp2;
		tmp1 = 7;
		tmp2 = 5;
		//drawRect(x,y,tmp1,tmp1,Color.white,g);
		//drawRect(x,y,tmp2,tmp2,Color.black,g);
                
            Graphics2D g2d = (Graphics2D)g;
               
                g2d.setStroke(new BasicStroke(1));
        
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

                g2d.setPaint(Color.white);
                g.fillOval(x-tmp1/2,y-tmp1/2,tmp1,tmp1);
                g2d.setPaint(Color.black);
                g.fillOval(x-tmp2/2,y-tmp2/2,tmp2,tmp2);

                g2d.setStroke(new BasicStroke(1));
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
	}

	private void drawWire(int x1, int y1, int x2, int y2, int mode, Graphics g){
		g.setColor(Color.white);
		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);
		}
	}

	

	public void drawRef(Graphics g){
	
	  if(state.xpos <=state.lineLength && state.xpos >= 0.0){
		int tx1, ty1, tx2, ty2;
		tx1 = (int)(x[3] - (state.xpos/state.lineLength)*(x[3]-xtr));
		ty1 = y[4]-10;
		tx2 = tx1;
		ty2 = y[0]+10;
		
		g.setColor(Color.green);
		g.drawLine(tx1,ty1,tx2,ty2);
          }
	
	}
	
	private void drawTransf(Graphics g){
	    Graphics2D g2d = (Graphics2D)g;
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
            
	    int tx1, ty1, tx2, ty2, ty3;
	    String tmp;
	    FontMetrics fm;
	    fm = g.getFontMetrics();
	    if(state.getDrawTransformer1()){
	    
		tx1 = (int)(x[3] - (state.d1/state.lineLength)*(x[3]-xtr));
		ty1 = y[4]-10;
		tx2 = tx1;
		ty2 = y[0]+10;
		ty3 = ty1+1;
		
		g.setColor(Color.red);
		g.drawLine(tx1,ty1,tx2,ty2);
		
		int x1 = (int)(x[3] - (state.d1+0.25)/state.lineLength*(x[3]-xtr));
		int y1 = y[4];
		int w1 = (int)((0.25/state.lineLength)*(x[3]-xtr));
		int h1 = y[0]-y[4]-1;
		int x2 = x1 + w1/2-10;
		int y2 = y1 + h1/2;
		
		g.setColor(Color.white);
		g.fillRect(x1,y1,w1,h1);
		
		g.setColor(Color.red);
		MaestroG.subscripterSanSym3("Z","","02"," ","",g,12,x2,y2);
                MaestroG.subscripterSymFirst3("\u03b5","r","2","",g,12,x2,y2+20);
		
                g.setColor(Color.white);
		MaestroG.subscripter("Z","01"," ",g,12,x1-30,y2);
		g.setFont(TheFonts.serif12);
		MaestroG.subscripterSymFirst3("\u03b5","r","1","",g,12,x1-30,y2+20);
		
		if(state.getZL().Imaginary()!=0.0){
		    g.setColor(Color.white);
                    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		    MaestroG.subscripter("Z","01"," ",g,12,x1+w1+5,y2);
		    MaestroG.subscripterSymFirst3("\u03b5","r","1","",g,12,x1+w1+5,y2+20);
		
		    g.setColor(Color.green);
		    g.drawLine(tx1-10,ty3,tx1+5,ty3);
		    MaestroG.drawArrow(tx1+5,ty3,7,g);
                    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		    tmp=new String(" = "+MaestroA.rounder(state.Zin1.Real(),2));
                    // CHANGE ==================================================
                    //MaestroG.subscripterSanSym2("Z","",tmp," \u03a9",g,12,tx1-30,ty3-8);
                    MaestroG.subscripterSanSym2("Z","",tmp," \u03a9",g,12,tx1-35,ty3-8);
                    //==========================================================
		    g.setFont(TheFonts.sanSerif16);
		}
		if(state.getAtInput()){
		    g.setColor(Color.green);
		    g.drawLine(x1-10,ty3,x1+5,ty3);
		    MaestroG.drawArrow(x1+5,ty3,7,g);
                    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		    tmp = new String(" = "+MaestroA.rounder(state.getZ0old(),2));
                    MaestroG.subscripterSanSym2("Z","in",tmp," \u03a9",g,12,x1-60,ty3-8);
		    g.setFont(TheFonts.sanSerif16);
		}
		
	    }
	    if(state.getDrawTransformer2()){
	    
		
		tx1 = (int)(x[3] - (state.d2/state.lineLength)*(x[3]-xtr));
		ty1 = y[4]-10;
		tx2 = tx1;
		ty2 = y[0]+10;
		ty3 = ty1+1;
		
		g.setColor(Color.red);
		g.drawLine(tx1,ty1,tx2,ty2);
		
		
		int x1 = (int)(x[3] - (state.d2+0.25)/state.lineLength*(x[3]-xtr));
		int y1 = y[4];
		int w1 = (int)((0.25/state.lineLength)*(x[3]-xtr));
		int h1 = y[0]-y[4]-1;
		int x2 = x1 + w1/2-10;
		int y2 = y1 + h1/2;
				
		g.setColor(Color.green);
		g.drawLine(tx1-10,ty3,tx1+5,ty3);
		MaestroG.drawArrow(tx1+5,ty3,7,g);
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		tmp = new String(" = "+MaestroA.rounder(state.Zin2.Real(),2));
		MaestroG.subscripterSanSym2("Z","",tmp," \u03a9",g,12,tx1-30,ty3-8);
                g.setFont(TheFonts.sanSerif16);
		
		if(state.getAtInput()){
		    g.setColor(Color.green);
		    g.drawLine(x1-10,ty3,x1+5,ty3);
		    MaestroG.drawArrow(x1+5,ty3,7,g);
                    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		    tmp = new String(" = "+MaestroA.rounder(state.getZ0old(),2));
		    MaestroG.subscripterSanSym2("Z","in",tmp," \u03a9",g,12,x1-60,ty3-8);
                    g.setFont(TheFonts.sanSerif16);
		}
		
		g.setColor(Color.white);
		g.fillRect(x1,y1,w1,h1);
		g.setColor(Color.red);
		MaestroG.subscripterSanSym3("Z","","02"," ","",g,12,x2,y2);
                MaestroG.subscripterSymFirst3("\u03b5","r","2","",g,12,x2,y2+20);
		
		g.setColor(Color.white);
		MaestroG.subscripter("Z","01"," ",g,12,x1-30,y2);
		
		g.setColor(Color.white);
		MaestroG.subscripter("Z","01"," ",g,12,x1+w1+20,y2);
		
	
		MaestroG.subscripterSymFirst3("\u03b5","r","1","",g,12,x1-30,y2+20);
		MaestroG.subscripterSymFirst3("\u03b5","r","1","",g,12,x1+w1+20,y2+20);
		
	    }
	        	
	}
	
	private void drawAxis(Graphics g){
		int ytmp;
		FontMetrics fm;
                
                Graphics2D g2d = (Graphics2D)g;
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
            
		ytmp=y[0] + 15;
		g.setColor(Color.black);
		g.drawLine(x[4],ytmp,x[0],ytmp);
		g.drawLine(x[2],ytmp-4,x[2],ytmp+4);
		g.drawLine(x[3],ytmp-4,x[3],ytmp+4);
		//Arrowhead
		MaestroG.drawArrow(x[0],ytmp,8,g);
		g.setFont(TheFonts.sanSerif12);
		fm = g.getFontMetrics();
                g.setColor(Color.white);
		MaestroG.subscripterSerIT("l","","",g,16,x[2],ytmp+fm.getHeight()+3);
		g.drawString("0",x[3]-4,ytmp+fm.getHeight()+3);
                MaestroG.subscripter("d","","",g,12,x[0],ytmp+fm.getHeight()+3);
                
                // print again because smoothed fonts wash out on dark
                MaestroG.subscripterSerIT("l","","",g,16,x[2],ytmp+fm.getHeight()+3);
		g.drawString("0",x[3]-4,ytmp+fm.getHeight()+3);
                MaestroG.subscripter("d","","",g,12,x[0],ytmp+fm.getHeight()+3);
	}
	
	private void drawStrings(Graphics g){
		Graphics2D g2d = (Graphics2D)g;
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
            
                String tmp;
		g.setColor(Color.white);
		g.setFont(TheFonts.sanSerif12);
		FontMetrics fm = g.getFontMetrics();
		
		int xz0 = x[2]-50;
		int yz0 = getSize().height - 37;
                
                String temp = new String(" = "+MaestroA.rounder(state.getZ0old(),4));
		MaestroG.subscripterSanSym2("Z","01",temp," \u03a9",g,12,xz0,yz0);
		
		int xzTR = (x[2]+x[3])/2-15;
		int yzTR = getSize().height - 37;
		
		if(state.getDrawTransformer1()){
                    MaestroG.subscripterSanSym2("Z","02"," = "+MaestroA.rounder(state.Z_transformer1,4)," \u03a9",g,12,xzTR,yzTR);
		}
		if(state.getDrawTransformer2()){
                    MaestroG.subscripterSanSym2("Z","02"," = "+MaestroA.rounder(state.Z_transformer2,4)," \u03a9",g,12,xzTR,yzTR);
		}
		
		int xzL0 = (x[2]+x[3])/2-15;
		int yzL0 = getSize().height - 55;
                
                if(Complex.Real(state.getZL())==0.0&&Complex.Imaginary(state.getZL())<=-2.0E140){ 
                    MaestroG.subscripter("Z","L"," =         ( Open Circuit )",g,12,xzL0,yzL0);
		}
		else if(Complex.Real(state.getZL())==0.0&&Complex.Imaginary(state.getZL())==0.0){ 
                    MaestroG.subscripter("Z","L"," = 0        ( Short Circuit )",g,12,xzL0,yzL0);
		}
		else{
                    temp = new String(new Complex(MaestroA.rounder(Complex.Real(state.getZL()),4),
				    MaestroA.rounder(Complex.Imaginary(state.getZL()),4))+"");
                    MaestroG.subscripterSanSym2("Z","L"," = "+temp," \u03a9",g,12,xzL0,yzL0);
		}

		g.setColor(Color.white);		
		
		// write frequency	
		int x0 = x[2]-50;
                int x00 = x0+20;
		int y0 = getSize().height - 55;
		double f_normalized;
		frequency = state.frequency;
	
		if(frequency < 1.0E3){
		    f_normalized = frequency;
		    g.drawString("=  "+MaestroA.rounder(f_normalized,6)+"   Hz",x00,y0);	
		}
		else if(frequency < 1.0E6 && frequency >= 1.0E3  ){
		    f_normalized = frequency/1.0E3;
		    g.drawString("=  "+MaestroA.rounder(f_normalized,6)+"   kHz",x00,y0);	
		}
		else if(frequency < 1.0E9 && frequency >= 1.0E6 ){
		    f_normalized = frequency/1.0E6;
		    g.drawString("=  "+MaestroA.rounder(f_normalized,6)+"   MHz",x00,y0);	
		}
		else if(frequency < 1.0E12 && frequency >= 1.0E9 ){
		    f_normalized = frequency/1.0E9;
		    g.drawString("=  "+MaestroA.rounder(f_normalized,6)+"   GHz",x00,y0);	
		}
		else if(frequency < 1.0E15 && frequency >=1.0E12 ){
		    f_normalized = frequency/1.0E12;
		    g.drawString("=  "+MaestroA.rounder(f_normalized,6)+"   THz",x00,y0);	
		}
		else{
		    f_normalized = frequency/1.0E12;
		    g.drawString("=  "+MaestroA.rounder(f_normalized,6)+"   THz",x00,y0);
		}
		
		MaestroG.subscripterSerIT("  f","","",g,12,x0,y0);
		
		int xeps1 = x[2]-50;
		int xeps2 = (x[2]+x[3])/2-15;
		int yeps = getSize().height - 20;
		
		MaestroG.subscripterSymFirst3("\u03b5","r", "1"," = "+MaestroA.rounder(state.epsilon_r1,4),g,12,xeps1,yeps);
		
		//if(state.getDrawTransformer1() || state.getDrawTransformer2()){
		MaestroG.subscripterSymFirst3("\u03b5","r", "2"," = "+MaestroA.rounder(state.epsilon_r2,4),g,12,xeps2,yeps);
		//}
	}
	
	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){
	
	}
    
}//End of CircuitCanvs

