package brickbreaker;

import javafx.animation.*;
import javafx.scene.*;
import javafx.scene.image.*;
import javafx.scene.input.*;
import javafx.scene.paint.*;
import javafx.scene.shape.*;

/**
 * @author Pavel Porvatov
 */

def STATE_SHOW_TITLE = 0;
def STATE_SHOW_STRIKE = 1;
def STATE_SUN = 2;

def SUN_AMPLITUDE_X = bind Config.screenWidth * 2 / 3;
def SUN_AMPLITUDE_Y = bind Config.screenHeight / 2;

public class Splash extends CustomNode {
    public function start() {
        background.requestFocus();
        
        timeline.play();
    }

    public function stop() {
        timeline.stop();
    }
    
    def background = ImageView {
        image: Config.images[Config.IMAGE_BACKGROUND]
        
        onMousePressed: function( e: MouseEvent ):Void {
            Main.mainFrame.startGame();
        }

        onKeyPressed: function( e: KeyEvent ):Void {
            Main.mainFrame.startGame();
        }
    }

    def brick: ImageView = ImageView {
        image: Config.images[Config.IMAGE_SPLASH_BRICK]
        translateX: -1000
        translateY: bind brick.image.height
    }

    def brickShadow: ImageView = ImageView {
        image: Config.images[Config.IMAGE_SPLASH_BRICKSHADOW]
        opacity: 0
    }

    def breaker = ImageView {
        image: Config.images[Config.IMAGE_SPLASH_BREAKER]
        translateX: -1000
        translateY: brick.translateY + brick.image.height * 5 /4
    }

    def breakerShadow: ImageView = ImageView {
        image: Config.images[Config.IMAGE_SPLASH_BREAKERSHADOW]
        opacity: 0
    }

    def strike: ImageView = ImageView {
        image: Config.images[Config.IMAGE_SPLASH_STRIKE]
        translateY: bind brick.translateY -
            (strike.image.height - brick.image.height) / 2
        visible: false
    }

    def strikeShadow: ImageView = ImageView {
        image: Config.images[Config.IMAGE_SPLASH_STRIKESHADOW]
        opacity: 0
    }

    def pressanykey: ImageView = ImageView {
        def y = breaker.translateY + breaker.image.height;

        image: Config.images[Config.IMAGE_SPLASH_PRESSANYKEY]
        translateX: bind (Config.screenWidth - pressanykey.image.width) / 2
        translateY: y + (Config.screenHeight - y) / 2
        opacity: 0
    }

    def pressanykeyShadow: ImageView = ImageView {
        image: Config.images[Config.IMAGE_SPLASH_PRESSANYKEYSHADOW]
        opacity: 0
    }

    def sun: ImageView = ImageView {
        image: Config.images[Config.IMAGE_SPLASH_SUN]
        translateX: -1000
    }

    def NODES = [
        brick
        breaker
        strike
        pressanykey
    ];

    def NODES_SHADOWS = [
        brickShadow
        breakerShadow
        strikeShadow
        pressanykeyShadow
    ];

    var state = STATE_SHOW_TITLE;

    var stateArg = 0;
        
    def timeline = Timeline {
        repeatCount: Timeline.INDEFINITE
        keyFrames : [
            KeyFrame {
                time: Config.ANIMATION_TIME
                
                action: function () {
                    if (state == STATE_SHOW_TITLE) {
                        stateArg++;

                        var center = Config.screenWidth / 2;
                        var offset = java.lang.Math.cos(stateArg / 4.0) *
                            (40 - stateArg) / 40 * center  as Integer;

                        brick.translateX = center - brick.image.width / 2 + offset;
                        breaker.translateX = center - breaker.image.width / 2 - offset;

                        if (stateArg == 40) {
                            stateArg = 0;
                            state = STATE_SHOW_STRIKE;
                        }

                        return;
                    }
                    
                    if (state == STATE_SHOW_STRIKE) {
                        if (stateArg == 0) {
                            strike.translateX = breaker.translateX +
                                brick.image.width;
                            strike.scaleX = 0;
                            strike.scaleY = 0;
                            strike.visible = true;
                        }

                        stateArg++;

                        var coef = stateArg / 30.0;
                        brick.translateX = breaker.translateX +
                            (breaker.image.width - brick.image.width) / 2.0 *
                            (1 - coef);
                        strike.scaleX = coef;
                        strike.scaleY = coef;
                        strike.rotate = (30 - stateArg) * 2;

                        if (stateArg == 30) {
                            stateArg = 0;
                            state = STATE_SUN;
                        }

                        return;
                    }

                    // Here state == STATE_SUN
                    if (pressanykey.opacity < 1) {
                        pressanykey.opacity += 0.05
                    }

                    stateArg--;

                    var x = SUN_AMPLITUDE_X * java.lang.Math.cos(stateArg / 100.0);
                    var y = SUN_AMPLITUDE_Y * java.lang.Math.sin(stateArg / 100.0);

                    if (y < 0) {
                        for (node in NODES_SHADOWS) {
                            node.opacity = 0;
                        }

                        return;
                    }

                    var sunX = Config.screenWidth / 2 + x;
                    var sunY = Config.screenHeight / 2 - y;
            
                    sun.translateX = sunX - sun.image.width / 2;
                    sun.translateY = sunY - sun.image.height / 2;
                    sun.rotate = -stateArg;

                    for (i in [0..< sizeof NODES]) {
                        NODES_SHADOWS[i].opacity = y / SUN_AMPLITUDE_Y / 2;

                        NODES_SHADOWS[i].translateX = NODES[i].translateX +
                            (NODES[i].translateX + NODES[i].image.width / 2 - sunX) / 20;

                        NODES_SHADOWS[i].translateY = NODES[i].translateY +
                            (NODES[i].translateY + NODES[i].image.height / 2 - sunY) / 20;
                    }
                }
            }
        ]
    }

    override public function create(): Node {
        Group {
            content: [
                background

                NODES_SHADOWS

                NODES

                sun
            ]
        };
    }
}