package ac.essex.ecj.imaging;

import java.awt.image.BufferedImage;
import java.awt.*;
import java.io.File;

/**
 * Loads Pixels from an image file.
 */
public class PixelLoader implements Cloneable {

    File file = null;

    BufferedImage img;

    public PixelLoader(String filename) throws Exception {
        this(new File(filename));
    }

    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public BufferedImage getBufferedImage() {
        return img;
    }


    public PixelLoader(File imageFile) throws Exception {

        // ensure that the file actually exists before proceeding
        if (!imageFile.exists()) throw new Exception("File does not exist: " + imageFile.getAbsolutePath());

        // save a reference to the file
        this.file = imageFile;

        // Use the Java ImageIO library to open the file as a buffered image.
        img = javax.imageio.ImageIO.read(imageFile);


    }


    public File getFile() {
        return file;
    }

    int[][] greyColourCache;

    /**
     * Gets a grayscale value of the pixel
     *
     * @param x
     * @param y
     * @return
     * @throws RuntimeException
     */
    public int getPixel(int x, int y) throws RuntimeException {

        // this is called many times for each pixel. Hence we'll do the maths once only.
        if (greyColourCache == null) createColourCaches();

        return greyColourCache[x][y];


    }

    public int getBooleanPixel(int x, int y) {
        return getPixel(x, y) == 0 ? 0 : 1;
    }


    private void createColourCaches() {

        greyColourCache = new int[img.getWidth()][img.getHeight()];

        for (int yPos = 0; yPos < img.getHeight(); yPos++) {
            for (int xPos = 0; xPos < img.getWidth(); xPos++) {

                // get a colour object, which saves us having to shift bits and other stuff.
                Color c = new Color(img.getRGB(xPos, yPos));

                // extract the colours
                int red = c.getRed();
                int green = c.getGreen();
                int blue = c.getBlue();

                greyColourCache[xPos][yPos] = (int) ((red * 0.3) + (green * 0.59) + (blue * 0.11));

            }

        }
    }

    public static final int RED = new Color(255, 20, 0).getRGB();
    public static final int BLUE = new Color(20, 20, 255).getRGB();

    public void setPixelRed(int x, int y) {
        setPixel(x, y, RED);
    }

    public void setPixelBlue(int x, int y) {
        setPixel(x, y, BLUE);
    }


    public void setPixel(int x, int y, int colour) {

        img.setRGB(x, y, colour);
        if (greyColourCache != null) {
            greyColourCache[x][y] = colour;
        }

    }

    public void save(String filename) throws Exception {
        save(new File(filename));
    }

    public void save(File imageFile) throws Exception {

        // Use the Java ImageIO library to shave the file as a BMP image
        javax.imageio.ImageIO.write(img, "bmp", imageFile);


    }

    public int getWidth() {
        return img.getWidth();
    }

    public int getHeight() {
        return img.getHeight();
    }

}

