//import java.applet.*;
//import java.lang.*;

import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.net.*;
import java.awt.event.*;

public class PlaneWaveCanvas extends Canvas implements MouseListener, MouseMotionListener, ItemListener{
    PlaneWave_State state;
    InputPanel inputpanel;
    
    private static final Color bgcolor = new Color(255,255,255); // white background
        
    public double xnewmax, xnewmin, ynewmax, ynewmin, xpos, ypos;
    
    int yshift = 250;
    private int LeftMargin=90, RightMargin=85, TopMargin=60, BottomMargin=210;
    
    private Image im;
    private Graphics buf;
    public int x_Center, y_Center;
   
    //---------------------------------------------------
    private double xpos_old, ypos_old; 
    private int xxpos, yypos, xxpos_old, yypos_old, xxpos_0, yypos_0;
    //---------------------------------------------------
    
    private boolean IsTraceOn, IsFieldOn, IsCleanUpOn, IsDynamic, IsStop, IsStart, IsReset;
    
    public PlaneWaveCanvas(PlaneWave_State state, InputPanel inputpanel){
	super();
	setBackground(bgcolor);
        this.state = state;
        this.inputpanel = inputpanel;
        
	IsTraceOn = false;
        IsFieldOn = true;
	IsCleanUpOn = false;
	IsDynamic = false;
	IsStop = true;
        IsStart = false;
        IsReset = true;
        
        //Center point for (601 X 601)  Adjust if you change canvas size
        x_Center = 300;
        y_Center = 300;
        
        //xnewmax = 1.0;
	//xnewmin = -1.0;
	//ynewmax = 1.0;
	//ynewmin = -1.0;
        
        xnewmax = 0.1;
	xnewmin = -0.1;
	ynewmax = 0.1;
	ynewmin = -0.1;
        
        xpos = 0.0;
        ypos = 0.0;
        
        this.addMouseListener(this);
	this.addMouseMotionListener(this);
    }
    
    public void mouseDragged(MouseEvent evt){cricket_3(evt);}
    public void mouseMoved(MouseEvent evt){;}//cricket_1(evt);}
    public void mouseClicked(MouseEvent evt){cricket_1(evt);}
    public void mouseEntered(MouseEvent evt){;} 
    public void mouseExited(MouseEvent evt){;}
    public void mousePressed(MouseEvent evt){cricket_1(evt);}
    public void mouseReleased(MouseEvent evt){cricket_1(evt);}
    public void itemStateChanged(ItemEvent evt){;}
    
    private  void cricket_1(MouseEvent evt){

	int x, y, xProbe, yProbe;
        double xtest, ytest;
	x=evt.getX();
	y=evt.getY();
	Graphics g = this.getGraphics();
	
        if(x < 600 && x > 0 && y < 600 && y > 0){
            xProbe = x - x_Center;
            yProbe = y - y_Center;
        }
        else{
            
            if (x <= 0 && y <= 0){x = 0; y = 0;} 
            else if (x <= 0 && y >= 600){x = 0; y = 600;}
            else if (x >= 600 && y <= 0){x = 600; y = 0;}
            else if (x >= 600 && y >= 600){x = 600; y = 600;} 
            else if (x <= 0){x = 0;}
            else if (x >= 600){x = 600;}
            else if (y <= 0){y = 0;}
            else if (y >= 600){y = 600;}
              
        }
            xProbe = x - x_Center;
            yProbe = y - y_Center;
        
        xtest = xProbe * state.xmax/x_Center;
        ytest = yProbe * state.ymax/y_Center;
        
        if(IsReset){
            state.xpos = MaestroA.rounder(xtest,3);
            state.ypos = MaestroA.rounder(ytest,3);
            state.xpos_0 = MaestroA.rounder(xtest,3);
            state.ypos_0 = MaestroA.rounder(ytest,3);
            state.xpos_old = state.xpos;
            state.ypos_old = state.ypos;
            xxpos = x;
            yypos = y;
            xxpos_old = x;
            yypos_old = y;
            xxpos_0 = x;
            yypos_0 = y;
            repaint();
            
            inputpanel.sliderx0.setValue((int)((state.xpos + state.xmax)/state.Deltax));
            inputpanel.slidery0.setValue((int)((state.ypos + state.ymax)/state.Deltax));
            inputpanel.repaint();
        }
        
    }
    
