import java.awt.*;
import java.awt.image.*;

class Raster {
    protected int width, height;
    public final  float Znear = 1000;
    public final  float Zfar = -1000;
    public int pixel[];
    float depth[];

    ///////////////////////// Constructors //////////////////////

    /**
     *  This constructor which takes no arguments
     *  allows for future extension.
     */
    public Raster()
    {
    }

    /**
     *  This constructor creates an uninitialized
     *  Raster Object of a given size (w x h).
     */
    public Raster(int w, int h)
    {
        width = w;
        height = h;
        pixel = new int[w*h];
        depth = new float[w*h];
        resetz();
    }

    /**
     *  This constructor creates an Raster initialized
     *  with the contents of an image.
     */
    public Raster(Image img)
    {
        try {
            PixelGrabber grabber = new PixelGrabber(img, 0, 0, -1, -1, true);
            if (grabber.grabPixels()) {
                width = grabber.getWidth();
                height = grabber.getHeight();
                pixel = (int []) grabber.getPixels();
            }
        } catch (InterruptedException e) {
        }
        depth=new float[this.size()];
    }

    ////////////////////////// Methods //////////////////////////

    /**
     *  Returns the number of pixels in the Raster
     */
    public int size( ) {
        return pixel.length;
    }

    /**
     *  Access instance variables
     */
    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }

    public int [] getPixels() {
        return pixel;
    }

    /**
     *  Fills a Raster with a solid color
     */
    public void fill(Color c) {
        int s = size();
        int rgb = c.getRGB();
        for (int i = 0; i < s; i++)
            pixel[i] = rgb;
    }

     /**
     *  Converts Rasters to Images
     */
    public final Image toImage(Component root)
    {
        return root.createImage(new MemoryImageSource(width, height, pixel, 0, width));
    }

    
        /**
     *  Converts Rasters to Images
     */
    public Image toImage() {
        Toolkit toolkit = Toolkit.getDefaultToolkit();
        Image img = toolkit.createImage(new MemoryImageSource(width, height, pixel, 0, width));
        return img;
    }

    /**
     *  Gets a pixel from a Raster
     */
    public int getPixel(int x, int y) {
        return pixel[y*width+x];
    }
    
    /***** changed for Project #4 **********/
    public void resetz() {
        for (int i=0;i<depth.length;i++) {
            depth[i]=Zfar;
        }
    }
    
    /* get the depth value of point at x,y*/
    public float getDepth(int x, int y) {
        return depth[y*width+x];
    }

    /**
     *  Gets a color from a Raster
     */
    public Color getColor(int x, int y) {
        return new Color(pixel[y*width+x]);
    }

    /**
     *  Sets a pixel to a given value
     */
    public boolean setPixel(int pix, int x, int y, float z) {
        try{if (z>getDepth(x,y)) {
            //System.out.println("setting pix "+x+" "+y+" to color "+(pix&255));
            pixel[y*width+x] = pix;
            depth[y*width+x] = z;
        }}catch(ArrayIndexOutOfBoundsException e){System.out.println("error is at "+x+" "+y);}
        return true;
    }

    /**
     *  Sets a pixel to a given color
     */
    public boolean setColor(Color c, int x, int y) {
        pixel[y*width+x] = c.getRGB();
        return true;
    }
}
