import java.awt.*;
import java.awt.image.*;

class Raster implements ImageObserver {
    protected int width, height;
    protected int pixel[];

    ///////////////////////// 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];
    }

    private boolean available;  // used to communicate image download status

    /**
     *  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) {
        }
    }

    public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h)
    {
        if ((flags & WIDTH) != 0) width = w;
        if ((flags & HEIGHT) != 0) height = h;
        available = ((width >= 0) && (height >= 0));
        return !available;
    }


    ////////////////////////// Methods //////////////////////////

    /**
     *  Returns the number of pixels in the Raster
     */
    public int getSize( ) {
      return pixel.length;
    }

    /**
     *  Returns the number of pixels in the Raster
     */
    public int getWidth( ) {
      return width;
    }

    /**
     *  Returns the number of pixels in the Raster
     */
    public int getHeight( ) {
      return height;
    }

    public int[] getPixelBuffer( ) {
      return pixel;
    }

    /**
     *  Fills a Raster with a solid color
     */
    public void fill(int argb) {
      int s = pixel.length;
      for (int i = 0; i < s; i++)
        pixel[i] = argb;
    }

    public void fill(Color c) {
      fill(c.getRGB());
    }

    /**
     *  Converts Rasters to Images
     */
    public Image toImage( ) {
        Toolkit toolkit = Toolkit.getDefaultToolkit();
        Image img = toolkit.createImage(new MemoryImageSource(width, height, pixel, 0, width));
        return img;
    }

    /**
     * The following helper routine
     * test that x and y are valid
     */
    private final boolean invalid(int x, int y) {
      return ((x < 0) || (x >= width) || (y < 0) || (y >= height));
    }

    /**
     *  Get a pixel from a Raster
     */
    public int getPixel(int x, int y) {
      if (invalid(x, y))
        return 0;
      else
        return pixel[y*width+x];
    }

    /**
     *  Get a color from a Raster
     */
    public Color getColor(int x, int y) {
      return new Color(getPixel(x,y));
    }

    /**
     *  Set a pixel to a given value
     */
    public boolean setPixel(int pix, int x, int y) {
      if (invalid(x, y)) {
        return false;
      } else {
        pixel[y*width+x] = pix;
        return true;
      }
    }

    /**
     *  Set a pixel to a given color
     */
    public boolean setColor(Color c, int x, int y) {
      return setPixel(c.getRGB(), x, y);
    }
}