    private  void cricket_3(MouseEvent evt){

	int x, y, xProbe, yProbe;
        double xtest, ytest;
	x=evt.getX();
	y=evt.getY();
	Graphics g = this.getGraphics();
	
        if(x < 600 && x > 0 && y < 600 && y > 0){
            xProbe = x - x_Center;
            yProbe = y - y_Center;
        }
        else{
            
            if (x <= 0 && y <= 0){x = 0; y = 0;} 
            else if (x <= 0 && y >= 600){x = 0; y = 600;}
            else if (x >= 600 && y <= 0){x = 600; y = 0;}
            else if (x >= 600 && y >= 600){x = 600; y = 600;} 
            else if (x <= 0){x = 0;}
            else if (x >= 600){x = 600;}
            else if (y <= 0){y = 0;}
            else if (y >= 600){y = 600;}
              
        }
            xProbe = x - x_Center;
            yProbe = y - y_Center;
        
        xtest = xProbe * state.xmax/x_Center;
        ytest = yProbe * state.ymax/y_Center;
        
        if(IsReset){
            state.xpos = MaestroA.rounder(xtest,3);
            state.ypos = MaestroA.rounder(ytest,3);
            state.xpos_0 = MaestroA.rounder(xtest,3);
            state.ypos_0 = MaestroA.rounder(ytest,3);
            state.xpos_old = state.xpos;
            state.ypos_old = state.ypos;
            xxpos = x;
            yypos = y;
            xxpos_old = x;
            yypos_old = y;
            xxpos_0 = x;
            yypos_0 = y;
            
            repaint();
        }
        
    }
    
    
    public void paint(Graphics g){
	if(im == null){
	    im = createImage(getSize().width,getSize().height);
	    buf = im.getGraphics();
	    drawGraph(buf);
	}
	else{
            drawGraph(buf);
	}
	g.drawImage(im,0,0,null);
    }
    
    public void drawGraph(Graphics g){
	//g.draw3DRect(0,0,getSize().width-1,getSize().height-1,false);
	
	//this cleans the trajectory
	if(!IsTraceOn){g.clearRect(0,0,getSize().width,getSize().height);}
	if(IsReset){g.clearRect(0,0,getSize().width,getSize().height);}
        
        drawAxis(g);
        //drawStart(g);
	drawPoints(g,1);
	
    }
    
