package com.nirhart.parallaxscroll.views;

import android.annotation.SuppressLint;
import android.graphics.Rect;
import android.os.Build;
import android.view.View;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

public abstract class ParallaxedView {
    private static boolean isAPI11 = Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
    private static boolean isAPI18 = Build.VERSION.SDK_INT >= 18;
    protected WeakReference<View> view;
    protected int lastOffset;
    protected List<Animation> animations;
    protected Rect clippingRect = new Rect();
    protected boolean firstRectGet = false;
    private int lastScrollY;

    abstract protected void translatePreICS(View view, float offset);

    public ParallaxedView(View view) {
        this.lastOffset = 0;
        this.animations = new ArrayList<Animation>();
        this.view = new WeakReference<View>(view);
    }

    public boolean is(View v) {
        return (v != null && view != null && view.get() != null && view.get().equals(v));
    }

    @SuppressLint("NewApi")
    public void setOffset(float offset) {
        View view = this.view.get();
        if (view != null)
            if (isAPI11) {
                view.setTranslationY(offset);
            } else {
                translatePreICS(view, offset);
            }
    }

    @SuppressLint("NewApi")
    public void setOffset(float offset, int originalScrollY) {
        View view = this.view.get();
        if (view != null)
            if (isAPI11) {
                if (!firstRectGet) {
                    clippingRect.top = view.getTop();
                    clippingRect.left = view.getLeft();
                    clippingRect.right = view.getRight();
                    clippingRect.bottom = view.getBottom();
                    firstRectGet = true;
                }
                if (lastScrollY == 0) {
                    lastScrollY = originalScrollY;
                }
                int delta = lastScrollY - originalScrollY;
                clippingRect.bottom += delta;
                view.setTranslationY(Math.round(offset));
                if (isAPI18) view.setClipBounds(clippingRect);
                lastScrollY = originalScrollY;
                if (isAPI18) {
                    if (clippingRect.bottom <= clippingRect.top) {
                        view.setVisibility(View.INVISIBLE);
                    } else {
                        view.setVisibility(View.VISIBLE);
                    }
                }
            } else {
                translatePreICS(view, offset);
            }
    }

    public void setAlpha(float alpha) {
        View view = this.view.get();
        if (view != null)
            if (isAPI11) {
                view.setAlpha(alpha);
            } else {
                alphaPreICS(view, alpha);
            }
    }

    protected synchronized void addAnimation(Animation animation) {
        animations.add(animation);
    }

    protected void alphaPreICS(View view, float alpha) {
        addAnimation(new AlphaAnimation(alpha, alpha));
    }

    protected synchronized void animateNow() {
        View view = this.view.get();
        if (view != null) {
            AnimationSet set = new AnimationSet(true);
            for (Animation animation : animations)
                if (animation != null)
                    set.addAnimation(animation);
            set.setDuration(0);
            set.setFillAfter(true);
            view.setAnimation(set);
            set.start();
            animations.clear();
        }
    }

    public void setView(View view) {
        this.view = new WeakReference<View>(view);
    }
}