/*
 * Copyright (C) 2017 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.graphics.drawable.cts;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import android.graphics.Color;
import android.graphics.Path;
import android.graphics.Path.Direction;
import android.graphics.RectF;
import android.graphics.Region;
import android.graphics.Region.Op;
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.ColorDrawable;
import android.util.Log;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

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

@SmallTest
@RunWith(AndroidJUnit4.class)
public class AdaptiveIconMaskTest {

    public static final String TAG = AdaptiveIconMaskTest.class.getSimpleName();
    public static void L(String s, Object... parts) {
        Log.d(TAG, (parts.length == 0) ? s : String.format(s, parts));
    }
    private static final double SAFEZONE_INSET = .1;
    private static final double DELTA = .01f;
    private Path mMask = new Path();
    private Path mSafeZone = new Path();
    private ColorDrawable mBlueDrawable;
    private ColorDrawable mRedDrawable;
    private AdaptiveIconDrawable mDrawable;
    private boolean mUseRoundIcon;

    @Before
    public void setup() {
        mBlueDrawable = new ColorDrawable(Color.BLUE);
        mRedDrawable = new ColorDrawable(Color.RED);
        mDrawable = new AdaptiveIconDrawable( mBlueDrawable, mRedDrawable);
        mDrawable.setBounds(0, 0, 100, 100);

        mMask = mDrawable.getIconMask();

        int sInset = (int) (SAFEZONE_INSET * AdaptiveIconDrawable.MASK_SIZE);
        mSafeZone.addCircle(AdaptiveIconDrawable.MASK_SIZE/2, AdaptiveIconDrawable.MASK_SIZE/2,
            AdaptiveIconDrawable.MASK_SIZE/2/2 - sInset, Direction.CW);
        mUseRoundIcon =  InstrumentationRegistry.getTargetContext().getResources().getBoolean(
            InstrumentationRegistry.getTargetContext().getResources().getIdentifier(
                "config_useRoundIcon", "bool", "android"));
        L("config_useRoundIcon:" + mUseRoundIcon);
    }

    @Test
    public void testDeviceConfigMask_bounds() {
        assertNotNull(mMask);

        // Bounds should be [100 x 100]
        RectF bounds = new RectF();
        mMask.computeBounds(bounds, true);
        assertTrue("Mask top should be larger than or equal to 0", -DELTA <= bounds.top);
        assertTrue("Mask left should be larger than or equal to 0", -DELTA <= bounds.left);
        assertTrue("Mask bottom should be smaller than or equal to" +
                AdaptiveIconDrawable.MASK_SIZE,
            AdaptiveIconDrawable.MASK_SIZE + DELTA >= bounds.bottom);
        assertTrue("Mask right should be smaller than or equal to " +
                AdaptiveIconDrawable.MASK_SIZE,
            AdaptiveIconDrawable.MASK_SIZE + DELTA >= bounds.right);
    }

    @Test
    public void testDeviceConfigMask_largerThanSafezone() {
        assertNotNull(mMask);

        // MASK intersection SafeZone = SafeZone
        Region maskRegion = new Region(0, 0, (int) AdaptiveIconDrawable.MASK_SIZE,
            (int) AdaptiveIconDrawable.MASK_SIZE);
        maskRegion.setPath(mMask, maskRegion);

        Region safeZoneRegion = new Region(0, 0, (int) AdaptiveIconDrawable.MASK_SIZE,
            (int) AdaptiveIconDrawable.MASK_SIZE);
        safeZoneRegion.setPath(mSafeZone, safeZoneRegion);

        Region intersectRegion = new Region();
        boolean result = maskRegion.op(safeZoneRegion, intersectRegion, Region.Op.INTERSECT);

        // resultRegion should be exactly same as the safezone
        // Test if intersectRegion is smaller than safeZone, in which case test will fail.
        Region subtractRegion = new Region();
        result = safeZoneRegion.op(intersectRegion, subtractRegion, Op.DIFFERENCE);
        assertFalse("Mask is not respecting the safezone.", result);
    }

    @Test
    public void testDeviceConfigMask_isConvex() {
        assertNotNull(mMask);
        assertTrue("Mask is not convex", mMask.isConvex());
    }

    @Test
    public void testGetLayers() {
        assertEquals("Background layer is not the same.",
            mBlueDrawable, mDrawable.getBackground());
        assertEquals("Foreground layer is not the same.",
            mRedDrawable, mDrawable.getForeground());
    }

    @Test
    public void testDeviceConfig_iconMask_useRoundIcon() {
        assertNotNull(mMask);

        boolean circleMask = isCircle(mMask);
        // If mask shape is circle, then mUseRoundIcon should be defined and should be true.
        // If mask shape is not a circle
        //           mUseRoundIcon doesn't have to be defined.
        //           if mUseRoundIcon is defined, then should be false
        assertEquals(mUseRoundIcon, circleMask);
    }

    private boolean isCircle(Path maskPath) {
        Path circle101 = new Path();
        circle101.addCircle(50, 50, 50.5f, Direction.CCW);
        Path circle99 = new Path();
        circle99.addCircle(50, 50, 49.5f, Direction.CCW);
        circle99.op(maskPath, Path.Op.DIFFERENCE);
        boolean fullyEnclosesSmallerCircle = circle99.isEmpty();
        maskPath.op(circle101, Path.Op.DIFFERENCE);
        boolean fullyEnclosedByLargerCircle = maskPath.isEmpty();
        return fullyEnclosedByLargerCircle && fullyEnclosesSmallerCircle;
    }
}
