import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.geom.*;
 
public class DrawCurrent2 extends Canvas{
	private static final Color bgcolor = new Color(255,255,255);
                
	private static final Color acolor = new Color(152,152,152);
	private static final Color ccolor = new Color(230,230,230);
	private Image im;
        public double previous;
        public int imax, is_new;
        
	private Image im_palette;
	private MemoryImageSource mis;
	private int rgbPixels[];
	private int rgb_palette_Pixels[];
	private int new_width;
	private Color colorArray[]; private Color colorArray2[];
	private static final int width=206;
	private static final int height=206;
	private static final int palette_width=20, palette_height=500;
	private static final int LeftMargin=10, RightMargin=20, TopMargin=10, BottomMargin=10;
	private static final int LeftImageIndent=5, LeftPaletteIndent=670;
        
        private int Nx = 200;
        private int Ny = 200;
        private int Nratio = 1; // Since Nt = 6000, Nratio can be 10, 15, 20, 24
        public double previous_charge;
        private double w[][];
        
        private int go = 0;
        private int Npoints;
        private double ymax, ymin, xmax, xmin, ypmax, ypmin;
        private double[] x, y, v;
        private int[] xx, yy, yen;
        
	private Trans_State state;
	private boolean DirtyFlag;
	
        public DrawCurrent2(Trans_State state){
		super();
		this.state = state;
                setBackground(bgcolor);
		new_width = (int)(width);
		rgbPixels = new int[(width+1) * (height+1)];
		rgb_palette_Pixels = new int[palette_width * palette_height];
		colorArray = new Color[1024];
                colorArray2 = new Color[1024];
                previous_charge = state.Dipole_Charge;
		DirtyFlag = true;
                
                xmin = 0.0;
                ymax = 1.0;
                ymin = -1.0;
                ypmax = 1.0;
                ypmin = 0.0;
                
                //Npoints = 251;
                Npoints = state.Nt/Nratio + 1;
                
                try{
                    x = new double[Npoints];
                    y = new double[Npoints];
                    xx = new int[Npoints];
                    yy = new int[Npoints];
                    yen = new int[Npoints];
                }
                catch(Exception e){e.printStackTrace();}
                for(int i = 0; i < x.length; i++){
                    x[i] = (double)i;
                    y[i] = state.pulse[i*Nratio];
                }

                w = new double[Nx+1][Ny+1];
                
                
                imax = state.palettereference;
                
                if(state.IsThreshold){
                
                    for(int i = 0; i < 247; i++) {
                       colorArray[i] = new Color(0,0,255);
                    }

                    for(int i = 247; i < 503; i++) {
                       colorArray[i] = new Color((i-247)/16*16,(i-247)/16*16,255);
                    }

                    for(int i = 503; i < 520; i++) {
                       colorArray[i] = new Color(255,255,255);
                    }

                    // red
                    for(int i = 520; i < 778; i++) {
                        colorArray[i] = new Color(255,240-(((i-520)/16)*16),240-(((i-520)/16)*16));
                    }

                    for(int i = 778; i < 1025; i++) {
                       colorArray[i] = new Color(255,0,0);
                    }

                    //for(int s=0; s<1024;s++){
                        //System.out.println(s+"   "+colorArray[s]);
                    //}
                }
                else{
                
                    // blue
                    for(int i = 0; i < 256; i++) {
                       colorArray[i] = new Color(0,0,255);
                    }

                    for(int i = 256; i < 512; i++) {
                       colorArray[i] = new Color((i-256),(i-256),255);
                    }

                    // red
                    for(int i = 512; i < 768; i++) {
                        colorArray[i] = new Color(255,255-((i-512)),255-((i-512)));
                    }

                    for(int i = 768; i < 1024; i++) {
                       colorArray[i] = new Color(255,0,0);
                    }
                }
                //updatePixels();
		//mis = new MemoryImageSource(new_width,height,rgbPixels,0,new_width);
		//mis.setAnimated(true);
		//mis.setFullBufferUpdates(false);
		//im = createImage(mis);
	}
        