    public synchronized void ignition(){
        
        xxpos_0 = (int)MaestroA.mapper(state.xpos_0,0,(double)getSize().width,xnewmin,xnewmax);
        yypos_0 = (int)MaestroA.mapper(state.ypos_0,0,(double)getSize().height,ynewmin,ynewmax);
        
        xxpos_old = (int)MaestroA.mapper(xpos_old,0,(double)getSize().width,xnewmin,xnewmax);
        yypos_old = (int)MaestroA.mapper(ypos_old,0,(double)getSize().height,ynewmin,ynewmax);
        
        xxpos = (int)MaestroA.mapper(xpos,0,(double)getSize().width,xnewmin,xnewmax);
        yypos = (int)MaestroA.mapper(ypos,0,(double)getSize().height,ynewmin,ynewmax);
        
    }   
    
    
    private synchronized void drawAxis(Graphics g){
	
        Graphics2D g2d = (Graphics2D)g;
        int rule; 
        float alpha;
        rule = AlphaComposite.SRC_OVER;            
        
        //vertical lines
        Color line1 = new Color(250,250,250);
        Color line2 = new Color(235,235,255);
        
        for(int i = 1; i < 10; i++){
            if(i!=5){g.setColor(line1);}
            else{g.setColor(line2);}
            g.drawLine(i*30,0,i*30,getSize().height);
        }
        for(int i = 11; i < 20; i++){
            if(i!=15){g.setColor(line1);}
            else{g.setColor(line2);}
            g.drawLine(i*30,0,i*30,getSize().height);
        }
        for(int i = 1; i < 10; i++){
            if(i!=5){g.setColor(line1);}
            else{g.setColor(line2);}
            g.drawLine(0,i*30,getSize().width,i*30);
        }
        for(int i = 11; i < 20; i++){
            if(i!=15){g.setColor(line1);}
            else{g.setColor(line2);}
            g.drawLine(0,i*30,getSize().width,i*30);
        }
        
        
        
        g.setColor(Color.lightGray);
        //x axis
        g.drawLine(1,getSize().height/2,getSize().width-2,getSize().height/2);
        MaestroG.drawArrow(getSize().width-11,getSize().height/2,7,g);
        //y axis
        g.drawLine(getSize().width/2,1,getSize().width/2,getSize().height-2);
        MaestroG.drawArrow(getSize().width/2,getSize().height-11,6,g);
        
        //z axis
        g.setColor(Color.white);
        MaestroG.fillCircle(getSize().width/2,getSize().height/2,8,g);
        g.setColor(Color.lightGray);
        MaestroG.drawCircle(getSize().width/2,getSize().height/2,8,g);
        g.drawLine(getSize().width/2-3,getSize().height/2-3,getSize().width/2+3,getSize().height/2+3);
        g.drawLine(getSize().width/2-3,getSize().height/2+3,getSize().width/2+3,getSize().height/2-3);
        
        MaestroG.subscripter("x","","",g,11,getSize().width-12,getSize().height/2-5);
        MaestroG.subscripter("y","","",g,11,getSize().width/2-12,getSize().height-7);
        MaestroG.subscripter("z","","",g,11,getSize().width/2-12,getSize().height/2+12);
        
        if(!IsTraceOn && IsFieldOn){
            // H fields
            int xx = 8;
            int xxx = 5;
            int step = 75;
            Color newgray = new Color(230,230,230);


            if(state.Hz == 0.0){}
            else if(state.Hz > 0.0){
                g.setColor(newgray);
                MaestroG.subscripter("H","z","",g,16,step-45*xx/10,step);

                for(int i = 0; i < 4; i++){
                    for(int j = 0; j < 4; j++){
                        g.setColor(Color.white);
                        MaestroG.fillCircle(step+step*2*i,step+step*2*j,2*xx,g);
                        g.setColor(newgray);
                        MaestroG.drawCircle(step+step*2*i,step+step*2*j,2*xx,g);
                        g.drawLine(step+step*2*i-xxx,step+step*2*j-xxx,step+step*2*i+xxx,step+step*2*j+xxx);
                        g.drawLine(step+step*2*i-xxx,step+step*2*j+xxx,step+step*2*i+xxx,step+step*2*j-xxx);
                    }
                }
            }
            else{
                for(int i = 0; i < 4; i++){
                    for(int j = 0; j < 4; j++){
                        g.setColor(Color.white);
                        MaestroG.fillCircle(step+step*2*i,step+step*2*j,2*xx,g);
                        g.setColor(newgray);
                        MaestroG.drawCircle(step+step*2*i,step+step*2*j,2*xx,g);
                        MaestroG.fillCircle(step+step*2*i,step+step*2*j,2*xx/3,g);
                    }
                }
            }

            
            
            //E fields
            double EgoX, EgoY, Etest, Mtest, Elength, Mlength;
            double EFX, EFY;
            double BFX, BFY;
            double angle, angle1, angle2, length, lengthE, lengthM, stem;
            double angleB, angleB1, angleB2;
            angle = Math.atan(state.Ey/state.Ex);
            angleB = Math.atan(state.MFy/state.MFx);
            
            length = 15.0;
            stem = 60.0;
            
            Etest = Math.sqrt(state.EleFx*state.EleFx + state.EleFy*state.EleFy);
            Mtest = Math.sqrt(state.MFx*state.MFx + state.MFy*state.MFy);
            //if(Etest >= Mtest){
                Elength = stem;
                Mlength = Elength * Mtest/Etest;
                if(Mlength > 150.0){Mlength = 150.0;}
                if(Etest == 0.0){Mlength = stem;}
                
                lengthE = length * Elength/stem;
                lengthM = length * Mlength/stem;
                if(lengthE > 15.0){lengthE = 15.0;}
                if(lengthM > 15.0){lengthM = 15.0;}
                
            //}
            //else{
              //  Mlength = stem;
              //  Elength = Mlength * Etest/Mtest;
              //  lengthE = length * Elength/stem;
              //  lengthM = length * Mlength/stem;
            //}
            
            if(state.Ex > 0.0){
                EgoX = Math.abs(Math.cos(angle))*25.0;
                EFX = Math.abs(Math.cos(angle))*Elength;
            }
            else{
                EgoX = -Math.abs(Math.cos(angle))*25.0;
                EFX = -Math.abs(Math.cos(angle))*Elength;
            }
            if(state.Ey > 0.0){
                EgoY = Math.abs(Math.sin(angle))*25.0;
                EFY = Math.abs(Math.sin(angle))*Elength;
            }
            else{
                EgoY = -Math.abs(Math.sin(angle))*25.0;
                EFY = -Math.abs(Math.sin(angle))*Elength;
            }
            
            if(state.MFx > 0.0){
                BFX = -Math.abs(Math.cos(angleB))*Mlength;
            }
            else{
                BFX = Math.abs(Math.cos(angleB))*Mlength;
            }
            if(state.MFy > 0.0){
                BFY = -Math.abs(Math.sin(angleB))*Mlength;
            }
            else{
                BFY = Math.abs(Math.sin(angleB))*Mlength;
            }
            
            angle1 = angle + Math.PI/10;
            angle2 = angle - Math.PI/10;
            
            angleB1 = angleB + Math.PI/10;
            angleB2 = angleB - Math.PI/10;
            
            double x1=150.0, y1=150.0, x2=450.0, y2=150.0, 
                   x3=150.0, y3=450.0, x4=450.0, y4=450.0;
            
            
            drawLineThick(g,x1-EgoX,y1-EgoY,x1+EgoX,y1+EgoY,2,newgray);
            
            if(state.Ex == 0.0 && state.Ey == 0.0){}
            else{
                if(state.Ex >= 0.0 && state.Ey >= 0.0){
                    MaestroG.subscripter("E","","",g,16,(int)(x1+10),(int)(y1-10));
                }
                else if(state.Ex >= 0.0 && state.Ey <= 0.0){
                    MaestroG.subscripter("E","","",g,16,(int)(x1+10),(int)(y1+20));
                }
                else if(state.Ex <= 0.0 && state.Ey >= 0.0){
                    MaestroG.subscripter("E","","",g,16,(int)(x1-20),(int)(y1-10));
                }
                else if(state.Ex <= 0.0 && state.Ey <= 0.0){
                    MaestroG.subscripter("E","","",g,16,(int)(x1-20),(int)(y1+20));
                }
            }

            if(state.Ex >= 0.0){
                g.setColor(newgray);        
                drawLineThick(g,x1+EgoX,y1+EgoY,x1+EgoX-length*Math.cos(angle1),y1+EgoY-length*Math.sin(angle1),2,newgray);
                drawLineThick(g,x1+EgoX,y1+EgoY,x1+EgoX-length*Math.cos(angle2),y1+EgoY-length*Math.sin(angle2),2,newgray);
            }
            else{
                drawLineThick(g,x1+EgoX,y1+EgoY,x1+EgoX+length*Math.cos(angle1),y1+EgoY+length*Math.sin(angle1),2,newgray);
                drawLineThick(g,x1+EgoX,y1+EgoY,x1+EgoX+length*Math.cos(angle2),y1+EgoY+length*Math.sin(angle2),2,newgray);
            }

            drawLineThick(g,x2-EgoX,y2-EgoY,x2+EgoX,y2+EgoY,2,newgray);
            if(state.Ex >= 0.0){
                drawLineThick(g,x2+EgoX,y2+EgoY,x2+EgoX-length*Math.cos(angle1),y2+EgoY-length*Math.sin(angle1),2,newgray);
                drawLineThick(g,x2+EgoX,y2+EgoY,x2+EgoX-length*Math.cos(angle2),y2+EgoY-length*Math.sin(angle2),2,newgray);
            }
            else{
                drawLineThick(g,x2+EgoX,y2+EgoY,x2+EgoX+length*Math.cos(angle1),y2+EgoY+length*Math.sin(angle1),2,newgray);
                drawLineThick(g,x2+EgoX,y2+EgoY,x2+EgoX+length*Math.cos(angle2),y2+EgoY+length*Math.sin(angle2),2,newgray);
            }

            drawLineThick(g,x3-EgoX,y3-EgoY,x3+EgoX,y3+EgoY,2,newgray);
            if(state.Ex >= 0.0){
                drawLineThick(g,x3+EgoX,y3+EgoY,x3+EgoX-length*Math.cos(angle1),y3+EgoY-length*Math.sin(angle1),2,newgray);
                drawLineThick(g,x3+EgoX,y3+EgoY,x3+EgoX-length*Math.cos(angle2),y3+EgoY-length*Math.sin(angle2),2,newgray);
            }
            else{
                drawLineThick(g,x3+EgoX,y3+EgoY,x3+EgoX+length*Math.cos(angle1),y3+EgoY+length*Math.sin(angle1),2,newgray);
                drawLineThick(g,x3+EgoX,y3+EgoY,x3+EgoX+length*Math.cos(angle2),y3+EgoY+length*Math.sin(angle2),2,newgray);
            }

            drawLineThick(g,x4-EgoX,y4-EgoY,x4+EgoX,y4+EgoY,2,newgray);
            if(state.Ex >= 0.0){
                drawLineThick(g,x4+EgoX,y4+EgoY,x4+EgoX-length*Math.cos(angle1),y4+EgoY-length*Math.sin(angle1),2,newgray);
                drawLineThick(g,x4+EgoX,y4+EgoY,x4+EgoX-length*Math.cos(angle2),y4+EgoY-length*Math.sin(angle2),2,newgray);
            }
            else{
                drawLineThick(g,x4+EgoX,y4+EgoY,x4+EgoX+length*Math.cos(angle1),y4+EgoY+length*Math.sin(angle1),2,newgray);
                drawLineThick(g,x4+EgoX,y4+EgoY,x4+EgoX+length*Math.cos(angle2),y4+EgoY+length*Math.sin(angle2),2,newgray);
            }
            
            drawStart(g);
            
            // draw field vectors at particle
            if(state.particle == 1){
                drawLineThick(g,xxpos-EFX,yypos-EFY,xxpos,yypos,2,Color.red);
                if(state.Ex >= 0.0){
                    drawLineThick(g,xxpos-EFX,yypos-EFY,xxpos-EFX+lengthE*Math.cos(angle1),yypos-EFY+lengthE*Math.sin(angle1),2,Color.red);
                    drawLineThick(g,xxpos-EFX,yypos-EFY,xxpos-EFX+lengthE*Math.cos(angle2),yypos-EFY+lengthE*Math.sin(angle2),2,Color.red);
                }
                else{
                    drawLineThick(g,xxpos-EFX,yypos-EFY,xxpos-EFX-lengthE*Math.cos(angle1),yypos-EFY-lengthE*Math.sin(angle1),2,Color.red);
                    drawLineThick(g,xxpos-EFX,yypos-EFY,xxpos-EFX-lengthE*Math.cos(angle2),yypos-EFY-lengthE*Math.sin(angle2),2,Color.red);
                }
                
                drawLineThick(g,xxpos-BFX,yypos-BFY,xxpos,yypos,2,Color.blue);
                if(state.MFx > 0.0){
                    drawLineThick(g,xxpos-BFX,yypos-BFY,xxpos-BFX-lengthM*Math.cos(angleB1),yypos-BFY-lengthM*Math.sin(angleB1),2,Color.blue);
                    drawLineThick(g,xxpos-BFX,yypos-BFY,xxpos-BFX-lengthM*Math.cos(angleB2),yypos-BFY-lengthM*Math.sin(angleB2),2,Color.blue);
                }
                else if(state.MFx < 0.0){
                    drawLineThick(g,xxpos-BFX,yypos-BFY,xxpos-BFX+lengthM*Math.cos(angleB1),yypos-BFY+lengthM*Math.sin(angleB1),2,Color.blue);
                    drawLineThick(g,xxpos-BFX,yypos-BFY,xxpos-BFX+lengthM*Math.cos(angleB2),yypos-BFY+lengthM*Math.sin(angleB2),2,Color.blue);
                } 
                else if(state.MFx == 0.0 && state.MFy > 0.0 && state.vx > 0.0){
                    //System.out.println("CASE A"+state.MFy);
                    drawLineThick(g,xxpos-BFX,yypos-BFY,xxpos-BFX+lengthM*Math.cos(angleB1),yypos-BFY+lengthM*Math.sin(angleB1),2,Color.blue);
                    drawLineThick(g,xxpos-BFX,yypos-BFY,xxpos-BFX+lengthM*Math.cos(angleB2),yypos-BFY+lengthM*Math.sin(angleB2),2,Color.blue);
                }
                else if(state.MFx == 0.0 && state.MFy > 0.0 && state.vx < 0.0){
                    //System.out.println("CASE A"+state.MFy);
                    drawLineThick(g,xxpos-BFX,yypos-BFY,xxpos-BFX-lengthM*Math.cos(angleB1),yypos-BFY-lengthM*Math.sin(angleB1),2,Color.blue);
                    drawLineThick(g,xxpos-BFX,yypos-BFY,xxpos-BFX-lengthM*Math.cos(angleB2),yypos-BFY-lengthM*Math.sin(angleB2),2,Color.blue);
                }
                else if(state.MFx == 0.0 && state.MFy < 0.0 && state.vx < 0.0){
                    //System.out.println("CASE A"+state.MFy);
                    drawLineThick(g,xxpos-BFX,yypos-BFY,xxpos-BFX+lengthM*Math.cos(angleB1),yypos-BFY+lengthM*Math.sin(angleB1),2,Color.blue);
                    drawLineThick(g,xxpos-BFX,yypos-BFY,xxpos-BFX+lengthM*Math.cos(angleB2),yypos-BFY+lengthM*Math.sin(angleB2),2,Color.blue);
                }
                else if(state.MFx == 0.0 && state.MFy < 0.0 && state.vx > 0.0){
                    //System.out.println("CASE A"+state.MFy);
                    drawLineThick(g,xxpos-BFX,yypos-BFY,xxpos-BFX-lengthM*Math.cos(angleB1),yypos-BFY-lengthM*Math.sin(angleB1),2,Color.blue);
                    drawLineThick(g,xxpos-BFX,yypos-BFY,xxpos-BFX-lengthM*Math.cos(angleB2),yypos-BFY-lengthM*Math.sin(angleB2),2,Color.blue);
                }   
            }
            else if(state.particle == 2){
                drawLineThick(g,xxpos,yypos,xxpos+EFX,yypos+EFY,2,Color.red);
                if(state.Ex >= 0.0){
                    drawLineThick(g,xxpos+EFX,yypos+EFY,xxpos+EFX-lengthE*Math.cos(angle1),yypos+EFY-lengthE*Math.sin(angle1),2,Color.red);
                    drawLineThick(g,xxpos+EFX,yypos+EFY,xxpos+EFX-lengthE*Math.cos(angle2),yypos+EFY-lengthE*Math.sin(angle2),2,Color.red);
                }
                else{
                    drawLineThick(g,xxpos+EFX,yypos+EFY,xxpos+EFX+lengthE*Math.cos(angle1),yypos+EFY+lengthE*Math.sin(angle1),2,Color.red);
                    drawLineThick(g,xxpos+EFX,yypos+EFY,xxpos+EFX+lengthE*Math.cos(angle2),yypos+EFY+lengthE*Math.sin(angle2),2,Color.red);
                }
                
                //drawLineThick(g,xxpos+BFX,yypos+BFY,xxpos,yypos,2,Color.blue);
                drawLineThick(g,xxpos-BFX,yypos-BFY,xxpos,yypos,2,Color.blue);
                if(state.MFx > 0.0){
                    drawLineThick(g,xxpos-BFX,yypos-BFY,xxpos-BFX-lengthM*Math.cos(angleB1),yypos-BFY-lengthM*Math.sin(angleB1),2,Color.blue);
                    drawLineThick(g,xxpos-BFX,yypos-BFY,xxpos-BFX-lengthM*Math.cos(angleB2),yypos-BFY-lengthM*Math.sin(angleB2),2,Color.blue);
                }
                else{
                    drawLineThick(g,xxpos-BFX,yypos-BFY,xxpos-BFX+lengthM*Math.cos(angleB1),yypos-BFY+lengthM*Math.sin(angleB1),2,Color.blue);
                    drawLineThick(g,xxpos-BFX,yypos-BFY,xxpos-BFX+lengthM*Math.cos(angleB2),yypos-BFY+lengthM*Math.sin(angleB2),2,Color.blue);
                }           
            }
            else if(state.particle == 3){}
            
        }
        
        //frame
        g.setColor(Color.black);
	g.draw3DRect(0,0,getSize().width-1,getSize().height-1,false);
	
    }
    
