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

/* An instance maintains a row-major order array of pixels for an image. */
public class ImageArray {
    /** DM provides methods for extracting components of an rgb pixel.*/
    public final static DirectColorModel DM= (DirectColorModel) ColorModel.getRGBdefault();
    
    int rows;    // number of rows in the image
    int cols;    // number of columns in the image
    int[] rmoArray;   // The pixels of the image, in row-major order
    
    /** Constructor: An instance for image im with r rows and c cols.
       Precondition: im is an Image that is a .jpg (or .jpeg) file.
       */
    public ImageArray(Image im, int r, int c) {
        rows= r;
        cols= c;
        rmoArray= new int[r*c];
        
        /*Class PixelGrabber is given an image, as well as the number
         of rows and cols it should contain, and an int array rmoArray
         into which this image should be stored.
         
         Calling method grabPixels then causes the image to be stored
         in one-dimensional array rmoArray --even though a picture is a
         two-dimensional thing. The two-dimensional array of elements
         is stored in rmoArray in row-major order.*/
        PixelGrabber pg=
            new PixelGrabber(im, 0, 0, c, r, rmoArray, 0, c);
        try {
            pg.grabPixels();
        }
        catch (InterruptedException e) {
            System.out.println("pixel grab interrupted!");
            return;
        } 
    }
    
    /** Constructor: An instance with r rows and c cols and pixels
      (in row-major order) given by rmoa. A copy of rmoa is
      made: the argument array is different and remains unchanged.
      */
    public ImageArray(int[] rmoa, int r, int c) {
        rows= r;
        cols= c;
        rmoArray= new int[r*c];
        
        // copy rmoa into rmoArray.
        // inv: items 0..i-1 of rowMajOrderArray have been copied.
        for (int i= 0; i < r*c; i= i+1) {
            rmoArray[i]= rmoa[i];
        }
    }
    
    /** = the number of rows. */
    public int getRows() {
        return rows;
    }
    
    /** = the number of columns. */
    public int getCols() {
        return cols;
    }
    
    /** = the image (in row-major order). */
    public int[] getRmoArray() {
        return rmoArray;
    }
    
    /** Set number of rows to r */
    public void setRows(int r) {
        rows= r;
    }
    
    /** Set number of columns to c */
    public void setCols(int c) {
        cols= c;
    }
    
    /** = a copy of this instance. */
    public ImageArray copy() {
        return new ImageArray(rmoArray, rows, cols);
    }
    
    /** = the pixel value at [row, col] of the image. */
    public int getPixel(int row, int col) {
        return rmoArray[row*cols + col];
    }
    
    /** set the pixel value at [row, col] of the image to v. */
    public void setPixel(int row, int col, int v) {
        rmoArray[row*cols + col]= v;
    }
    
    /** swap the pixel at [a, b] with the pixel at [i, j]. */
    public void swapPixels(int a, int b, int i, int j) {
        int temp= getPixel(a, b);
        setPixel(a, b, getPixel(i, j));
        setPixel(i, j, temp);
    }
    
    /** = pixel number p of the image (in row major order),
          with pixel number 0 being the first. */
    public int getPixel(int p) {
        return rmoArray[p];
    }
    
    /** Set pixel number p (in row major order) of the image to v. */
    public void setPixel(int p, int v) {
        rmoArray[p]= v;
    }
    
    /** = pixel pix, in the form (red, green, blue) */
    public static String toString (int pix) {
        int red= DM.getRed(pix);
        int green=  DM.getGreen(pix);
        int blue=  DM.getBlue(pix);
        int alpha=  DM.getAlpha(pix);
        
        return "(" + red + ", " + green + ", " + blue + ")";
    }
}