        public void redopalette(){
                if(state.IsThreshold){
                 if(!state.IsCoarser){   
                    //8 x 8 palette
                     for(int ii = 0; ii < 251; ii++) {
                       colorArray[ii] = new Color(0,0,255);
                    }

                    for(int ii = 251; ii < 507; ii++) {
                       colorArray[ii] = new Color((ii-251)/8*8,(ii-251)/8*8,255);
                       //System.out.println(ii+"   "+colorArray2[ii]);
                    }

                    for(int ii = 507; ii < 516; ii++) {
                       colorArray[ii] = new Color(255,255,255);
                    }

                    // red
                    for(int ii = 516; ii < 772; ii++) {
                        colorArray[ii] = new Color(255,251-(((ii-516)/8)*8),251-(((ii-516)/8)*8));
                    }

                    for(int ii = 772; ii < 1024; ii++) {
                       colorArray[ii] = new Color(255,0,0);
                    }
                 }
                 else{
                 
                    for(int i = 0; i < 247; i++) {
                       colorArray[i] = new Color(0,0,255);
                    }

                    for(int i = 247; i < 503; i++) {
                       colorArray[i] = new Color((i-247)/16*16,(i-247)/16*16,255);
                    }

                    for(int i = 503; i < 520; i++) {
                       colorArray[i] = new Color(255,255,255);
                    }

                    // red
                    for(int i = 520; i < 776; i++) {
                        colorArray[i] = new Color(255,247-(((i-520)/16)*16),247-(((i-520)/16)*16));
                    }

                    for(int i = 776; i < 1024; i++) {
                       colorArray[i] = new Color(255,0,0);
                    }
                 }
                    
                }
                else{
                
                    // blue
                    for(int i = 0; i < 256; i++) {
                       colorArray[i] = new Color(0,0,255);
                    }

                    for(int i = 256; i < 512; i++) {
                       colorArray[i] = new Color((i-256),(i-256),255);
                    }

                    // red
                    for(int i = 512; i < 768; i++) {
                        colorArray[i] = new Color(255,255-((i-512)),255-((i-512)));
                    }

                    for(int i = 768; i < 1024; i++) {
                       colorArray[i] = new Color(255,0,0);
                    }
                }
        }
	
	public void paint(Graphics g){
	    updatePixels(g);
	}   
	
