package skadistats.clarity.analyzer.replay;

import javafx.application.Platform;
import skadistats.clarity.processor.runner.ControllableRunner;
import skadistats.clarity.source.Source;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.IOException;
import java.util.concurrent.locks.ReentrantLock;

public class PropertySupportRunner extends ControllableRunner {

    private final PropertyChangeSupport changes = new PropertyChangeSupport(this);

    public PropertySupportRunner(Source s) throws IOException {
        super(s);
    }

    public void addPropertyChangeListener(PropertyChangeListener l) {
        changes.addPropertyChangeListener(l);
    }

    public void removePropertyChangeListener(PropertyChangeListener l) {
        changes.removePropertyChangeListener(l);
    }


    private final ReentrantLock notificationLock = new ReentrantLock();
    private int notificationOldTick = Integer.MIN_VALUE;
    private int notificationTick = 0;

    private void commitNotification() {
        notificationLock.lock();
        try {
            changes.firePropertyChange("tick", notificationOldTick, notificationTick);
            notificationOldTick = Integer.MIN_VALUE;
        } finally {
            notificationLock.unlock();
        }
    }

    @Override
    protected void setTick(int tick) {
        notificationLock.lock();
        try {
            if (notificationOldTick != Integer.MIN_VALUE) {
                super.setTick(tick);
                notificationTick = tick;
            } else {
                notificationOldTick = getTick();
                super.setTick(tick);
                notificationTick = tick;
                Platform.runLater(this::commitNotification);
            }
        } finally {
            notificationLock.unlock();
        }
    }

}

@@ -179,16 +179,62 @@
 ource;%0A%0A
+import javax.annotation.processing.Processor;%0A
 import j
@@ -1885,10 +1885,152 @@
 %0A    %7D%0A%0A
+    public PropertySupportRunner runWith(Processor... processors) %7B%0A        super.runWith((Object%5B%5D)processors);%0A        return this;%0A    %7D%0A%0A%0A
 %7D%0A

remove generic self referential type T for runners