    private synchronized void drawPoints(Graphics g, int tipo){
        Graphics2D g2d = (Graphics2D)g;
        switch(tipo){
	    case 1:
		//if(IsTraceOn){
                    //g.setColor(Color.red);
                    //MaestroG.fillCircle(xxpos_0,yypos_0,9,g);
                    //g.setColor(Color.pink.brighter());
                    //MaestroG.fillCircle(xxpos_0-1,yypos_0-1,2,g);
                    
                    g.setColor(Color.black);
                    MaestroG.fillCircle(xxpos,yypos,9,g);
                    g.setColor(Color.white);
                    MaestroG.fillCircle(xxpos-1,yypos-1,2,g);
		//}
		//else{
                  //  g.setColor(Color.red);
                  //  MaestroG.fillCircle(xxpos_0,yypos_0,9,g);
                  //  g.setColor(Color.pink);
                  //  MaestroG.fillCircle(xxpos_0-1,yypos_0-1,2,g);
                  //  
                  //  g.setColor(Color.green);
		  //  MaestroG.fillCircle(xxpos,yypos,9,g);
                  //  g.setColor(Color.white);
                  //  MaestroG.fillCircle(xxpos-1,yypos-1,2,g);
		//}
		break;
	    case 2:
                g.setColor(bgcolor);
		MaestroG.fillCircle(xxpos,yypos,9,g);
                
                break;
	}
    }
    
