package com.cringe_studios.cristmastreescanning;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.awt.Color;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

import javax.imageio.ImageIO;

import org.junit.jupiter.api.Test;

import com.cringe_studios.christmastreescanning.Homograph;
import com.cringe_studios.christmastreescanning.Point3D;
import com.cringe_studios.christmastreescanning.Scanner;
import com.cringe_studios.christmastreescanning.TwoSidedScanner;
import com.cringe_studios.christmastreescanning.scanning.image_scanning.GrayscaleImageScanner;
import com.cringe_studios.christmastreescanning.scanning.image_scanning.ImageScanner;

public class ExampleTest {

	@Test
	public void testSus() {
		assertEquals(1 + 1, 2);
	}
	
	@Test
	public void scannerTest() {
		try {
			BufferedImage LED1Front = ImageIO.read(ExampleTest.class.getResourceAsStream("ScannerTest1_LED1_front.png"));
			BufferedImage LED2Front = ImageIO.read(ExampleTest.class.getResourceAsStream("ScannerTest1_LED2_front.png"));
			BufferedImage LED3Front = ImageIO.read(ExampleTest.class.getResourceAsStream("ScannerTest1_LED3_front.png"));
			BufferedImage LED1Right = ImageIO.read(ExampleTest.class.getResourceAsStream("ScannerTest1_LED1_right.png"));
			BufferedImage LED2Right = ImageIO.read(ExampleTest.class.getResourceAsStream("ScannerTest1_LED2_right.png"));
			BufferedImage LED3Right = ImageIO.read(ExampleTest.class.getResourceAsStream("ScannerTest1_LED3_right.png"));
			
			Scanner scanner = new TwoSidedScanner(new BufferedImage[] {LED1Front, LED2Front, LED3Front}, new BufferedImage[] {LED1Right, LED2Right, LED3Right});
			scanner.setGammaDelta((byte)(0.1 * 255));
			Homograph homo = scanner.scan();
			homo.normalize();
			homo.merge();
			homo.renormalize();
			Point3D points[] = homo.getPoints();
			
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	
	@Test
	public void generateVisualTestImages() {
		Path results;
		try {
			results = Files.createTempDirectory("testResult");
			for (int i = 0; i < 100; i++) {
				try {
					BufferedImage image = ImageIO.read(ExampleTest.class.getResourceAsStream("/0_" + i + ".png"));
					ImageScanner currentScanner = new GrayscaleImageScanner(image);
					Point2D p = currentScanner.getBrightestSpot((byte)(0.1 * 255));
					for (int j = -2; j < 2; j++) {
						for (int k = -2; k < 2; k++) {
							if ((int) p.getX() + j > 0 && (int) p.getX() + j < image.getWidth()
									&& (int) p.getY() + k > 0 && (int) p.getY() + k < image.getHeight())
								image.setRGB((int) p.getX() + j, (int) p.getY() + k, Color.red.getRGB());
						}
					}
					ImageIO.write(image, "png", Files.newOutputStream(results.resolve(String.valueOf(i) + ".png")));
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@Test
	public void gradientTest() {
		Path results;
		try {
			results = Files.createTempDirectory("testResultGradient");
			try {
				BufferedImage image = ImageIO.read(ExampleTest.class.getResourceAsStream("/gradient.png"));
				ImageScanner currentScanner = new GrayscaleImageScanner(image);
				Point2D p = currentScanner.getBrightestSpot((byte)0);
				for (int j = -2; j < 2; j++) {
					for (int k = -2; k < 2; k++) {
						if ((int) p.getX() + j > 0 && (int) p.getX() + j < image.getWidth() && (int) p.getY() + k > 0
								&& (int) p.getY() + k < image.getHeight())
							image.setRGB((int) p.getX() + j, (int) p.getY() + k, Color.red.getRGB());
					}
				}
				ImageIO.write(image, "png", Files.newOutputStream(results.resolve(String.valueOf("gradientout") + ".png")));
			} catch (IOException e) {
				e.printStackTrace();
			}

		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void generateVisualTestImagesWithOldMethod() {
		Path results;
		try {
			results = Files.createTempDirectory("testResultOldWay");

			for (int i = 0; i < 100; i++) {
				try {
					BufferedImage image = ImageIO.read(ExampleTest.class.getResourceAsStream("/0_" + i + ".png"));

					BufferedImage bi2 = new BufferedImage(image.getWidth(), image.getHeight(),
							BufferedImage.TYPE_INT_RGB);
					bi2.createGraphics().drawImage(image, 0, 0, null);
					int[] colors = ((DataBufferInt) bi2.getRaster().getDataBuffer()).getData();
					int x = -1, y = -1, brightness = 0;
					boolean multipleBright = true;
					int boxLeangth = 3;

					while (multipleBright) {
						if (boxLeangth > 1000) {
							System.out.println("alles gleich hell");
							return;
						}
						for (int ä = 0; ä < colors.length; ä++) {
							int b = 0;

							x: for (int k = 0; k < boxLeangth; k++) {
								y: for (int j = 0; j < boxLeangth; j++) {
									int c = ä;
									if (c + j - boxLeangth / 2 > 0 && c + j - boxLeangth / 2 < colors.length) {
										c += j - boxLeangth / 2;
									} else {
										continue y;
									}
									if (c + (k - boxLeangth / 2) * bi2.getWidth() > 0
											&& c + (k - boxLeangth / 2) * bi2.getWidth() < colors.length) {
										c += (k - boxLeangth / 2) * bi2.getWidth();
									} else {
										continue x;
									}
									b += colors[c] & 255 + ((colors[c] >> 8) & 255) + ((colors[c] >> 8) & 255);
								}
							}

							if (b > brightness) {
								brightness = b;
								x = ä % bi2.getWidth();
								y = ä / bi2.getWidth();
								multipleBright = false;
							} else if (b == brightness) {
								multipleBright = true;
							}
						}
						if (multipleBright) {
							boxLeangth += 2;
						}
					}

					for (int j = -2; j < 2; j++) {
						for (int k = -2; k < 2; k++) {
							if (x + j > 0 && x + j < image.getWidth() && y + k > 0 && y + k < image.getHeight())
								image.setRGB(x + j, y + k, Color.red.getRGB());
						}
					}
					ImageIO.write(image, "png", Files.newOutputStream(results.resolve(String.valueOf(i) + ".png")));

				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
