package com.example.demo;

import javafx.animation.*;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Scale;
import javafx.scene.transform.Transform;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.io.IOException;
import java.security.Key;
import java.util.Collection;
import java.util.Iterator;
import java.util.Timer;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TransferQueue;

public class HelloApplication extends Application {
    private static Group createArm ( ) {
        Group arm = new Group();

        Group current = arm;
        for ( int i = 0; i < 4; ++i ) {
            Circle circle = new Circle ( 20, Color.RED );
            current.getChildren( ).add ( circle );

            current.getTransforms( ).addAll(
                    new Rotate ( 20 ),
                    new Translate ( 20, 0 ),
                    new Scale ( 1.25, 1.25 ),
                    new Translate ( 20, 0 )
            );

            Group next = new Group ( );
            current.getChildren ( ).add ( next );
            current = next;
        }

        return arm;
    }

    private static Group createSpiral ( ) {
        Group spiral = new Group ( );

        Circle center = new Circle ( 20, Color.RED );

        spiral.getChildren ( ).addAll ( center );

        for ( int i = 0; i < 6; ++i ) {
            Group arm = new Group( createArm ( ) );
            arm.getTransforms ( ).add ( new Rotate ( i * 60 ) );
            spiral.getChildren ( ).add ( arm );
        }

        Rotate rotate = new Rotate ( );
        spiral.getTransforms ( ).add ( rotate );

        Timeline animation = new Timeline (
                new KeyFrame ( Duration.ZERO, new KeyValue ( rotate.angleProperty ( ), 0, Interpolator.LINEAR ) ),
                new KeyFrame ( Duration.seconds ( 3 ), new KeyValue ( rotate.angleProperty ( ), 360, Interpolator.LINEAR ) )
        );
        animation.setCycleCount ( Animation.INDEFINITE );
        animation.play ( );


        return new Group ( spiral );
    }

    private static Group createPendulum ( ) {
        Group pendulum = new Group ( );

        Rectangle base = new Rectangle ( 20, 400, Color.BLACK );
        base.getTransforms ( ).add ( new Translate ( -10, 0 ) );

        Circle redWeight = new Circle ( 60, Color.RED );
        redWeight.getTransforms ( ).add ( new Translate ( 0, 400 ) );

        Circle blackWeight = new Circle ( 30, Color.BLACK );
        blackWeight.getTransforms ( ).add ( new Translate ( 0, 400 ) );

        pendulum.getChildren ( ).addAll ( base, redWeight, blackWeight );

        Rotate rotate = new Rotate ( );

        pendulum.getTransforms ( ).addAll (
               new Translate ( 300, 0 ),
                rotate
        );

        Timeline animation = new Timeline (
                new KeyFrame ( Duration.ZERO, new KeyValue ( rotate.angleProperty ( ), -20, Interpolator.EASE_BOTH ) ),
                new KeyFrame ( Duration.seconds ( 4 ), new KeyValue ( rotate.angleProperty ( ), 20, Interpolator.EASE_BOTH ) )
        );
        animation.setCycleCount ( Animation.INDEFINITE );
        animation.setAutoReverse ( true );
        animation.play ( );

        return new Group ( pendulum );
    }

    @Override
    public void start(Stage stage) throws IOException {
        Group pendulum = createPendulum ( );
        Scene scene = new Scene(pendulum, 600, 600);

        scene.addEventHandler (KeyEvent.ANY, keyEvent -> {
            boolean isReleased = keyEvent.getEventType().equals(KeyEvent.KEY_RELEASED);
            if ( isReleased ) {
                switch ( keyEvent.getCode( ) ) {
                    case UP: {

                    }
                    case DOWN: {

                    }
                }
            }
        });

        scene.addEventHandler (MouseEvent.ANY, mouseEvent -> {
            boolean mouseMoved = mouseEvent.getEventType ( ).equals ( MouseEvent.MOUSE_MOVED );
            if ( mouseMoved ) {
                double x = mouseEvent.getSceneX ( );
                double y = mouseEvent.getSceneY ( );
                System.out.println ( x + " " + y );
            }
        });

        stage.setTitle("Hello!");
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }
}