package com.example.rgpractice;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.image.PixelWriter;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

import java.io.IOException;

public class HelloApplication extends Application {
	
	private static interface Emmiter {
		public void emit ( int x, int y );
	}
	
	private static void circle ( int r, Emmiter emmiter ) {
		int d = 3 - 2 * r;
		int x = r;
		int y = 0;
		
		while ( y <= x ) {
			emmiter.emit ( x, y );
			
			if ( d < 0 ) {
				d += 4 * y + 6;
			} else {
				d += 4 * ( y - x ) + 10;
				x--;
			}
			y++;
		}
	}
	
	private static void hLine ( int xStart, int xEnd, int y, PixelWriter pixelWriter, Color color ) {
		for ( int x = xStart; x < xEnd; ++x ) {
			pixelWriter.setColor ( x, y, color );
		}
	}
	
	private static void jinJang ( int cx, int cy, int r, PixelWriter pixelWriter ) {
		Emmiter border = (x, y) -> {
			pixelWriter.setColor ( cx + x, cy + y, Color.BLACK );
			pixelWriter.setColor ( cx - x, cy + y, Color.BLACK );
			pixelWriter.setColor ( cx + x, cy - y, Color.BLACK );
			pixelWriter.setColor ( cx - x, cy - y, Color.BLACK );
			
			pixelWriter.setColor ( cx + y, cy + x, Color.BLACK );
			pixelWriter.setColor ( cx + y, cy - x, Color.BLACK );
			pixelWriter.setColor ( cx - y, cy + x, Color.BLACK );
			pixelWriter.setColor ( cx - y, cy - x, Color.BLACK );
		};
		
		Emmiter halfBlack = (x, y) -> {
			hLine ( cx, cx + x, cx + y, pixelWriter, Color.BLACK );
			hLine ( cx, cx + x, cx - y, pixelWriter, Color.BLACK );
			hLine ( cx, cx + y, cx + x, pixelWriter, Color.BLACK );
			hLine ( cx, cx + y, cx - x, pixelWriter, Color.BLACK );
		};
		
		Emmiter smallWhite = (x, y) -> {
			hLine ( cx, cx + x, cx + y - r / 2, pixelWriter, Color.WHITE );
			hLine ( cx, cx + x, cx - y - r / 2, pixelWriter, Color.WHITE );
			hLine ( cx, cx + y, cx + x - r / 2, pixelWriter, Color.WHITE );
			hLine ( cx, cx + y, cx - x - r / 2, pixelWriter, Color.WHITE );
		};
		
		Emmiter smallBlack = (x, y) -> {
			hLine ( cx - x, cx, cx + y + r / 2, pixelWriter, Color.BLACK );
			hLine ( cx - x, cx, cx - y + r / 2, pixelWriter, Color.BLACK );
			hLine ( cx - y, cx, cx + x + r / 2, pixelWriter, Color.BLACK );
			hLine ( cx - y, cx, cx - x + r / 2, pixelWriter, Color.BLACK );
		};
		
		circle ( r, halfBlack );
		circle ( r / 2, smallWhite );
		circle ( r / 2, smallBlack );
		circle ( r, border );
	}
	
	@Override
	public void start ( Stage stage ) throws IOException {
		Canvas canvas = new Canvas ( 600, 600 );
		
		PixelWriter pixelWriter = canvas.getGraphicsContext2D ( ).getPixelWriter ( );
		
		final int cx = 300;
		final int cy = 300;
		final int r  = 300;
		
		Emmiter simple = (x, y) -> {
			pixelWriter.setColor ( cx + x, cy + y, Color.BLACK );
			pixelWriter.setColor ( cx - x, cy + y, Color.BLACK );
			pixelWriter.setColor ( cx + x, cy - y, Color.BLACK );
			pixelWriter.setColor ( cx - x, cy - y, Color.BLACK );
			
			pixelWriter.setColor ( cx + y, cy + x, Color.BLACK );
			pixelWriter.setColor ( cx + y, cy - x, Color.BLACK );
			pixelWriter.setColor ( cx - y, cy + x, Color.BLACK );
			pixelWriter.setColor ( cx - y, cy - x, Color.BLACK );
		};
		
		Emmiter blackCircle = (x, y) -> {
			hLine ( cx - x, cx + x, cy + y, pixelWriter, Color.BLACK );
			hLine ( cx - x, cx + x, cy - y, pixelWriter, Color.BLACK );
			hLine ( cx - y, cx + y, cy + x, pixelWriter, Color.BLACK );
			hLine ( cx - y, cx + y, cy - x, pixelWriter, Color.BLACK );
			
		};
		
		Emmiter whiteCircle = (x, y) -> {
			hLine ( cx - x, cx + x, cy + y, pixelWriter, Color.WHITE );
			hLine ( cx - x, cx + x, cy - y, pixelWriter, Color.WHITE );
			hLine ( cx - y, cx + y, cy + x, pixelWriter, Color.WHITE );
			hLine ( cx - y, cx + y, cy - x, pixelWriter, Color.WHITE );
		};
		
		Emmiter twoQuarters = (x, y) -> {
			hLine ( cx, cx + x, cy + y, pixelWriter, Color.BLACK );
			hLine ( cx, cx + y, cy + x, pixelWriter, Color.BLACK );
			hLine ( cx - x, cx, cy - y, pixelWriter, Color.BLACK );
			hLine ( cx - y, cx, cy - x, pixelWriter, Color.BLACK );
		};
		
		// jinJang ( cx, cy, r, pixelWriter );
		
		Emmiter exam = (x, y) -> {
			hLine ( cx - r, cx - r + x, cy - r + y, pixelWriter, Color.BLACK );
			hLine ( cx - r, cx - r + y, cy - r + x, pixelWriter, Color.BLACK );
			
			hLine ( cx + r - x, cx + r, cy - r + y, pixelWriter, Color.BLACK );
			hLine ( cx + r - y, cx + r, cy - r + x, pixelWriter, Color.BLACK );
			
			hLine ( cx - r, cx - r + x, cy + r - y, pixelWriter, Color.BLACK );
			hLine ( cx - r, cx - r + y, cy + r - x, pixelWriter, Color.BLACK );
			
			hLine ( cx + r - x, cx + r, cy + r - y, pixelWriter, Color.BLACK );
			hLine ( cx + r - y, cx + r, cy + r - x, pixelWriter, Color.BLACK );
			
			// hLine ( cx + r - x, cx + r, y, pixelWriter, Color.BLACK );
			// hLine ( cx + r - y, cx + r, x, pixelWriter, Color.BLACK );
			// hLine ( cx + r - x, cx + r, -y, pixelWriter, Color.BLACK );
			// hLine ( cx + r - y, cx + r, -x, pixelWriter, Color.BLACK );
		};
		circle ( r, exam );
		
		Group root = new Group ( canvas );
		Scene      scene      = new Scene ( root, 600, 600 );
		stage.setTitle ( "Hello!" );
		stage.setScene ( scene );
		stage.show ( );
	}
	
	public static void main ( String[] args ) {
		launch ( );
	}
}