import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.SVGPath;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class AnimationTimerApp extends Application {

	private final BorderPane root = new BorderPane();

	private final Text fpsText = new Text("FPS:");

	private final Text frameRateText = new Text();

	private final Supplier<SVGPath> svgPathSupplier = () -> {
        SVGPath svgPath = new SVGPath();
        svgPath.setContent("M15,0l-0.9,1.5v31.7l0.9,1.5l0.9-1.5V1.5L15,0z M15,7.5l-3.5-2.3V3.5L15,5.8V7.5z M15,11l-4.6-2.9V6.4L15,9.3V11z M15,7.5l3.5-2.3V3.5L15,5.8V7.5z M15,11l4.6-2.9V6.4L15,9.3V11z M15,27.1l-3.5,2.3v1.7l3.5-2.3V27.1z M15,23.7l-4.6,2.9v1.7l4.6-2.9V23.7z M15,27.1l3.5,2.3v1.7L15,28.8V27.1z M15,23.7l4.6,2.9v1.7L15,25.4V23.7z M0,26h1.7l27.4-15.8L30,8.7h-1.7L0.9,24.5L0,26z M6.5,22.2l-0.3,4.1l-1.5,0.9L5,23.1L6.5,22.2z M9.5,20.5l-0.2,5.4l-1.5,0.9L8,21.4L9.5,20.5z M6.5,22.2l-3.7-1.8l-1.5,0.9L5,23.1L6.5,22.2z M9.5,20.5L4.7,18l-1.5,0.9L8,21.4L9.5,20.5z M23.5,12.4l3.7,1.8l1.5-0.9L25,11.6L23.5,12.4z M20.5,14.2l4.8,2.6l1.5-0.9L22,13.3L20.5,14.2z M23.5,12.4l0.3-4.1l1.5-0.9L25,11.6L23.5,12.4z M20.5,14.2l0.2-5.4l1.5-0.9L22,13.3L20.5,14.2z M30,26h-1.7L0.9,10.2L0,8.7h1.7l27.4,15.8L30,26z M23.5,22.2l0.3,4.1l1.5,0.9L25,23.1L23.5,22.2z M20.5,20.5l0.2,5.4l1.5,0.9L22,21.4L20.5,20.5z M23.5,22.2l3.7-1.8l1.5,0.9L25,23.1L23.5,22.2z M20.5,20.5l4.8-2.5l1.5,0.9L22,21.4L20.5,20.5z M6.5,12.4l-3.7,1.8l-1.5-0.9L5,11.6L6.5,12.4z M9.5,14.2l-4.8,2.6l-1.5-0.9L8,13.3L9.5,14.2z M6.5,12.4L6.3,8.3L4.8,7.4L5,11.6L6.5,12.4z M9.5,14.2L9.3,8.8L7.8,7.9L8,13.3L9.5,14.2z M15,22.8l-4.7-2.7v-5.4l4.7-2.7l4.7,2.7V20L15,22.8z M11.7,19.2l3.3,1.9l3.3-1.9v-3.7L15,13.6l-3.3,1.9V19.2z");
        svgPath.setFill(Color.SNOW);return svgPath;};

	private final int svgPathCapacity = 500;
	private final List<SVGPath> svgPathList = new ArrayList<>(svgPathCapacity);

	private final AnimationTimer animationTimer=new AnimationTimer(){

	
	private long lastTime;

	
	private int handleCount;

	@Override public void handle(long now){
	
	computeFPS(now);double rootHeight=root.getHeight();double width=root.getWidth()-30.0;svgPathList.forEach(svgPath->{double translateY=svgPath.getTranslateY();
	
	if(translateY>=rootHeight){svgPath.setRotate(0.0);svgPath.setTranslateX(Math.random()*width);svgPath.setTranslateY(0.0);double scale=Math.random()+0.1;svgPath.setScaleX(scale);svgPath.setScaleY(scale);return;}svgPath.setTranslateY(translateY+1.0);svgPath.setRotate(svgPath.getRotate()+1.0);});}

	private void computeFPS(long now){
	
	long elapsedTime=now-lastTime;long seconds=elapsedTime/1_000_000_000;
	
	if(seconds>=1L){
	
	frameRateText.setText(String.valueOf(handleCount/seconds));handleCount=0;
	
	lastTime=now;}handleCount++;}

	};

	public static void main(String[] args) {
		Application.launch(args);
	}

	@Override
	public void init() throws Exception {
		fpsLayout();
	}

	private void fpsLayout() {
		fpsText.setFont(Font.font(30.0));
		fpsText.setFill(Color.WHITE);
		frameRateText.setFont(Font.font(30.0));
		frameRateText.setFill(Color.WHITE);
		HBox fpsHBox = new HBox(10.0, fpsText, frameRateText);
		fpsHBox.setMaxSize(0.0, 0.0);
		BorderPane.setAlignment(fpsHBox, Pos.TOP_RIGHT);
		root.setTop(fpsHBox);
	}

	public void start(Stage primaryStage) throws Exception {
		primaryStage.setTitle(getClass().getSimpleName());
		
		primaryStage.initStyle(StageStyle.TRANSPARENT);
		
		primaryStage.setMaximized(true);
		
		primaryStage.setAlwaysOnTop(true);
		primaryStage.setScene(new Scene(root, null));
		primaryStage.show();

		double width = root.getWidth() - 30.0;
		double height = root.getHeight();
		for (int i = 0; i < svgPathCapacity; i++) {
			SVGPath svgPath = svgPathSupplier.get();
			svgPath.setTranslateX(Math.random() * width);
			svgPath.setTranslateY(Math.random() * height);
			double scale = Math.random() + 0.1;
			svgPath.setScaleX(scale);
			svgPath.setScaleY(scale);
			svgPathList.add(svgPath);
		}
		root.setCenter(new Pane(svgPathList.toArray(new SVGPath[0])));
		animationTimer.start();
	}
}