    private synchronized void drawStart(Graphics g){
        Graphics2D g2d = (Graphics2D)g;
        g.setColor(Color.red);
        MaestroG.fillCircle(xxpos_0,yypos_0,9,g);
        g.setColor(Color.pink.brighter());
        MaestroG.fillCircle(xxpos_0-1,yypos_0-1,2,g);
    }
    
    private 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);
    }

    
    public synchronized void reset(){
	IsTraceOn = true;//false;
	IsCleanUpOn = false;
    }
    
    public synchronized void cleanUp(){
	IsCleanUpOn=true;
    }
    
    public synchronized void setTrace(boolean IsTraceOn){
	this.IsTraceOn = IsTraceOn;
    }
    
    public synchronized void setField(boolean IsFieldOn){
	this.IsFieldOn = IsFieldOn;
    }
    
    public synchronized void setDynamics(boolean IsDynamic){
	this.IsDynamic = IsDynamic;
    }

    
    public void update(Graphics g){
	
        if(!IsDynamic){
	    paint(g);
	    return;
	}
	if(IsDynamic && IsTraceOn){g.clipRect(LeftMargin+1,TopMargin+1,WIDTH-1,HEIGHT-1);}
	if(IsCleanUpOn){
	    g.clearRect(0,0,getSize().width,getSize().height);
	    IsCleanUpOn = false;
	    drawAxis(g);
	}
        if(!IsTraceOn){
	    drawPoints(g,2);//This cleans the previous graph
	}
        //drawStart(g);
	drawPoints(g,1);//This draws the new graph
	drawAxis(g);
    }
    
    //private void clean_memory(){}
    
    public synchronized void setMargins(int LeftMargin, int RightMargin, int TopMargin, int BottomMargin){
	this.LeftMargin = LeftMargin;
	this.RightMargin = RightMargin;
	this.TopMargin = TopMargin;
	this.BottomMargin = BottomMargin;
    }
    
    public synchronized void setPositions(double xpos, double ypos, double xpos_old, double ypos_old){
        this.xpos = xpos;
        this.ypos = ypos;
        this.xpos_old = xpos_old;
        this.ypos_old = ypos_old;
    }
    
    public synchronized void setNewBoundaries(double xnewmax, double ynewmax, double xnewmin, double ynewmin){
        this.xnewmax = xnewmax;
        this.ynewmax = ynewmax;
        this.xnewmin = xnewmin;
        this.ynewmin = ynewmin;
    }
    
    public synchronized void setStop(boolean IsStop){
        this.IsStop = IsStop;
    }
    
    public synchronized void setStart(boolean IsStart){
        this.IsStart = IsStart;
    }
    
    public synchronized void setReset(boolean IsReset){
        this.IsReset = IsReset;
    }
}
