import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
 
public class Draw2DCanvas extends Canvas{
	//private static final Color bgcolor = new Color(216,216,191);
	//private static final Color bgcolor = new Color(216,230,230);
        private static final Color bgcolor = new Color(0,0,0);
                
	private static final Color acolor = new Color(152,152,152);
	private static final Color ccolor = new Color(230,230,230);
	private Image im;
        
        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=606;
	private static final int height=606;
	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 = 300;
        private int Ny = 300;
        private int Nratio = 1; // Since Nt = 6000, Nratio can be 10, 15, 20, 24
        
        private double w[][];
        
        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 Draw2DCanvas(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];
                
		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];
                
                //Initialize the color palette
                
                /* old code
                for(int i = 0; i < 127; i++) {
		    colorArray[i] = new Color(2*i,2*i,255);
		}
		
		for(int i = 127; i < 256; i++) {
		    colorArray[i] = new Color(255,255-(i-127),255-(i-127));
		}
                */
		
                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);
                    }
                 }
                    /*
                    for(int i = 0; i < 246; i++) {
                       colorArray[i] = new Color(0,0,255);
                    }

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

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

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

                    for(int i = 778; i < 1024; 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);
                    }
                }
        }
	
	public void paint(Graphics g){
	    //drawImage(g);
	    updatePixels(g);
	    //drawPalette(g);
	    //drawLabels(g);
	    //drawLabels2(g);
	    //drawAxis(g);
            
	}   
	
	private void updatePixels(Graphics g){
	    int i=0, j=0, map=0, istar = 0, jstar = 0;
	    double x, y, min, max;
	    min =  0.0; 
	    max =  1.0e-20;
	    double myarray[][] = new double[width+1][height+1];
            int myslit[][] = new int[width+1][height+1];
            
            int Ny2 = Ny+6;
            int Nx2 = Nx+6;
            
            min = -300.0;
            max = 300.0;
            for(i = 1; i < Nx+1; i++){
		for(j = 1; j < Ny+1; j++){
                    
                    myarray[i][j] = state.Ey[i][j];
		    
                    if(myarray[i][j] > max){myarray[i][j]=max;}
                    if(myarray[i][j] < min){myarray[i][j]=min;}
		}
	    }
            
            for(i = 1; i < Nx+1; i++){
		for(j = 1; j < Ny+1; j++){
                    
                    myarray[i][j+Ny2] = state.Ex[i][j];
		    
                    if(myarray[i][j+Ny2] > max){myarray[i][j+Ny2]=max;}
                    if(myarray[i][j+Ny2] < min){myarray[i][j+Ny2]=min;}
		}
	    }
            
            for(i = 1; i < Nx+1; i++){
		for(j = 1; j < Ny+1; j++){
                    
                    myarray[i+Nx2][j] = state.Er[i][j];
		    
                    if(myarray[i+Nx2][j] > max){myarray[i+Nx2][j]=max;}
                    if(myarray[i+Nx2][j] < min){myarray[i+Nx2][j]=min;}
		}
	    }
            
            for(i = 1; i < Nx+1; i++){
		for(j = 1; j < Ny+1; j++){
                    
                    myarray[i+Nx2][j+Ny2] = state.Ey[i][j] - state.Ex[i][j];
		    
                    if(myarray[i+Nx2][j+Ny2] > max){myarray[i+Nx2][j+Ny2]=max;}
                    if(myarray[i+Nx2][j+Ny2] < min){myarray[i+Nx2][j+Ny2]=min;}
		}
	    }
            
            
	    for(i = 0; i < width+1; i++){
		for(j = 0; j < height+1; j++){ // actual values
		  {     
                        map = (int)MaestroA.mapper(myarray[i][j],1023.0,0.0,max,min);
                        rgbPixels[j*new_width+i] = colorArray[map].getRGB();
                  }
		}
	    }
            
            //Force color at dipole location point
            //black
            rgbPixels[Ny/2*new_width+Nx/2] = new Color(255,255,255).getRGB();
            rgbPixels[(3*Ny/2+6)*new_width+(3*Nx/2+6)] = new Color(255,255,255).getRGB();
            rgbPixels[(3*Ny/2+6)*new_width+(Nx/2)] = new Color(255,255,255).getRGB();
            rgbPixels[(Ny/2)*new_width+(3*Nx/2+6)] = new Color(255,255,255).getRGB();

            for(i = 0; i < width+1; i++){
		for(j = Ny+1; j < Ny2+1; j++){ 
		  {     
                        rgbPixels[j*new_width+i] = new Color(0,0,0).getRGB();
                  }
		}
	    }
            
            for(i = Nx+1; i < Nx2+1; i++){
		for(j = 0; j < height+1; j++){ 
		  {     
                        rgbPixels[j*new_width+i] = new Color(0,0,0).getRGB();
                  }
		}
	    }
            
            //System.out.println(min+"   "+max);
	    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 drawPalette(Graphics g){
	    int i, j, map, imax;
	    FontMetrics fm = g.getFontMetrics();
	    imax = state.palettereference;
                /*
                for(int ii = 0; ii < imax; ii++) {
		    colorArray2[ii] = new Color((2550000/imax*ii)/10000,(2550000/imax*ii)/10000,255);
		}
		
		for(int ii = imax; ii < 256; ii++) {
		    colorArray2[ii] = new Color(255,255-(ii-imax),255-(ii-imax));
		}
                */
            
                for(int ii = 0; ii < 256; ii++) {
		   colorArray2[ii] = new Color(0,0,255);
		}
                
                for(int ii = 256; ii < 512; ii++) {
		   colorArray2[ii] = new Color(ii-256,ii-256,255);
		}
		
		for(int ii = 512; ii < 768; ii++) {
		    colorArray2[ii] = new Color(255,255-(ii-512),255-(ii-512));
		}
                
                for(int ii = 768; ii < 1024; ii++) {
		   colorArray2[ii] = new Color(255,0,0);
		}
            
                //colorArray2[126] = new Color(200,200,200);
                //colorArray2[128] = new Color(200,200,200);
                
                /*
                colorArray2[7] = new Color(0,0,255);
                colorArray2[23] = new Color(0,0,255);
                colorArray2[39] = new Color(0,0,255);
                colorArray2[55] = new Color(0,0,255);
                colorArray2[71] = new Color(0,0,255);
                colorArray2[87] = new Color(0,0,255);
                colorArray2[103] = new Color(0,0,255);
                colorArray2[119] = new Color(0,0,255);
                colorArray2[135] = new Color(255,0,0);
                colorArray2[151] = new Color(255,0,0);
                colorArray2[167] = new Color(255,0,0);
                colorArray2[183] = new Color(255,0,0);
                colorArray2[199] = new Color(255,0,0);
                colorArray2[215] = new Color(255,0,0);
                colorArray2[231] = new Color(255,0,0);
                colorArray2[247] = new Color(255,0,0);
                */
                
            for(i = 0; i < palette_width; i++){
		for(j = 0; j < palette_height; j++){
		    map = (palette_height-1-j)*1023/(palette_height-1);
                    
                    if(map < 0) { map = 0;}
		    if(map >1023) { map = 1023; }
                    rgb_palette_Pixels[j*palette_width+i] = colorArray2[map].getRGB();
		}
	    }
            int leftshift = 15;
	    im_palette = createImage(new MemoryImageSource(palette_width,palette_height,
				rgb_palette_Pixels,0,palette_width));
	    g.drawImage(im_palette,LeftPaletteIndent-leftshift,(getSize().height-height)/2,this);
	    
	    g.drawString("-max",LeftPaletteIndent+palette_width-27-leftshift,getSize().height-28*BottomMargin/10);
    	    g.drawString("max",LeftPaletteIndent+palette_width-22-leftshift,getSize().height/2-height/2-5);
	    g.drawRect(LeftPaletteIndent-1-leftshift,getSize().height/2-height/2-1,
			palette_width+1,1+palette_height);
	}
	
	private void drawLabels(Graphics g){
	    g.setFont(new Font("SanSerif",Font.PLAIN,14));
	    FontMetrics fm = g.getFontMetrics();
	    g.setColor(Color.black);
	    g.drawString("Poynting Vector Magnitude",(getSize().width-fm.stringWidth("Poynting Vector Magnitude"))/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));
	    
            
	    //Draw Arrows
	    //MaestroG.drawArrow(LeftImageIndent+new_width-10,15+(getSize().height+height)/2,7,g);
	    
	}
	
	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){
		//drawPalette(g);
                updatePixels(g);
		mis.newPixels(0,0,new_width,height);
		drawImage(g);

		//if(DirtyFlag){
		    //drawLabels2(g);
		    //drawLabels(g);
		    //drawAxis(g);
		    //DirtyFlag=false;
		//}
                //drawAxis(g);
               
	}
		
}	

