//GraphCanvas.java

import java.awt.*;
import java.awt.geom.Line2D;

public class GraphCanvasD extends Canvas{
    protected static final Color bgcolor = Color.lightGray;
    protected Image im;
    protected Graphics buf;
    protected int LeftMargin;
    protected int TopSep;
    protected int BottomSep;
    protected int RightMargin;
    protected int VPos=0;
    protected String XLabel, YLabel, TITLE;
    protected String X1, X2, X3;
    protected String Y1, Y2, Y3;
    protected int NumPoints;
    protected double x[];
    protected double y[];
    protected double phi_angle, Mag;
    protected double ymin, ymax;
    protected double xmin, xmax;
    protected int xx[];
    protected int yy[];
    protected int flag;
    protected int type;
    protected double xRef;
    protected boolean Should_Plot_Zero_Line;
    protected boolean Should_Plot_Ref_Point;
    protected boolean IsYRangeMinSet, IsYRangeMaxSet;
    protected boolean IsXRangeMinSet, IsXRangeMaxSet;
    protected boolean IsPolar, is_theta_plane, Is_dB, IsTE, onlyDirect;
    protected Font font1;
    protected Font font2;
    NewGuide_State state;
    
    public GraphCanvasD(NewGuide_State state){
	super();
        this.state = state;
        
        LeftMargin = state.s60;
        TopSep = state.s40;
        BottomSep = state.s40;
        RightMargin = state.s40;
        font1 = new Font("Serif",Font.PLAIN,state.font12);
        font2 = new Font("SanSerif",Font.PLAIN,state.font11);
    
	setBackground(bgcolor);
	XLabel="x-axis";
	YLabel="y-axis";
	TITLE ="Unknown Title";
	Y1 = " ";
	Y2 = " ";
	Y3 = " ";
	X1 = " ";
	X2 = " ";
	X3 = " ";
	NumPoints = 361;
	x = new double[NumPoints];
	y = new double[NumPoints];
	xx = new int[NumPoints];
	yy = new int[NumPoints];
	for(int i=0;i<NumPoints;i++){
	    x[i]=i;
	    y[i]=0.0;
	}
	//phi_angle = 45;
        //Mag = 1.0;
        IsTE = true;
        onlyDirect = false;
    }
    
    @Override
    public void paint(Graphics g){
    
    if(im == null){
	im = createImage(getSize().width,getSize().height);
	buf = im.getGraphics();
	
        drawGraph2(buf);
    }
    
	drawGraph2(buf);
    
    g.drawImage(im,0,0,null);
}

