/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.uirendering.cts.testclasses;

import static org.junit.Assert.assertEquals;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Picture;
import android.graphics.Rect;
import android.os.Handler;
import android.uirendering.cts.R;
import android.uirendering.cts.bitmapcomparers.MSSIMComparer;
import android.uirendering.cts.bitmapverifiers.BitmapVerifier;
import android.uirendering.cts.bitmapverifiers.ColorCountVerifier;
import android.uirendering.cts.bitmapverifiers.RectVerifier;
import android.uirendering.cts.testinfrastructure.ActivityTestBase;
import android.uirendering.cts.testinfrastructure.ViewInitializer;
import android.view.FrameMetrics;
import android.view.View;
import android.view.ViewAnimationUtils;
import android.view.Window;
import android.widget.FrameLayout;

import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.Arrays;

@LargeTest
@RunWith(AndroidJUnit4.class)
public class BitmapTests extends ActivityTestBase {
    class BitmapView extends View {
        private Bitmap mBitmap;
        private int mColor;

        public BitmapView(Context context) {
            super(context);
            mBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
            setColor(Color.BLUE);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawBitmap(mBitmap, new Rect(0, 0, 1, 1), canvas.getClipBounds(), null);
        }

        public void setColor(int color) {
            mColor = color;
            mBitmap.setPixel(0, 0, color);
        }

        public int getColor() {
            return mColor;
        }
    }

    /*
     * The following test verifies that bitmap changes during render thread animation won't
     * be visible: we changed a bitmap from blue to red during circular reveal (an RT animation),
     * and changed it back to blue before the end of the animation; we should never see any
     * red pixel.
     */
    @Test
    public void testChangeDuringRtAnimation() {
        class RtOnlyFrameCounter implements Window.OnFrameMetricsAvailableListener {
            private int count = 0;

            @Override
            public void onFrameMetricsAvailable(Window window, FrameMetrics frameMetrics,
                    int dropCountSinceLastInvocation) {
                if (frameMetrics.getMetric(FrameMetrics.ANIMATION_DURATION) == 0
                        && frameMetrics.getMetric(FrameMetrics.INPUT_HANDLING_DURATION) == 0
                        && frameMetrics.getMetric(FrameMetrics.LAYOUT_MEASURE_DURATION) == 0) {
                    count++;
                };
            }

            public boolean isLargeEnough() {
                return count >= 5;
            }
        }

        RtOnlyFrameCounter counter = new RtOnlyFrameCounter();

        ViewInitializer initializer = new ViewInitializer() {
            Animator mAnimator;

            @Override
            public void initializeView(View view) {
                FrameLayout root = (FrameLayout) view.findViewById(R.id.frame_layout);

                final BitmapView child = new BitmapView(view.getContext());
                child.setLayoutParams(new FrameLayout.LayoutParams(50, 50));
                root.addView(child);

                mAnimator = ViewAnimationUtils.createCircularReveal(child, 0, 0, 0, 90);
                mAnimator.setDuration(3000);
                mAnimator.start();

                Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        child.setColor(Color.RED);
                        try {
                            Thread.sleep(1000);
                        } catch (Exception e) {
                            // do nothing
                        }
                        child.setColor(Color.BLUE);
                    }
                }, 1000);
                getActivity().getWindow().addOnFrameMetricsAvailableListener(counter, handler);
            }

            @Override
            public void teardownView() {
                mAnimator.cancel();
                getActivity().getWindow().removeOnFrameMetricsAvailableListener(counter);
            }
        };

        createTest()
                .addLayout(R.layout.frame_layout, initializer, true)
                .runWithAnimationVerifier(new ColorCountVerifier(Color.RED, 0));

        Assert.assertTrue(counter.isLargeEnough());
    }

    /*
     * The following test verifies that bitmap changes during UI thread animation are
     * visible: we keep changing a bitmap's color between red and blue in sync with the
     * background, and we should only see pure blue or red.
    */
    @Test
    public void testChangeDuringUiAnimation() {
        class BlueOrRedVerifier extends BitmapVerifier {
            @Override
            public boolean verify(int[] bitmap, int offset, int stride, int width, int height) {
                MSSIMComparer comparer = new MSSIMComparer(0.99);
                int[] red  = new int[offset + height * stride];
                Arrays.fill(red, Color.RED);
                int[] blue  = new int[offset + height * stride];
                Arrays.fill(blue, Color.BLUE);
                boolean isRed = comparer.verifySame(red, bitmap, offset, stride, width, height);
                boolean isBlue = comparer.verifySame(blue, bitmap, offset, stride, width, height);
                return isRed || isBlue;
            }
        }

        ViewInitializer initializer = new ViewInitializer() {
            ValueAnimator mAnimator;

            @Override
            public void initializeView(View view) {
                FrameLayout root = (FrameLayout) view.findViewById(R.id.frame_layout);
                root.setBackgroundColor(Color.BLUE);

                final BitmapView child = new BitmapView(view.getContext());

                // The child size is strictly less than the test canvas size,
                // and we are moving it up and down inside the canvas.
                child.setLayoutParams(new FrameLayout.LayoutParams(ActivityTestBase.TEST_WIDTH / 2,
                        ActivityTestBase.TEST_HEIGHT / 2));
                root.addView(child);
                child.setColor(Color.BLUE);

                mAnimator = ValueAnimator.ofInt(0, ActivityTestBase.TEST_HEIGHT / 2);
                mAnimator.setRepeatMode(mAnimator.REVERSE);
                mAnimator.setRepeatCount(mAnimator.INFINITE);
                mAnimator.setDuration(400);
                mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        int v = (Integer) mAnimator.getAnimatedValue();
                        child.setTranslationY(v);
                        if (child.getColor() == Color.BLUE) {
                            root.setBackgroundColor(Color.RED);
                            child.setColor(Color.RED);
                        } else {
                            root.setBackgroundColor(Color.BLUE);
                            child.setColor(Color.BLUE);
                        }
                    }
                });
                mAnimator.start();
            }

            @Override
            public void teardownView() {
                mAnimator.cancel();
            }
        };

        createTest()
                .addLayout(R.layout.frame_layout, initializer, true)
                .runWithAnimationVerifier(new BlueOrRedVerifier());
    }

    @Test
    public void testCreateFromPicture() {
        final Rect rect = new Rect(10, 10, 80, 80);
        Picture picture = new Picture();
        {
            Canvas canvas = picture.beginRecording(TEST_WIDTH, TEST_HEIGHT);
            Paint p = new Paint();
            p.setAntiAlias(false);
            p.setColor(Color.BLUE);
            canvas.drawRect(rect, p);
            picture.endRecording();
        }
        Bitmap bitmap = Bitmap.createBitmap(picture, picture.getWidth(),
                picture.getHeight(), Bitmap.Config.ARGB_8888);
        assertEquals(TEST_WIDTH, bitmap.getWidth());
        assertEquals(TEST_HEIGHT, bitmap.getHeight());
        assertEquals(Bitmap.Config.ARGB_8888, bitmap.getConfig());
        createTest().addCanvasClient((canvas, width, height) -> {
            canvas.drawBitmap(bitmap, 0, 0, null);
        }, true).runWithVerifier(new RectVerifier(Color.WHITE, Color.BLUE, rect));
    }
}
