package fractaltree;

import javafx.animation.*;
import javafx.scene.*;
import javafx.scene.paint.*;
import javafx.scene.transform.*;
import javafx.scene.shape.*;

public class RecursiveTree extends CustomNode {
    public var x = 0;
    public var y = 100;
    public var startDepth: Number = 3;
    public var leftFactor = 1.12;
    public var rightFactor = 1.6;
    public var leftAngle = 20.0;
    public var rightAngle = -45.0;
    public-init var maxAngle = 30.0;
    public var angle = 0.0;
    public var segmentLength = 15.0;
    public-init var cycleLength:Duration = 5s;
    
    public-read var anim = Timeline {
        repeatCount: Timeline.INDEFINITE
        keyFrames: [
            KeyFrame { time: 0s values: angle => 0 tween Interpolator.EASEBOTH},
            KeyFrame { time: cycleLength/4 values: angle => -maxAngle tween Interpolator.EASEBOTH},
            KeyFrame { time: cycleLength/4*2 values: angle => 0 },
            KeyFrame { time: cycleLength/4*3 values: angle => maxAngle tween Interpolator.EASEBOTH},
            KeyFrame { time: cycleLength/4*4 values: angle => 0  tween Interpolator.EASEBOTH},
            KeyFrame { time: cycleLength+2s values: angle => 0},
        ]
    };

    override public function create():Node {
        return Group {
            translateX: bind x
            translateY: bind y
            content: [
                create(startDepth,1)
            ]
        }
    }
    
    function create(depth:Number, angleAdjust:Number):Node {
        var adj = angleAdjust;
        var color = (depth*255/startDepth);
        var g = Group {
            transforms:  bind Transform.rotate(angle+adj, 0, 0),
            content: Line { 
                startX:0 startY:0 endX:0 endY:-depth*segmentLength
                stroke: Color.rgb(0,0,color)
            }
        };
        
        // recurse
        if(depth >= 1) {
            insert Group {
                transforms: Transform.translate(0,-depth*segmentLength)
                content: [
                    create(depth/leftFactor, leftAngle),
                    create(depth/rightFactor, rightAngle)
                ]
            } into g.content;
        }
        
        return g;
    }
}