    public void drawGraph2(Graphics g){
        
	g.clearRect(0,0,getSize().width,getSize().height);
	
		int i;
		double theta;
		double geom;
		
                int rwidth = getSize().width;
		int rheight = getSize().height;
		double phi;
		phi = (double)((int)phi_angle);
		
                
		//g.setColor(Color.lightGray);
		//g.fill3DRect(0,0,rwidth,rheight,true);
                
		Graphics2D g2d = (Graphics2D)g;
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                
		int myx, myy1, myy2;
                myx = state.s10;
                myy1 = getSize().height - state.s25;
                myy2 = getSize().height - state.s10;
		if(IsTE){
                    g.setColor(Color.red.darker());
                    MaestroG.subscripter("Received","","",g,state.font13,myx,myy1);
                    MaestroG.subscripter("Electric Field","","",g,state.font13,myx,myy2);
                }
                else{
                    g.setColor(Color.blue.darker());
                    MaestroG.subscripter("Received","","",g,state.s13,myx,myy1);
                    MaestroG.subscripter("Magnetic Field","","",g,state.s13,myx,myy2);
                }
                
                g.setColor(Color.blue.darker());
                MaestroG.special2("","DIRECT","","",g,state.font11,state.s55,state.s13);
                MaestroG.drawLineThick(g,state.s15,state.s8,state.s45,state.s8,2,Color.blue.darker());
                MaestroG.drawLineThick(g,state.s38,state.s5,state.s45,state.s8,2,Color.blue.darker());
                MaestroG.drawLineThick(g,state.s38,state.s11,state.s45,state.s8,2,Color.blue.darker());
                g.setColor(Color.red.darker());
                MaestroG.special2("","REFLECTED","","",g,state.font11,state.s160,state.s13);
                MaestroG.drawLineThick(g,state.s120,state.s8,state.s150,state.s8,2,Color.red);
                MaestroG.drawLineThick(g,state.s143,state.s5,state.s150,state.s8,2,Color.red);
                MaestroG.drawLineThick(g,state.s143,state.s11,state.s150,state.s8,2,Color.red);
                g.setColor(Color.yellow);
                MaestroG.special2("","TOTAL","","",g,state.font11,state.s200+state.s90,state.s13);
		MaestroG.drawLineThick(g,state.s200+state.s50,state.s8,state.s200+state.s80,state.s8,2,Color.yellow);
                MaestroG.drawLineThick(g,state.s200+state.s73,state.s5,state.s200+state.s80,state.s8,2,Color.yellow);
                MaestroG.drawLineThick(g,state.s200+state.s73,state.s11,state.s200+state.s80,state.s8,2,Color.yellow);
                
		g.setColor(Color.white);
		//draw concentric circles
		g.drawOval((int)(rwidth*0.4),(int)(rwidth*0.4),(int)(rwidth*0.20),(int)(rwidth*0.20));
		g.drawOval((int)(rwidth*0.3),(int)(rwidth*0.3),(int)(rwidth*0.40),(int)(rwidth*0.40));
		g.drawOval((int)(rwidth*0.2),(int)(rwidth*0.2),(int)(rwidth*0.60),(int)(rwidth*0.60));
		g.drawOval((int)(rwidth*0.1),(int)(rwidth*0.1),(int)(rwidth*0.80),(int)(rwidth*0.80));
                
		//draw radial lines
		g.drawLine((int)(rwidth*0.1),(int)(rwidth*0.5),(int)(rwidth*0.9),(int)(rwidth*0.5));
		g.drawLine((int)(rwidth*0.5),(int)(rwidth*0.1),(int)(rwidth*0.5),(int)(rwidth*0.9));
		g.drawLine( (int)(rwidth*(0.5+0.4*(0.866))), (int)(rwidth*(0.5+0.4*(0.5))), 
                            (int)(rwidth*(0.5-0.4*(0.866))), (int)(rwidth*(0.5-0.4*(0.5))));
		g.drawLine( (int)(rwidth*(0.5-0.4*(0.866))), (int)(rwidth*(0.5+0.4*(0.5))), 
                            (int)(rwidth*(0.5+0.4*(0.866))), (int)(rwidth*(0.5-0.4*(0.5))));
		g.drawLine( (int)(rwidth*(0.5+0.4*(0.5))), (int)(rwidth*(0.5+0.4*(0.866))), 
                            (int)(rwidth*(0.5-0.4*(0.5))), (int)(rwidth*(0.5-0.4*(0.866))));
		g.drawLine( (int)(rwidth*(0.5-0.4*(0.5))), (int)(rwidth*(0.5+0.4*(0.866))), 
                            (int)(rwidth*(0.5+0.4*(0.5))), (int)(rwidth*(0.5-0.4*(0.866))));
		
                float[] dashPattern = {state.s5,state.s5};// Add these lines to make line dotted
                g2d.setStroke(new BasicStroke(1.0F,BasicStroke.CAP_BUTT,BasicStroke.JOIN_MITER,10.0F,dashPattern,0));
                g.setColor(Color.white); // locus of resultant
                //g.setColor(new Color(150,255,150)); // locus of resultant
                g.drawOval((int)(rwidth*0.5),(int)(rwidth*0.3),(int)(rwidth*0.40),(int)(rwidth*0.40));
                g2d.setStroke(new BasicStroke(1));
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
    
		g.setColor(Color.black);
		//write the angles
		{   g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                        g.setColor(Color.black);
			g.setFont(new Font("Serif",Font.PLAIN,state.font20));
			g.drawString("\u0394\u03d5",getSize().width - state.s50,getSize().height - state.s25);
                        			
			g.setFont(new Font("Sanserif",Font.PLAIN,state.font11));
			g.setColor(Color.black);
			g.drawString("90\u00ba",(int)(rwidth*  (0.5-0.42*(0.050))),(int)(rwidth*(0.5+0.42*(-1.00))));
			g.drawString("60\u00ba",(int)(rwidth* (0.5+0.45*(0.450))),(int)(rwidth*(0.5+0.44*(-0.866))));
			g.drawString("120\u00ba",(int)(rwidth* (0.5-0.47*(0.550))),(int)(rwidth*(0.5+0.44*(-0.866))));
			g.drawString("30\u00ba",(int)(rwidth* (0.5+0.42*(0.866))),(int)(rwidth*(0.5+0.42*(-0.50))));
			g.drawString("150\u00ba",(int)(rwidth* (0.5-0.44*(1.0))),(int)(rwidth*(0.5+0.44*(-0.47))));
			g.drawString("0\u00ba",(int)(3+rwidth* (0.5+0.41*(1.000))),(int)(rwidth*(0.5+0.42*(0.05))));
			g.drawString("180\u00ba",(int)(rwidth* (0.5-0.44*(1.10))),(int)(rwidth*(0.5+0.45*(0.05))));
			g.drawString("330\u00ba",(int)(rwidth*(0.5+0.43*(0.866))),(int)(rwidth*(0.5+0.48*(0.50))));
			g.drawString("210\u00ba",5+(int)(rwidth* (0.5-0.44*(1.0))),(int)(rwidth*(0.5+0.48*(0.50))));
			g.drawString("300\u00ba",(int)(rwidth*(0.5+0.42*(0.450))),(int)(rwidth*(0.5+0.47*(0.866))));
			g.drawString("240\u00ba",(int)(rwidth*(0.5-0.47*(0.550))),(int)(rwidth*(0.5+0.47*(0.866))));
			g.drawString("270\u00ba",(int)(rwidth*(0.5-0.42*(0.05))),(int)(rwidth*(0.5+0.44*(1.05))));
		}
		
		//Now draw the radiation diagram
		int vectormod = 4*rwidth/20;
                int xcenter = rwidth/2;
                int ycenter = rheight/2;
                double tipDirectx, tipDirecty,tipReflectx, tipReflecty, tipResultx, tipResulty;
                                
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                
                double angolo, angolo2, angolone, tempx, tempy, Len;
                tipResultx = (double)(xcenter + vectormod) + (vectormod*Mag*Math.cos(phi_angle));
                tipResulty = (double) ycenter - vectormod*Mag*Math.sin(phi_angle);
                tipDirectx = (double)(xcenter + vectormod);
                tipDirecty = (double) ycenter;
                tipReflectx = (double)xcenter + (vectormod*Mag*Math.cos(phi_angle));
                tipReflecty = (double) ycenter - vectormod*Mag*Math.sin(phi_angle);
                
                if(!onlyDirect){
                    drawLineThickDashed(g,tipReflectx,tipReflecty,tipResultx,tipResulty,1,Color.gray);
                    drawLineThickDashed(g,tipDirectx,tipDirecty,tipResultx,tipResulty,1,Color.gray);
                }
                
                // Resultant vector
                g.setColor(Color.yellow);
                Len = state.s7;
                int ThickL = state.s2;
                tempx = (double)(xcenter + vectormod) + (vectormod*Mag*Math.cos(phi_angle));
                tempy = (double) ycenter - vectormod*Mag*Math.sin(phi_angle);
                angolone = Math.atan(vectormod*Mag*Math.sin(phi_angle)/((double)(vectormod) + (vectormod*Mag*Math.cos(phi_angle))));
                angolo = Math.PI*0.5-(angolone+Math.PI)-25.0*Math.PI/180.0;
                angolo2 = (angolone+Math.PI)-25.0*Math.PI/180.0;
                
                if(!onlyDirect){
                    MaestroG.drawLineThick(g,tempx,tempy,tempx+Len*Math.sin(angolo),tempy-Len*Math.cos(angolo),ThickL,Color.yellow);
                    MaestroG.drawLineThick(g,tempx,tempy,tempx+Len*Math.cos(angolo2),tempy-Len*Math.sin(angolo2),ThickL,Color.yellow);
                    MaestroG.drawLineThick(g, (double) xcenter, (double) ycenter, tipResultx, tipResulty, ThickL, Color.yellow);
                }
                
                // Direct path
                //g.setColor(Color.red);
                //g.drawLine(xcenter, ycenter, xcenter + vectormod, ycenter);
                MaestroG.drawLineThick(g, (double) xcenter, (double) ycenter, tipDirectx, tipDirecty, ThickL, Color.blue.darker());
                MaestroG.drawLineThick(g, (double)(xcenter + vectormod), (double) ycenter, (double)(xcenter + vectormod-state.s6), (double) (ycenter-3), ThickL, Color.blue.darker());
                MaestroG.drawLineThick(g, (double)(xcenter + vectormod), (double) ycenter, (double)(xcenter + vectormod-state.s6), (double) (ycenter+3), ThickL, Color.blue.darker());
                
                // Reflected path
                //g.setColor(Color.blue);
                //g.drawLine(xcenter, ycenter, xcenter + (int)(vectormod*Math.cos(phi_angle)), ycenter - (int)(vectormod*Math.sin(phi_angle)));
                Len = state.s7;
                angolo = Math.PI*0.5-(phi_angle+Math.PI)-25.0*Math.PI/180.0;
                angolo2 = (phi_angle+Math.PI)-25.0*Math.PI/180.0;
                tempx = (double)xcenter + (vectormod*Mag*Math.cos(phi_angle));
                tempy = (double) ycenter - vectormod*Mag*Math.sin(phi_angle);
                if(!onlyDirect){
                    MaestroG.drawLineThick(g, (double) xcenter, (double) ycenter, tipReflectx, tipReflecty, ThickL, Color.red);
                    if(Mag < 0.2){
                        MaestroG.drawLineThick(g,tempx,tempy,tempx+(Len*5*Mag)*Math.sin(angolo),tempy-(Len*5*Mag)*Math.cos(angolo),ThickL,Color.red);
                        MaestroG.drawLineThick(g,tempx,tempy,tempx+(Len*5*Mag)*Math.cos(angolo2),tempy-(Len*5*Mag)*Math.sin(angolo2),ThickL,Color.red);
                    }
                    else{
                        MaestroG.drawLineThick(g,tempx,tempy,tempx+(Len)*Math.sin(angolo),tempy-(Len)*Math.cos(angolo),ThickL,Color.red);
                        MaestroG.drawLineThick(g,tempx,tempy,tempx+(Len)*Math.cos(angolo2),tempy-(Len)*Math.sin(angolo2),ThickL,Color.red);
                    }
                }
                
    }

