import java.awt.*;
import java.awt.image.*;

class Raster {
    public int width, height;
    public int pixel[];
    public MemoryImageSource source;

    ///////////////////////// 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];
    }

    /**
     *  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) {
        }
    }

    ////////////////////////// Methods //////////////////////////

    /**
     *  Returns the number of pixels in the Raster
     */
    public int size( )
    {
        return pixel.length;
    }

    /**
     *  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 Image toImage()
    {
        return Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(width, height, pixel, 0, width));
    }

    /**
     *  Converts Rasters to Images that can be updated.
     */
    public Image toUpdatedImage()
    {
      source = new MemoryImageSource(width, height, pixel, 0, width);
      source.setAnimated(true);
      return Toolkit.getDefaultToolkit().createImage(source);
    }

    /**
     *  Gets a pixel from a Raster
     */
    public int getPixel(int x, int y)
    {
        return pixel[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)
    {
        pixel[y*width+x] = pix;
        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;
    }

  /**
    * Copies another raster into this one
    */
  public void dup(Raster in) {
    dup(in, 0, 0, width, height);
  }

  /**
    * Copies another raster into this one, with a clip rectangle.
    */
  public void dup(Raster in, int clipx, int clipy, int clipw, int cliph) {
    int xlimit = (width>in.width) ? in.width : width;
    int ylimit = (height>in.height) ? in.height : height;

    if ((clipx+clipw) < xlimit) xlimit = clipx+clipw;
    if ((clipy+cliph) < ylimit) ylimit = clipy+cliph;

    for (int xloop=clipx; xloop<xlimit; xloop++)
      for (int yloop=clipy; yloop<ylimit; yloop++)
	pixel[yloop*width+xloop] = in.pixel[yloop*in.width+xloop];
  }
}