	private void updatePixels(Graphics g){
                Graphics2D g2d = (Graphics2D)g;
                
                Color charge_colorA = new Color(255,255,255);
                Color charge_colorB = new Color(255,255,255);
                
                double distance = (double)Nx* 4.0/30.0;
                
                double distance_current = - distance * state.Dipole_Current;
                double centerx = (double)Nx/2;
                double centery = (double)Nx/2;
                double charge_radius = Nx*25.0/300.0;
                double charge_center_A = centery - distance - charge_radius - 7;
                double charge_center_B = centery + distance + charge_radius + 7;
                
                // draw legends
                g.setColor(Color.black);
                g.drawLine((int)centerx*13/10,(int)charge_center_A,(int)centerx*15/10,(int)charge_center_A);
                g.drawLine((int)centerx*13/10,(int)charge_center_B,(int)centerx*15/10,(int)charge_center_B);
                g.drawLine((int)centerx*14/10,(int)charge_center_A,(int)centerx*14/10,(int)charge_center_B);
            
                MaestroG.drawArrow((int)centerx*14/10,(int)charge_center_A+10,5,g);
                MaestroG.drawArrow((int)centerx*14/10,(int)charge_center_B-10,6,g);
                
                g.setFont(new Font("SanSerif",Font.ITALIC,22));
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                g.setColor(Color.gray);
                g.drawString("\u0394 z",(int)centerx*15/10,(int)(charge_center_A+charge_center_B)/2);
                g.setFont(new Font("Serif",Font.ITALIC,22));
                
                g.drawString("I ( t )",(int)centerx*60/100,(int)(charge_center_A+charge_center_B)/2);
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
                
                // draw charges
                if(state.Dipole_Charge >= 0.0){
                     charge_colorA = new Color(255,255*(100-(int)(state.Dipole_Charge*100.0))/100,255*(100-(int)(state.Dipole_Charge*100.0))/100);
                     charge_colorB = new Color(255*(100-(int)(state.Dipole_Charge*100.0))/100,255*(100-(int)(state.Dipole_Charge*100.0))/100,255);
                }
                if(state.Dipole_Charge < 0.0){
                     charge_colorB = new Color(255,255*(100+(int)(state.Dipole_Charge*100.0))/100,255*(100+(int)(state.Dipole_Charge*100.0))/100);
                     charge_colorA = new Color(255*(100+(int)(state.Dipole_Charge*100.0))/100,255*(100+(int)(state.Dipole_Charge*100.0))/100,255);
                }
                     
                    MaestroG.fillCircleThick(g, centerx, charge_center_A, charge_radius, 2, charge_colorA);
                    MaestroG.fillCircleThick(g, centerx, charge_center_B, charge_radius, 2, charge_colorB);
                    
                    MaestroG.drawCircleThick(g, centerx, charge_center_A, charge_radius, 2, Color.gray);
                    MaestroG.drawCircleThick(g, centerx, charge_center_B, charge_radius, 2, Color.gray);
                    
                    // draw + and -
                    int xshift = 80;
                    
                    if(state.Dipole_Charge > 0){
                        if(go == 0){
                            MaestroG.drawLineThick(g,centerx-10-xshift,charge_center_A,centerx+10-xshift, charge_center_A, 8, Color.white);
                            MaestroG.drawLineThick(g,centerx-xshift,charge_center_A-10,centerx-xshift, charge_center_A+10, 8, Color.white);
                            MaestroG.drawLineThick(g,centerx-10-xshift,charge_center_B,centerx+10-xshift, charge_center_B, 8, Color.white);
                            MaestroG.drawLineThick(g,centerx-xshift,charge_center_B-10,centerx-xshift, charge_center_B+10, 8, Color.white);
                        }
                        MaestroG.drawLineThick(g,centerx-10-xshift,charge_center_A,centerx+10-xshift, charge_center_A, 5, Color.black);
                        MaestroG.drawLineThick(g,centerx-xshift,charge_center_A-10,centerx-xshift, charge_center_A+10, 5, Color.black);
                        MaestroG.drawLineThick(g,centerx-10-xshift,charge_center_B,centerx+10-xshift, charge_center_B, 5, Color.black);
                        go = 1;
                    }
                    else if(state.Dipole_Charge == 0){
                        
                            MaestroG.drawLineThick(g,centerx-10-xshift,charge_center_A,centerx+10-xshift, charge_center_A, 8, Color.white);
                            MaestroG.drawLineThick(g,centerx-xshift,charge_center_A-10,centerx-xshift, charge_center_A+10, 8, Color.white);
                            MaestroG.drawLineThick(g,centerx-10-xshift,charge_center_B,centerx+10-xshift, charge_center_B, 8, Color.white);
                            MaestroG.drawLineThick(g,centerx-xshift,charge_center_B-10,centerx-xshift, charge_center_B+10, 8, Color.white);
                        //MaestroG.drawLineThick(g,centerx-10-xshift,charge_center_A,centerx+10-xshift, charge_center_A, 5, Color.black);
                        //MaestroG.drawLineThick(g,centerx-xshift,charge_center_A-10,centerx-xshift, charge_center_A+10, 5, Color.black);
                        //MaestroG.drawLineThick(g,centerx-10-xshift,charge_center_B,centerx+10-xshift, charge_center_B, 5, Color.black);
                        
                    }
                    else if(state.Dipole_Charge < 0){
                        if(go == 1){
                            MaestroG.drawLineThick(g,centerx-10-xshift,charge_center_A,centerx+10-xshift, charge_center_A, 8, Color.white);
                            MaestroG.drawLineThick(g,centerx-xshift,charge_center_A-10,centerx-xshift, charge_center_A+10, 8, Color.white);
                            MaestroG.drawLineThick(g,centerx-10-xshift,charge_center_B,centerx+10-xshift, charge_center_B, 8, Color.white);
                            MaestroG.drawLineThick(g,centerx-xshift,charge_center_B-10,centerx-xshift, charge_center_B+10, 8, Color.white);
                        }
                        MaestroG.drawLineThick(g,centerx-10-xshift,charge_center_B,centerx+10-xshift, charge_center_B, 5, Color.black);
                        MaestroG.drawLineThick(g,centerx-xshift,charge_center_B-10,centerx-xshift, charge_center_B+10, 5, Color.black);
                        MaestroG.drawLineThick(g,centerx-10-xshift,charge_center_A,centerx+10-xshift, charge_center_A, 5, Color.black);
                        go = 0;
                    }
                    
                    previous_charge = state.Dipole_Charge;
                    
                g.setColor(Color.white);
                // draw current                
                g.fillRect((int)centerx-10, (int)centery - (int)distance -5, 20, 2*(int)distance+10);
                
                if(state.Dipole_Current > 0.0){
                     charge_colorA = new Color(255,255*(1-(int)state.Dipole_Charge),255*(1-(int)state.Dipole_Charge));
                     charge_colorB = new Color(255*(1-(int)state.Dipole_Charge),255*(1-(int)state.Dipole_Charge),255);
                    
                     
                    if(Math.abs(state.Dipole_Current) < 0.25){
                        MaestroG.drawLineThick(g,centerx,centery-distance_current,centerx, centery+distance_current, 3, Color.red);
                        if(Math.abs(state.Dipole_Current) > 0.05){
                            MaestroG.drawLineThick(g,centerx,centery+distance_current,centerx-2, centery+distance_current+4, 3, Color.red);
                            MaestroG.drawLineThick(g,centerx,centery+distance_current,centerx+2, centery+distance_current+4, 3, Color.red);
                        }
                    }
                    else{
                        MaestroG.drawLineThick(g,centerx,centery-distance_current,centerx, centery+distance_current, 5, Color.red);
                        MaestroG.drawLineThick(g,centerx,centery+distance_current,centerx-4, centery+distance_current+8, 5, Color.red);
                        MaestroG.drawLineThick(g,centerx,centery+distance_current,centerx+4, centery+distance_current+8, 5, Color.red);
                    }
                }
                else{
                    if(Math.abs(state.Dipole_Current) < 0.25){
                        MaestroG.drawLineThick(g,centerx,centery-distance_current,centerx, centery+distance_current, 3, Color.blue);
                        if(Math.abs(state.Dipole_Current) > 0.05){
                            MaestroG.drawLineThick(g,centerx,centery+distance_current,centerx-2, centery+distance_current-4, 3, Color.blue);
                            MaestroG.drawLineThick(g,centerx,centery+distance_current,centerx+2, centery+distance_current-4, 3, Color.blue);
                        }
                    }
                    else{
                        MaestroG.drawLineThick(g,centerx,centery-distance_current,centerx, centery+distance_current, 5, Color.blue);
                        MaestroG.drawLineThick(g,centerx,centery+distance_current,centerx-4, centery+distance_current-8, 5, Color.blue);
                        MaestroG.drawLineThick(g,centerx,centery+distance_current,centerx+4, centery+distance_current-8, 5, Color.blue);
                    
                    }
                }
                
                previous = - distance*state.Dipole_Current;
            
                //myarray = null;
	    mis = new MemoryImageSource(new_width,height,rgbPixels,0,new_width);
	    mis.setAnimated(true);
	    mis.setFullBufferUpdates(false);
            im = createImage(mis);
            g.drawImage(im,LeftImageIndent,(getSize().height-height)/2,this);
	}
	
