package io.gitlab.jfronny.ImgJava.imageProcessing;

import io.gitlab.jfronny.ImgJava.util.MColor;
import io.gitlab.jfronny.ImgJava.util.Picture;

import java.awt.*;

public class UtilColor {
    public enum GrayscaleMode {
        Avg, Min, Max, Natural
    }
    
    public static Picture tint(Picture picture, Color tint) {
        int w = picture.getWidth();
        int h = picture.getHeight();

        Color[][] pixel = picture.getPixelArray();
        Color[][] pixelNeu = new Color[w][h];

        for (int x = 0; x < w; x++) {
            for (int y = 0; y < h; y++) {
                pixelNeu[x][y] = new MColor(pixel[x][y]).tint(tint).get();
            }
        }

        picture.setPixelArray(pixelNeu);
        return picture;
    }

    public static Picture tint(Picture picture, double factor) {
        int w = picture.getWidth();
        int h = picture.getHeight();

        Color[][] pixel = picture.getPixelArray();
        Color[][] pixelNeu = new Color[w][h];

        for (int x = 0; x < w; x++) {
            for (int y = 0; y < h; y++) {
                pixelNeu[x][y] = new MColor(pixel[x][y]).mult(factor).get();
            }
        }

        picture.setPixelArray(pixelNeu);
        return picture;
    }
    
    public static Picture tint(Picture picture, double fR, double fG, double fB) {
        int w = picture.getWidth();
        int h = picture.getHeight();

        Color[][] pixel = picture.getPixelArray();
        Color[][] pixelNeu = new Color[w][h];

        for (int x = 0; x < w; x++) {
            for (int y = 0; y < h; y++) {
                pixelNeu[x][y] = new MColor(pixel[x][y]).tint(fR, fG, fB).get();
            }
        }

        picture.setPixelArray(pixelNeu);
        return picture;
    }

    public static Picture switcheroo(Picture picture) {
        int w = picture.getWidth();
        int h = picture.getHeight();

        Color[][] pixel = picture.getPixelArray();
        Color[][] pixelNeu = new Color[w][h];

        for (int x = 0; x < w; x++) {
            for (int y = 0; y < h; y++) {
                Color c = pixel[x][y];
                pixelNeu[x][y] = new Color(c.getGreen(), c.getBlue(), c.getRed(), c.getAlpha());
            }
        }

        picture.setPixelArray(pixelNeu);
        return picture;
    }
    
    public static Picture invert(Picture picture) {
        int w = picture.getWidth();
        int h = picture.getHeight();

        Color[][] pixel = picture.getPixelArray();
        Color[][] pixelNeu = new Color[w][h];

        for (int x = 0; x < w; x++) {
            for (int y = 0; y < h; y++) {
                pixelNeu[x][y] = new MColor(pixel[x][y]).invert().get();
            }
        }

        picture.setPixelArray(pixelNeu);
        return picture;
    }

    public static Picture grayscale(Picture picture, GrayscaleMode mode) {
        int w = picture.getWidth();
        int h = picture.getHeight();

        Color[][] pixel = picture.getPixelArray();
        Color[][] pixelNeu = new Color[w][h];

        for (int x = 0; x < w; x++) {
            for (int y = 0; y < h; y++) {
                Color c = pixel[x][y];
                int n = MColor.clamp(switch (mode) {
                    case Avg -> (c.getRed() + c.getGreen() + c.getBlue()) / 3d;
                    case Max -> Math.max(Math.max(c.getRed(), c.getBlue()), c.getGreen());
                    case Min -> Math.min(Math.min(c.getRed(), c.getBlue()), c.getGreen());
                    case Natural -> c.getRed() * 0.299d + c.getGreen() * 0.587d + c.getBlue() * 0.114d;
                });
                pixelNeu[x][y] = new Color(n, n, n, c.getAlpha());
            }
        }

        picture.setPixelArray(pixelNeu);
        return picture;
    }
}
