//DrawCanvas.java
import java.awt.*;
import java.awt.geom.Line2D;

class DrawCanvas extends Canvas{
    private Image im;
    private Graphics buf;
    DipoleAnt ant;
    Rectangle r;

    DrawCanvas(DipoleAnt ant){
            super();
            this.ant=ant;
    }
    public void drawCanvas(Graphics g){
        Graphics2D g2d = (Graphics2D)g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        
        int i, numpoints, length_monopole, ycenter, deltay;
        int x1, y1, x2, y2, x3, y3;
        r = getBounds();
        g.setColor(Color.white);
        g.fill3DRect(0,0,r.width-1,r.height-1,true);
        
        ycenter = (int)(r.height*0.478);
        //deltay = (int)(r.height*0.20*0.05);
        //deltay = (int)(5*getSize().height/100);
        deltay = ant.s4;
        length_monopole = (int)(r.height*((0.44)*ant.dipolelength/ant.dipolelengthmax));
        
        if((int)ant.dipolelengthmax < 6){
            //deltay = (int)(r.height*0.30*0.05);
            length_monopole = (int)(r.height*((0.43)*ant.dipolelength/ant.dipolelengthmax));
        }
        else if((int)ant.dipolelengthmax >= 6 && (int)ant.dipolelengthmax < 11){
            //deltay = (int)(r.height*0.20*0.05);
            length_monopole = (int)(r.height*((0.44)*ant.dipolelength/ant.dipolelengthmax));
        }
        else if((int)ant.dipolelengthmax >= 11 && (int)ant.dipolelengthmax <= 20){
            //deltay = (int)(r.height*0.15*0.05);
            length_monopole = (int)(r.height*((0.45)*ant.dipolelength/ant.dipolelengthmax));
        }
        
        int dipole_x = (int)(r.width*0.35);
        int length_x = (int)(r.width*0.5) + ant.s10;
        
        g.setColor(Color.black);
       
        g.drawLine((int)(r.width*0.1 - ant.s10), ycenter - deltay,
                   (int)(dipole_x - ant.s10),ycenter - deltay);
        g.drawLine((int)(r.width*0.1 - ant.s10), ycenter + deltay,
                   (int)(dipole_x - ant.s10),ycenter + deltay);
        
        if(ant.dipolelength > 0.0){
            g.setColor(Color.red);
            // draw the dipole
            //MaestroG.drawLineThick ---> Rounded end lines
            //MaestroG.drawLineThick2 ---> Butt end lines
            MaestroG.drawLineThick2(g, dipole_x - ant.s10, ycenter - deltay, 
                dipole_x-ant.s10, ycenter - deltay - length_monopole, ant.s3, Color.red);
            MaestroG.drawLineThick2(g, dipole_x - ant.s10, ycenter + deltay, 
                dipole_x-ant.s10, ycenter + deltay + length_monopole, ant.s3, Color.red);
            
            // draw cross-section if choosing rounded end lines (increase thickness of dipoles)
            //g.setColor(new Color(240,240,240));
            //MaestroG.fillCircle((int)(r.width*0.35 - ant.s10), ycenter - deltay - length_monopole,ant.s3,g);
            //MaestroG.fillCircle((int)(r.width*0.35 - ant.s10)+ant.s1, ycenter - deltay - length_monopole,ant.s3,g);
            
            //MaestroG.fillCircle((int)(r.width*0.35 - ant.s10), ycenter + deltay,ant.s3,g);
            //MaestroG.fillCircle((int)(r.width*0.35 - ant.s10)+ant.s1, ycenter + deltay,ant.s3,g);

            // Length of antenna - Vertical line
            MaestroG.drawLineThick2(g, length_x, ycenter - deltay - length_monopole,  
                length_x, ycenter + deltay + length_monopole, 1, Color.gray);
            
            // limits - horizontal line
            MaestroG.drawLineThick2(g, length_x - ant.s5, ycenter - deltay - length_monopole,  
                length_x + ant.s5, ycenter - deltay - length_monopole, 1, Color.gray);
            MaestroG.drawLineThick2(g, length_x - ant.s5, ycenter + deltay + length_monopole,  
                length_x + ant.s5, ycenter + deltay + length_monopole, 1, Color.gray);
            
            if(length_monopole >= ant.s10){
                MaestroG.drawArrowScaled(length_x, ycenter + deltay + length_monopole - ant.s8, 2, ant.sfactor, g);
                MaestroG.drawArrowScaled(length_x, ycenter - deltay - length_monopole + ant.s8, 1, ant.sfactor, g);
                
                g.setColor(Color.black);
                g.setFont(new Font("Times",Font.ITALIC,ant.font20));
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                //g.drawString("l",length_x + ant.s8,(int) (r.height*0.5));
                MaestroG.subscripter2B("","l","","",g,ant.font20,length_x + ant.s8,(int) (r.height*0.5));
            }
            else{
                MaestroG.drawArrowScaled(length_x, ycenter + deltay + length_monopole + ant.s8, 1, ant.sfactor, g);
                MaestroG.drawArrowScaled(length_x, ycenter - deltay - length_monopole - ant.s8, 2, ant.sfactor, g);
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        
                g.setColor(Color.black);
                g.setFont(new Font("Times",Font.ITALIC,ant.font20));
                //g.drawString("l",length_x + ant.s8,(int) (r.height*0.5));
                MaestroG.subscripter2B("","l","","",g,ant.font20,length_x + ant.s8,(int) (r.height*0.5));
            }
        }
        g.setColor(Color.black);
        x3 = (int) (r.width*0.30 + ant.s10);
        y3 = (int) (r.height*0.5);
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        
        g.setFont(new Font("SanSerif",Font.BOLD,ant.font13));
        g.drawString("Dipole",x3,y3);
        
        int current_x = (int)(r.width*0.78);
        int current_0 = ant.s35;
        
        numpoints=(int)(r.height*0.45f*ant.dipolelength/(ant.dipolelengthmax));
        
        g.setColor(Color.green.darker());
        
        if(ant.dipolelength>=(ant.dipolelengthmax/100.0f)){
            for(i=-numpoints;i<numpoints;i++){
                y2 = (int)(r.height*(0.48f)+i);
                y1 = y2-1;
                x2 = (int)(current_x + current_0 * ant.scaling *Math.sin(Math.PI*ant.dipolelength
                                               -2.0*Math.PI*Math.abs(i+1)*ant.dipolelength/(2.0*numpoints)));
                x1 = (int)(current_x + current_0 * ant.scaling*Math.sin(Math.PI*ant.dipolelength
                                               -2.0*Math.PI*Math.abs(i)*ant.dipolelength/(2.0*numpoints)));
                g.drawLine(x1, y1, x2, y2);
            }
            //draw the axis
            g.setColor(Color.black);		
            y2=(int)(r.height*(0.48f)+numpoints);
            y1=(int)(r.height*(0.48f)-numpoints)-1;
            x2=(int)(current_x);
            x1=(int)(current_x);
            g.drawLine(x1,y1,x2,y2);
        }
        else{
            x1=(int)(current_x);
            x2 = x1 + current_0;
            y1=(int)(r.height*0.48f);
            y2=y1;
            g.drawLine(x1,y1,x2,y2);
            
            //draw the axis
            g.setColor(Color.black);		
            y2=(int)(r.height*(0.48f)+numpoints);
            y1=(int)(r.height*(0.48f)-numpoints);
            x2=(int)(current_x);
            x1=(int)(current_x);
            g.drawLine(x1,y1,x2,y2);
        }
        
        MaestroG.drawLineThick2(g, current_x - current_0 - ant.s5, (double)ycenter, current_x + current_0 + ant.s10, (double)ycenter, 1, Color.gray);
        MaestroG.drawLineThick2(g, current_x + current_0, (double)(ycenter + ant.s5), current_x + current_0, (double)(ycenter - ant.s5), 1, Color.gray);
        MaestroG.drawArrowScaled(current_x + current_0 + ant.s10, ycenter, 3, ant.sfactor, g);
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        MaestroG.subscripter2B("","I","0","",g,ant.font12,current_x + current_0,ycenter - ant.s9);
        
        g.setColor(Color.black);
        g.setFont(new Font("SanSerif",Font.BOLD,ant.font13));
        g.drawString("Current",x2 - ant.s20,y2 + ant.s14);
        //g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
        
    }
    
    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);
        //drawCanvas(g);
    }

    //Addition to reduce flicker 
    public void update(Graphics g){		// added to avoid clearing
        paint(g);
    }

    public void redraw(){
            repaint();
    }
    
    public static void drawLineThick(Graphics g, double x1, double y1, double x2, double y2, int thick, Color color){
	
        Graphics2D g2d = (Graphics2D)g;
        g2d.setPaint(color);
        g2d.setStroke(new BasicStroke(thick,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
        
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
        
        Line2D.Double line = new Line2D.Double(x1,y1,x2,y2);
        g2d.draw(line);
  
        g2d.setStroke(new BasicStroke(1));
        //g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
    }
}