    public static void drawLineThickDashed(Graphics g, double x1, double y1, double x2, double y2, int thick, Color color){
	
        Graphics2D g2d = (Graphics2D)g;
        g2d.setPaint(color);
        float[] dashPattern = {3,3};// Add these lines to make line dotted
        g2d.setStroke(new BasicStroke(1.0F,BasicStroke.CAP_BUTT,BasicStroke.JOIN_MITER,10.0F,dashPattern,0));
        
        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);
    }

    protected void ignition(){
    
    }

    public final synchronized void setLabels(String TITLE, String YLabel, String XLabel){
        this.TITLE=TITLE;
        this.YLabel = YLabel;
        this.XLabel = XLabel;
    }

    public final synchronized void setTitle(String TITLE){
        this.TITLE = TITLE;
    }
 
    public void plot(double[] xdata, double[] ydata){
        if(NumPoints != xdata.length){
            NumPoints = xdata.length;
            x = new double[NumPoints];
            y = new double[NumPoints];
            xx = new int[NumPoints];
            yy = new int[NumPoints];
        }
        for(int i = 0; i < NumPoints; i++){
            x[i] = xdata[i];
            y[i] = ydata[i];
        }
        repaint();
    }

    public void setPhiAngle(double phi_angle){
        this.phi_angle=phi_angle;
    }

    public void setReflectionMag(double Mag){
        this.Mag=Mag;
    }
    
    public void setVector(boolean onlyDirect){
        this.onlyDirect = onlyDirect;
    }

    public void setPolarization(boolean IsTE){
        this.IsTE = IsTE;
    }

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