public class ImageManipulator {
    
    /*
     * Helper method for converting a value between 0-255 into a shade of gray.
     * If the input is 192, that has an 8 bit binary representation of 11000000.
     * The corresponding shade of gray in ARGB format should then be:
     * 
     * 00000000110000001100000011000000
     * |alpha ||red   ||green ||blue  |
     */
    private static int toGrayscaleRGB(int grayscale) {
        return grayscale + (256 * grayscale) + (65536 * grayscale);
    }
    
    /*
     * Given a 32 bit integer, representing a color in ARGB format,
     * return the integer interpretation of the 8-bit sequence
     * representing the red value for this color.
     */
    public static int getRed(int pixel) {
        int mask = 0xFF;
        return (pixel >> 16) & mask;
    }
    
    /*
     * Given a 32 bit integer, representing a color in ARGB format,
     * return the integer interpretation of the 8-bit sequence
     * representing the green value for this color.
     */
    public static int getGreen(int pixel) {
        int mask = 0xFF;
        return (pixel >> 8) & mask;
    }
    
    /*
     * Given a 32 bit integer, representing a color in ARGB format,
     * return the integer interpretation of the 8-bit sequence
     * representing the blue value for this color.
     */
    public static int getBlue(int pixel) {
        int mask = 0xFF;
        return pixel & mask;
    }
    
    /*
     * Given a rectangular int[][] representing an image,
     * calculate the grayscale value of every int in the 2D array
     * and then copy that value to a new int[][] with the same dimensions.
     * 
     * This will return a new version of the input img in black and white.
     */
    public static int[][] toBlackAndWhite(int[][] img) {
        
        int[][] blackAndWhite = new int[img.length][img[0].length];
        
        for (int row = 0; row < img.length; row++) {
            for (int col = 0; col < img[row].length; col++) {
                int color = img[row][col];
                int red = getRed(color);
                int green = getGreen(color);
                int blue = getBlue(color);
                
                int grayscale = (red + green + blue) / 3;
                blackAndWhite[row][col] = toGrayscaleRGB(grayscale);
            }
        }
        return blackAndWhite;
    }
    
    /*
     * Given a rectangular int[][] img representing an image with n rows, return a 
     * new version of img, called flippedImg, where the order of the rows in img are
     * reversed.
     * 
     * The values within the rows should have the same order, but img[0] should be
     * stored as flippedImg[n - 1], img[1] as flippedImg[n - 2], and so on.
     * 
     * This will return a new version of the input, but flipped vertically.
     */
    public static int[][] verticalFlip(int[][] img) {
        int nRows = img.length;
        int nCols = img[0].length;
        int[][] flippedImg = new int[nRows][nCols];
        for (int row = 0; row < nRows; row++) {
            flippedImg[nRows - 1 - row] = img[row];
        }
        
        return flippedImg;
        
    }
    public static void main(String[] args) {
        String filename = args[0];
        int[][] imageData = ImageData.load(filename);
        
        int[][] blackAndWhiteImg = toBlackAndWhite(imageData);
        ImageData.show(blackAndWhiteImg);
        
        int[][] flippedImg = verticalFlip(imageData);
        ImageData.show(flippedImg);
        
        int color = 0x3384EC12;
        System.out.println("00110011100001001110110000010010");
        int red = getRed(color);
        int green = getGreen(color);
        int blue = getBlue(color);
        
        System.out.println(red);
        System.out.println(green);
        System.out.println(blue);
        
        System.out.println(red == 0x84);
        System.out.println(green == 0xEC);
        System.out.println(blue == 0x12);

    }
}

