package com.alexvasilkov.gestures.animation;

import android.os.Build;
import android.view.View;
import android.view.ViewTreeObserver;

import androidx.annotation.NonNull;

/**
 * Helper class that monitors {@link View} position on screen and notifies
 * {@link OnViewPositionChangeListener} if any changes were detected.
 */
class ViewPositionHolder implements ViewTreeObserver.OnPreDrawListener {

    private final ViewPosition pos = ViewPosition.newInstance();

    private OnViewPositionChangeListener listener;
    private View view;
    private boolean isPaused;

    @Override
    public boolean onPreDraw() {
        update();
        return true;
    }

    void init(@NonNull View view, @NonNull OnViewPositionChangeListener listener) {
        this.view = view;
        this.listener = listener;

        view.getViewTreeObserver().addOnPreDrawListener(this);
        if (isLaidOut()) {
            update();
        }
    }

    void clear() {
        if (view != null) {
            view.getViewTreeObserver().removeOnPreDrawListener(this);
        }

        pos.view.setEmpty();
        pos.viewport.setEmpty();
        pos.image.setEmpty();

        view = null;
        listener = null;
        isPaused = false;
    }

    void pause(boolean paused) {
        if (isPaused == paused) {
            return;
        }

        isPaused = paused;
        update();
    }

    private void update() {
        if (view != null && listener != null && !isPaused) {
            boolean changed = ViewPosition.apply(pos, view);
            if (changed) {
                listener.onViewPositionChanged(pos);
            }
        }
    }

    private boolean isLaidOut() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            return view.isLaidOut();
        } else {
            return view.getWidth() > 0 && view.getHeight() > 0;
        }
    }

    interface OnViewPositionChangeListener {
        void onViewPositionChanged(@NonNull ViewPosition position);
    }

}

@@ -529,24 +529,85 @@
  View view;%0A
+    private View.OnAttachStateChangeListener attachListener;%0A
     private 
@@ -814,123 +814,593 @@
     
-this.view = view;%0A        this.listener = listener;%0A%0A        view.getViewTreeObserver().addOnPreDrawListener(this);
+clear(); // Cleaning up old listeners, just in case%0A%0A        this.view = view;%0A        this.listener = listener;%0A%0A        attachListener = new View.OnAttachStateChangeListener() %7B%0A            @Override%0A            public void onViewAttachedToWindow(View view) %7B%0A                onViewAttached(view, true);%0A            %7D%0A%0A            @Override%0A            public void onViewDetachedFromWindow(View view) %7B%0A                onViewAttached(view, false);%0A            %7D%0A        %7D;%0A        view.addOnAttachStateChangeListener(attachListener);%0A%0A        onViewAttached(view, isAttached(view));%0A
 %0A   
@@ -1418,16 +1418,20 @@
 LaidOut(
+view
 )) %7B%0A   
@@ -1474,118 +1474,394 @@
     
-void clear() %7B%0A        if (view != null) %7B%0A            view.getViewTreeObserver().removeOnPreDrawListener(this
+private void onViewAttached(View view, boolean attached) %7B%0A        view.getViewTreeObserver().removeOnPreDrawListener(this);%0A        if (attached) %7B%0A            view.getViewTreeObserver().addOnPreDrawListener(this);%0A        %7D%0A    %7D%0A%0A    void clear() %7B%0A        if (view != null) %7B%0A            view.removeOnAttachStateChangeListener(attachListener);%0A            onViewAttached(view, false
 );%0A 
@@ -1976,32 +1976,63 @@
    view = null;%0A
+        attachListener = null;%0A
         listener
@@ -2488,32 +2488,39 @@
  %7D%0A%0A    private 
+static 
 boolean isLaidOu
@@ -2521,16 +2521,25 @@
 LaidOut(
+View view
 ) %7B%0A    
@@ -2732,24 +2732,272 @@
    %7D%0A    %7D%0A%0A
+    private static boolean isAttached(View view) %7B%0A        if (Build.VERSION.SDK_INT %3E= Build.VERSION_CODES.KITKAT) %7B%0A            return view.isAttachedToWindow();%0A        %7D else %7B%0A            return view.getWindowToken() != null;%0A        %7D%0A    %7D%0A%0A
     interfac

Fix for potential memory leak (#136)