import javafx.application.Application;
import javafx.animation.Timeline;
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.scene.AmbientLight;
import javafx.scene.Group;
import javafx.scene.PerspectiveCamera;
import javafx.scene.PointLight;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Sphere;
import javafx.scene.transform.Rotate;
import javafx.scene.transform.Translate;
import javafx.stage.Stage;
import javafx.util.Duration;

public class Hello3d extends Application {

    private final Image earthImage = new Image(
        getClass().getResourceAsStream("physical-free-world-map-b1.jpg")
    );

    // TODO: あとでクラス化する
    private final Rotate cameraRotateX = new Rotate(0, Rotate.X_AXIS);
    private final Rotate cameraRotateY = new Rotate(0, Rotate.Y_AXIS);
    private final Rotate cameraRotateZ = new Rotate(0, Rotate.Z_AXIS);
    private final Translate cameraTranslate = new Translate(0, 0, -200);

    @Override
    public void start(final Stage stage) {
	final Group root = new Group();

	// 球体の定義
	final Sphere earth = new Sphere(100);
	root.getChildren().add(earth);

	// 材質の定義
        final PhongMaterial material = new PhongMaterial();
        material.setDiffuseMap(earthImage);
        earth.setMaterial(material);

	// カメラの定義
        final PerspectiveCamera camera = new PerspectiveCamera(true);
        camera.setFieldOfView(60);
        camera.setFarClip(1000);
        camera.getTransforms().addAll(
            cameraRotateX,
            cameraRotateY,
            cameraRotateZ,
	    cameraTranslate
        );

        // 点光源の定義
        final PointLight pointLight = new PointLight(Color.WHITE);
        pointLight.setTranslateX(500);
        pointLight.setTranslateY(0);
        pointLight.setTranslateZ(-500);
        root.getChildren().add(pointLight);

        // 環境光の定義
        final AmbientLight ambientLight = new AmbientLight(Color.rgb(80, 80, 80, 0.5));
        root.getChildren().add(ambientLight);

        final Scene scene = new Scene(root, 800, 600, Color.BLACK);
        scene.setCamera(camera);

        // アニメーション定義
	// カメラを0度から-90度まで回転させる
	// 次にZ軸に沿って-200固定で移動させる
        final Timeline animation = new Timeline();
        animation.getKeyFrames().addAll(
            new KeyFrame(Duration.ZERO,
                         new KeyValue(cameraRotateY.angleProperty(), 0)
            ),
            new KeyFrame(Duration.millis(3000),
                         new KeyValue(cameraRotateY.angleProperty(), -90)
            )
        );

        stage.setScene(scene);
        stage.setTitle("Hello JavaFX 3D World");
        stage.show();
        
        root.setOnMouseClicked(event -> animation.play());
    }

    public static void main(final String... args) {
        launch(args);
    }
}
