import java.awt.*;
//import java.awt.event.*;
import java.awt.image.*;

public class Draw2DCanvasB extends Canvas{
    private static final Color bgcolor = new Color(0,0,0);
    private Image im;
    public int imax;
    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 int rgbwidth;
    private int rgbheight; 
    private int palette_width, palette_height;
    private int LeftMargin, RightMargin, TopMargin, BottomMargin;
    private int LeftImageIndent, LeftPaletteIndent;
    private int Npoints;
    private Oblique_State state;
    
    public Draw2DCanvasB(Oblique_State state){
        super();
        this.state = state;
        
        // NOTE: The values are calculated in the state routine
        rgbwidth = state.width;
        rgbheight = state.height; 
        palette_width = state.s20;
        palette_height = state.s500;
        LeftMargin = state.s10; 
        RightMargin = state.s20;
        TopMargin = state.s10;
        BottomMargin = state.s10;
        LeftImageIndent = 1; 
        LeftPaletteIndent = state.s600+state.s70;
        
        setBackground(bgcolor);
        new_width = (int)(rgbwidth+1);
        rgbPixels = new int[(rgbwidth+1) * (rgbheight+1)];
        rgb_palette_Pixels = new int[palette_width * palette_height];
        colorArray = new Color[256];
        colorArray2 = new Color[256];

        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));
        }               
    }
        
    public void paint(Graphics g){
        //-----------------------------------------
        updatePixels(g);
        //-----------------------------------------
    }   

    private void updatePixels(Graphics g){
        int i=0, j=0, map=0, istar = 0, jstar = 0;
        double x, y, min, max;
        int iangle = 0;
        int jangle = 0;

        double myarray[][] = new double[rgbwidth+1][rgbheight+1];
        int myslit[][] = new int[rgbwidth+1][rgbheight+1];

        min = -(double)state.s300;
        max = (double)state.s300;
        int mid = rgbheight/2;
        int mid2 = rgbwidth/2;
        double totang = state.totalR_angle*Math.PI/180.0;

        if(state.Incident || state.Total){
            for(i = 0; i < rgbwidth+1; i++){
                for(j = 0; j < rgbheight+1; j++){
                    //myarray[i][j] = state.myarray[i][j];
                    myarray[i][j] = state.myarray[j][i]; 
                    myslit[i][j] = 0;

                    if(j == mid){myslit[i][j] = 1;}
                    if(i == mid2){myslit[i][j] = 1;}

                    if(myarray[i][j] > max){myarray[i][j] = max;}
                    if(myarray[i][j] < min){myarray[i][j] = min;}

                    // Create line perpendicular to incident wavefront

                    if(state.theta1 >= Math.PI*0.25){
                        jangle = j - mid;
                        iangle = mid2 - (int)((double)jangle*Math.cos(state.theta1)/Math.sin(state.theta1));

                        if(iangle < 0 || iangle > rgbwidth || j < mid ){ }
                        else{
                            myslit[iangle][j] = 2;
                        }
                    }

                    if(state.theta1 < Math.PI*0.25){
                        iangle = mid2 -i;
                        jangle = mid + (int)((double)iangle*Math.sin(state.theta1)/Math.cos(state.theta1));

                        if(jangle < 0 || jangle > rgbheight || i > mid2){ }
                        else{
                            myslit[i][jangle] = 2;
                        }
                    }
                    //------------------------------------------------------
                    // Create lines perpendicular to transmitted wavefront
                    if(state.theta2 >= Math.PI*0.25 || state.theta1 >= totang){
                        jangle = mid - j;
                        if(state.theta1 >= totang){
                            iangle = mid2;
                        }
                        else{
                            iangle = mid2 + (int)((double)jangle*Math.cos(state.theta2)/Math.sin(state.theta2));
                        }

                        if(iangle < 0 || iangle > rgbwidth || j > mid ){ }
                        else{
                            myslit[iangle][j] = 2;
                        }
                    }

                    if(state.theta2 < Math.PI*0.25){
                        iangle = i -mid2;
                        jangle = mid - (int)((double)iangle*Math.sin(state.theta2)/Math.cos(state.theta2));

                        if(jangle < 0 || jangle > rgbheight || i < mid2){ }
                        else{
                            myslit[i][jangle] = 2;
                        }
                    }
                }
            }
        }
        if(state.Reflected){
            for(i = 0; i < rgbwidth+1; i++){
                for(j = 0; j < rgbheight+1; j++){

                    //myarray[i][j] = state.myarray[j][i];
                    myarray[i][j] = state.myarray[j][i];//change 3
                    myslit[i][j] = 0;

                    if(j == mid){myslit[i][j] = 1;}
                    if(i == mid2){myslit[i][j] = 1;}

                    if(myarray[i][j] > max){myarray[i][j] = max;}
                    if(myarray[i][j] < min){myarray[i][j] = min;}

                    // Create lines perpendicular to reflected wavefront
                    if(state.theta1 >= Math.PI*0.25){
                        jangle = mid-j;
                        iangle = mid2 - (int)((double)jangle*Math.cos(state.theta1)/Math.sin(state.theta1));

                        if(iangle < 0 || iangle > rgbwidth || j > mid){ }
                        else{
                            myslit[iangle][j] = 2;
                        }
                    }
                    if(state.theta1 < Math.PI*0.25){
                        iangle = mid2 -i;
                        jangle = mid - (int)((double)iangle*Math.sin(state.theta1)/Math.cos(state.theta1));

                        if((jangle) < 0 || (jangle) > rgbheight || i > mid2){ }
                        else{
                            myslit[i][jangle] = 2;
                        }
                    }
                    // Create lines perpendicular to transmitted wavefront
                    if(state.theta2 >= Math.PI*0.25 || state.theta1 >= totang){
                        jangle = mid - j;
                        if(state.theta1 >= totang){
                            iangle = mid2;
                        }
                        else{
                            iangle = mid2 + (int)((double)jangle*Math.cos(state.theta2)/Math.sin(state.theta2));
                        }

                        if(iangle < 0 || iangle > rgbwidth || j > mid ){ }
                        else{
                            myslit[iangle][j] = 2;
                        }
                    }
                    if(state.theta2 < Math.PI*0.25){
                        iangle = i -mid2;
                        jangle = mid - (int)((double)iangle*Math.sin(state.theta2)/Math.cos(state.theta2));

                        if(jangle < 0 || jangle > rgbheight || i < mid2){ }
                        else{
                            myslit[i][jangle] = 2;
                        }
                    }
                }
            }
        }

        for(i = 0; i < rgbwidth+1; i++){
            for(j = 0; j < rgbheight+1; j++){
                if(j == rgbheight -14){myslit[i][j] = 1;}
                if(j == 12){myslit[i][j] = 1;}
            }
        }
        for(i = 0; i < rgbwidth+1; i++){
            for(j = 0; j < rgbheight+1; j++){ // actual values
                  if(myslit[i][j] == 0){
                        map = (int)MaestroA.mapper(myarray[i][j],255.0,0.0,max,min);
                        rgbPixels[j*new_width+i] = colorArray[map].getRGB();
                  }
                  else if(myslit[i][j] == 1){ // black
                        map = 255;
                        rgbPixels[j*new_width+i] = new Color(0,0,0).getRGB();
                  }
                  else if(myslit[i][j] == 2){ // green
                        map = 255;
                        rgbPixels[j*new_width+i] = new Color(0,255,0).getRGB();
                  }  
            }
        }
        myarray = null;
        mis = new MemoryImageSource(new_width,rgbheight,rgbPixels,0,new_width);
        mis.setAnimated(true);
        mis.setFullBufferUpdates(false);
        im = createImage(mis);
        g.drawImage(im,LeftImageIndent,(getSize().height-rgbheight)/2+1,this);
    }
	
    private void drawImage(Graphics g){
        g.drawImage(im,LeftImageIndent,(getSize().height-rgbheight)/2+1,this);
    }

    private void drawPalette(Graphics g){
        int i, j, map, imax;
        FontMetrics fm = g.getFontMetrics();
        imax = state.palettereference;

        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);
        }

        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();
            }
        }
    }

    public void setWidth(double ratio){
        this.new_width=(int)(rgbwidth/ratio);
        this.rgbPixels=new int[(int)(rgbwidth/ratio*rgbheight)];    
    }

    public void update(Graphics g){
        //drawPalette(g);
        updatePixels(g);
        mis.newPixels(0,0,new_width,rgbheight);
        drawImage(g);
    }
}