/* 
 * 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.
 */

package podcastfeedviewer.media;

import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.scene.*;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.*;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.text.TextOrigin;
import podcastfeedviewer.Main;

/**
 * @author baechul
 */

def FRAME_RATE = 10;

public class BufferSpinner extends CustomNode {
    public-init var parentNode: Node;
    public var radius: Number;

    public var backColor = Color.BLACK;
    public var fillColor = Color.rgb(10, 138, 232);
    public var labelColor = Color.WHITE;
    public var gapBetweenArcs = bind Main.buttonGap;
    public var bandThick: Number = 14;
    public-read var isRunning = bind t.running;

    var opacities: Number[];
    public var numArcs = 16 on replace {
        var n = 1.0 / numArcs;
        for(i in [1..numArcs]) {
            insert i * n into opacities;
        }
        opacities = reverse opacities;
    }

    var base:Integer = 0;

    var t: Timeline = Timeline {
        repeatCount: Timeline.INDEFINITE;
        keyFrames: [
            KeyFrame {
                time: (1000ms / FRAME_RATE);
                action: function() {
                    base++;
                    if(base == numArcs)
                        base = 0;
                }
                canSkip: true;
            }
        ]
    }

    public function play(): Void {
        parentNode.opacity = 0.3;
        this.opacity = 1.0;
        if(not t.running) t.play();
    }

    public function stop(): Void {
        parentNode.opacity = 1.0;
        this.opacity = 0.0;
        if(t.running) t.stop();
    }

    var backArcs: Shape[] = createBand(numArcs, gapBetweenArcs, backColor, false);
    var bandArcs: Shape[] = createBand(numArcs, gapBetweenArcs, fillColor, true);

    function createBand(numArcs:Number, gap:Number,
    fillColor:Paint, linearOpacity:Boolean):Shape[] {
        var arcs: Shape[];
        var start = 0.0;
        var length = (360 - numArcs * gap)/numArcs;

        for(i in [0..(numArcs-1)]) {
            start = (length + gap) * i;
            var arc:Shape = createBandArc(i, radius, radius, radius,
            start, length, fillColor, linearOpacity);
            insert arc into arcs;
        }
        return arcs;
    }

    function createBandArc(index:Integer, centerX:Number, centerY:Number, radius:Number,
    start:Number, length:Number, fillColor:Paint, linearOpacity:Boolean): Shape {
        var outer = Arc {
            centerX: centerX  centerY: centerY
            radiusX: radius  radiusY: radius
            startAngle: start
            length: length
            type: ArcType.ROUND
        }

        var inner = Arc {
            centerX: centerX  centerY: centerY
            radiusX: radius - bandThick  radiusY: radius - bandThick
            startAngle: start
            length: length
            type: ArcType.ROUND
        }

        def id = index;
        ShapeSubtract {
            a: outer
            b: inner
            fill: fillColor
            opacity: bind if(linearOpacity) opacities[(base+id) mod numArcs] else 1.0
        }
    }

    var label: Text = Text {
        content: "Parsing FeedURL..."
        textOrigin: TextOrigin.TOP

        translateX: bind (2 * radius - label.boundsInLocal.width) / 2.0
        translateY: bind 2 * radius + 10 //bind (2 * radius - label.boundsInLocal.height) / 2.0 + 2
        font: Font{ name: "Arial Bold" size: 12 }
        fill: labelColor
    }

    postinit {
        this.opacity = 0.0;
    }

    override function create(): Group {
        Group {
            content: [
                backArcs,
                bandArcs,
                label
            ]
        }
    }
}