package com.annimon.hotarufx.visual.objects;

import com.annimon.hotarufx.visual.PropertyBindings;
import com.annimon.hotarufx.visual.PropertyTimeline;
import com.annimon.hotarufx.visual.PropertyTimelineHolder;
import com.annimon.hotarufx.visual.TimeLine;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Shape;
import static com.annimon.hotarufx.visual.PropertyType.*;

public abstract class ShapeNode extends ObjectNode {

    private final Shape shape;

    private PropertyTimelineHolder<Paint> fill, stroke;

    public ShapeNode(Shape shape) {
        super(shape);
        this.shape = shape;
        fill = PropertyTimelineHolder.empty();
        stroke = PropertyTimelineHolder.empty();
    }

    public PropertyTimeline<Paint> fillProperty() {
        return fill.setIfEmptyThenGet(shape::fillProperty);
    }

    public PropertyTimeline<Paint> strokeProperty() {
        return stroke.setIfEmptyThenGet(shape::strokeProperty);
    }

    @Override
    public void buildTimeline(TimeLine timeline) {
        super.buildTimeline(timeline);
        fill.applyIfPresent(timeline);
        stroke.applyIfPresent(timeline);
    }

    @Override
    public PropertyBindings propertyBindings(PropertyBindings bindings) {
        return super.propertyBindings(bindings)
                .add("fill", PAINT, this::fillProperty)
                .add("stroke", PAINT, this::strokeProperty);
    }
}

@@ -499,27 +499,171 @@
 der%3C
-Paint%3E fill, stroke
+Boolean%3E smooth;%0A    private PropertyTimelineHolder%3CPaint%3E fill, stroke;%0A    private PropertyTimelineHolder%3CNumber%3E strokeWidth, strokeDashOffset, strokeMiterLimit
 ;%0A%0A 
@@ -747,16 +747,65 @@
  shape;%0A
+        smooth = PropertyTimelineHolder.empty();%0A
         
@@ -900,237 +900,989 @@
     
-%7D%0A%0A    public PropertyTimeline%3CPaint%3E fillProperty() %7B%0A        return fill.setIfEmptyThenGet(shape::fillProperty);%0A    %7D%0A%0A    public PropertyTimeline%3CPaint%3E strokeProperty() %7B%0A        return stroke.setIfEmptyThenGet(shape::stroke
+    strokeWidth = PropertyTimelineHolder.empty();%0A        strokeDashOffset = PropertyTimelineHolder.empty();%0A        strokeMiterLimit = PropertyTimelineHolder.empty();%0A    %7D%0A%0A    public PropertyTimeline%3CBoolean%3E smoothProperty() %7B%0A        return smooth.setIfEmptyThenGet(shape::smoothProperty);%0A    %7D%0A%0A    public PropertyTimeline%3CPaint%3E fillProperty() %7B%0A        return fill.setIfEmptyThenGet(shape::fillProperty);%0A    %7D%0A%0A    public PropertyTimeline%3CPaint%3E strokeProperty() %7B%0A        return stroke.setIfEmptyThenGet(shape::strokeProperty);%0A    %7D%0A%0A    public PropertyTimeline%3CNumber%3E strokeWidthProperty() %7B%0A        return strokeWidth.setIfEmptyThenGet(shape::strokeWidthProperty);%0A    %7D%0A%0A    public PropertyTimeline%3CNumber%3E strokeDashOffsetProperty() %7B%0A        return strokeDashOffset.setIfEmptyThenGet(shape::strokeDashOffsetProperty);%0A    %7D%0A%0A    public PropertyTimeline%3CNumber%3E strokeMiterLimitProperty() %7B%0A        return strokeMiterLimit.setIfEmptyThenGet(shape::strokeMiterLimit
 Prop
@@ -1991,32 +1991,73 @@
 line(timeline);%0A
+        smooth.applyIfPresent(timeline);%0A
         fill.app
@@ -2116,24 +2116,172 @@
 (timeline);%0A
+        strokeWidth.applyIfPresent(timeline);%0A        strokeDashOffset.applyIfPresent(timeline);%0A        strokeMiterLimit.applyIfPresent(timeline);%0A
     %7D%0A%0A    @
@@ -2411,16 +2411,78 @@
 ndings)%0A
+                .add(%22smooth%22, BOOLEAN, this::smoothProperty)%0A
         
@@ -2580,26 +2580,259 @@
 :strokeProperty)
+%0A                .add(%22strokeWidth%22, NUMBER, this::strokeWidthProperty)%0A                .add(%22strokeDashOffset%22, NUMBER, this::strokeDashOffsetProperty)%0A                .add(%22strokeMiterLimit%22, NUMBER, this::strokeMiterLimitProperty)
 ;%0A    %7D%0A%7D%0A

Add shape properties