/* 
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. 
 * 
 * This file is available and licensed under the following license:
 * 
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 *
 *   * Redistributions of source code must retain the above copyright notice, 
 *     this list of conditions and the following disclaimer.
 *
 *   * Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *
 *   * Neither the name of Sun Microsystems nor the names of its contributors 
 *     may be used to endorse or promote products derived from this software 
 *     without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
import javafx.animation.Interpolator;
import javafx.animation.Timeline;

import javafx.scene.Cursor;
import javafx.scene.Scene;
import javafx.scene.layout.Panel;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.text.TextOrigin;

import javafx.stage.Stage;
import javafx.stage.StageStyle;

import javafx.util.Math.min;
import javafx.util.Math.random;

/**
 * @author Sergey A. Malenkov
 */

def anim = Timeline { }
def text = "JavaFX";
def chars = for (i in [1..text.length()]) Text {
  textOrigin: TextOrigin.TOP
  content: text.substring(i - 1, i)
  strokeWidth: 2
  stroke: Color.BLUE
  fill: Color.YELLOW
}

def panel: Panel = Panel {
  content: chars
  cursor: bind if (anim.running)
          then Cursor.DEFAULT
          else Cursor.HAND
  onMouseClicked: function (event) {
    if (not anim.running) {
      anim.keyFrames = for (node in chars) {
        def i1 = Interpolator.SPLINE(random(), random(), random(), random());
        def i2 = Interpolator.SPLINE(random(), random(), random(), random());
    
        def op1 = node.opacity;      def op2 = 0.0;
        def sx1 = node.scaleX;       def sx2 = 0.0;
        def sy1 = node.scaleY;       def sy2 = 0.0;
        def tx1 = node.translateX;   def tx2 = random() * node.scene.width;
        def ty1 = node.translateY;   def ty2 = random() * node.scene.height;
        def ro1 = node.rotate;       def ro2 = random() * 2880 - 1440;
        [
          at (3s) {
            node.opacity    => op2 tween i2;
            node.scaleX     => sx2 tween i2;
            node.scaleY     => sy2 tween i2;
            node.translateX => tx2 tween i2;
            node.translateY => ty2 tween i2;
            node.rotate     => ro2 tween i2;
            node.stroke     => Color.color(random(), random(), random()) tween Interpolator.DISCRETE;
            node.fill       => Color.color(random(), random(), random()) tween Interpolator.DISCRETE;
          }
          at (6s) {
            node.opacity    => op1 tween i1;
            node.scaleX     => sx1 tween i1;
            node.scaleY     => sy1 tween i1;
            node.translateX => tx1 tween i1;
            node.translateY => ty1 tween i1;
            node.rotate     => ro1 tween i1;
          }
        ]
      }
      anim.playFromStart()
    }
  }
  var width:  Number;
  var height: Number;
  onLayout: function () {
    if (not anim.running and (panel.scene.width != width or panel.scene.height != height)) {
      def font = Font {
        size: min(1.5 * panel.scene.width / text.length(), panel.scene.height)
      }
      for (node in chars) {
        node.font = font
      }
      width  = 0;
      height = 0;
      for (node in chars) {
        node.translateX = width;
        width += node.boundsInLocal.width;
        if (height < node.boundsInLocal.height) {
          height = node.boundsInLocal.height
        }
      }
      width  = .5 * (panel.scene.width  - width);
      height = .5 * (panel.scene.height - height);
      for (node in chars) {
        node.translateX += width;
        node.translateY = height;
      }
      width  = panel.scene.width;
      height = panel.scene.height;
    }
  }
}

Stage {
  title: "Flying Letters (JavaFX sample)"
  style: StageStyle.TRANSPARENT
  scene: Scene {
    fill: null
    width: 600
    height: 400
    content: panel
  }
}

def w = bind panel.scene.width  on replace { panel.onLayout() }
def h = bind panel.scene.height on replace { panel.onLayout() }