	private void drawImage(Graphics g){
	   g.drawImage(im,LeftImageIndent,(getSize().height-height)/2,this);
	}
	
	
	
	private void drawLabels(Graphics g){
	    g.setFont(new Font("SanSerif",Font.PLAIN,14));
	    FontMetrics fm = g.getFontMetrics();
	    g.setColor(Color.black);
	    g.drawString("",(getSize().width-fm.stringWidth(""))/2,2*TopMargin);
	}
	
	private void drawLabels2(Graphics g){
	    g.setFont(new Font("SanSerif",Font.BOLD,12));
	    FontMetrics fm = g.getFontMetrics();
	    g.clearRect(100,getSize().height-2*BottomMargin,getSize().width-200,2*BottomMargin-3);
	}
	
	private void drawCanvas(Graphics g){
	    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);
	}	
	
	private void drawAxis(Graphics g){
	    g.setColor(Color.black);
            //horizontal axis
	    g.drawLine(Nx+(Nx/2),Ny+(Ny/2),2*Nx,Ny+(Ny/2));
	}
	
	public void setDirtyFlag(boolean DirtyFlag){
	    this.DirtyFlag = DirtyFlag;
	}
	
	public void setWidth(double ratio){
	    this.new_width=(int)(width/ratio);
	    this.rgbPixels=new int[(int)(width/ratio*height)];
	}
	
	public void update(Graphics g){
		updatePixels(g);
	}
		
}	

