/*
 * Copyright (C) 2008 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 com.android.cts.stub.R;

import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;

import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Drawable.ConstantState;
import android.graphics.drawable.ScaleDrawable;
import android.test.AndroidTestCase;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.StateSet;
import android.view.Gravity;

public class ScaleDrawableTest extends AndroidTestCase {

    @SuppressWarnings("deprecation")
    public void testConstructor() {
        Drawable d = new BitmapDrawable();
        ScaleDrawable scaleDrawable = new ScaleDrawable(d, Gravity.CENTER, 100, 200);
        assertSame(d, scaleDrawable.getDrawable());

        new ScaleDrawable(null, -1, Float.MAX_VALUE, Float.MIN_VALUE);
    }

    @SuppressWarnings("deprecation")
    public void testInvalidateDrawable() {
        ScaleDrawable scaleDrawable = new ScaleDrawable(new BitmapDrawable(),
                Gravity.CENTER, 100, 200);

        MockCallback cb = new MockCallback();
        scaleDrawable.setCallback(cb);
        scaleDrawable.invalidateDrawable(null);
        assertTrue(cb.hasCalledInvalidate());

        cb.reset();
        scaleDrawable.invalidateDrawable(new BitmapDrawable());
        assertTrue(cb.hasCalledInvalidate());

        cb.reset();
        scaleDrawable.setCallback(null);
        scaleDrawable.invalidateDrawable(null);
        assertFalse(cb.hasCalledInvalidate());
    }

    @SuppressWarnings("deprecation")
    public void testScheduleDrawable() {
        ScaleDrawable scaleDrawable = new ScaleDrawable(new BitmapDrawable(),
                Gravity.CENTER, 100, 200);

        MockCallback cb = new MockCallback();
        scaleDrawable.setCallback(cb);
        scaleDrawable.scheduleDrawable(null, null, 0);
        assertTrue(cb.hasCalledSchedule());

        cb.reset();
        scaleDrawable.scheduleDrawable(new BitmapDrawable(), new Runnable() {
            public void run() {
            }
        }, 1000L);
        assertTrue(cb.hasCalledSchedule());

        cb.reset();
        scaleDrawable.setCallback(null);
        scaleDrawable.scheduleDrawable(null, null, 0);
        assertFalse(cb.hasCalledSchedule());
    }

    @SuppressWarnings("deprecation")
    public void testUnscheduleDrawable() {
        ScaleDrawable scaleDrawable = new ScaleDrawable(new BitmapDrawable(),
                Gravity.CENTER, 100, 200);

        MockCallback cb = new MockCallback();
        scaleDrawable.setCallback(cb);
        scaleDrawable.unscheduleDrawable(null, null);
        assertTrue(cb.hasCalledUnschedule());

        cb.reset();
        scaleDrawable.unscheduleDrawable(new BitmapDrawable(), new Runnable() {
            public void run() {
            }
        });
        assertTrue(cb.hasCalledUnschedule());

        cb.reset();
        scaleDrawable.setCallback(null);
        scaleDrawable.unscheduleDrawable(null, null);
        assertFalse(cb.hasCalledUnschedule());
    }

    private static class MockCallback implements Drawable.Callback2 {
        private boolean mCalledInvalidate;
        private boolean mCalledSchedule;
        private boolean mCalledUnschedule;

        public void invalidateDrawable(Drawable who) {
            mCalledInvalidate = true;
        }

        public void scheduleDrawable(Drawable who, Runnable what, long when) {
            mCalledSchedule = true;
        }

        public void unscheduleDrawable(Drawable who, Runnable what) {
            mCalledUnschedule = true;
        }

        public boolean hasCalledInvalidate() {
            return mCalledInvalidate;
        }

        public boolean hasCalledSchedule() {
            return mCalledSchedule;
        }

        public boolean hasCalledUnschedule() {
            return mCalledUnschedule;
        }

        public int getResolvedLayoutDirection(Drawable who) {
            return 0;
        }

        public void reset() {
            mCalledInvalidate = false;
            mCalledSchedule = false;
            mCalledUnschedule = false;
        }
    }

    public void testDraw() {
        MockDrawable mockDrawable = new MockDrawable();
        ScaleDrawable scaleDrawable = new ScaleDrawable(mockDrawable, Gravity.CENTER, 100, 200);

        scaleDrawable.draw(new Canvas());
        assertFalse(mockDrawable.hasCalledDraw());

        // this method will call the contained drawable's draw method
        // if the contained drawable's level doesn't equal 0.
        mockDrawable.setLevel(1);
        scaleDrawable.draw(new Canvas());
        assertTrue(mockDrawable.hasCalledDraw());

        mockDrawable.reset();
        scaleDrawable.draw(null);
        assertTrue(mockDrawable.hasCalledDraw());
    }

    public void testGetChangingConfigurations() {
        final int SUPER_CONFIG = 1;
        final int CONTAINED_DRAWABLE_CONFIG = 2;

        MockDrawable mockDrawable = new MockDrawable();
        ScaleDrawable scaleDrawable = new ScaleDrawable(mockDrawable, Gravity.CENTER, 100, 200);

        assertEquals(0, scaleDrawable.getChangingConfigurations());

        mockDrawable.setChangingConfigurations(CONTAINED_DRAWABLE_CONFIG);
        assertEquals(CONTAINED_DRAWABLE_CONFIG, scaleDrawable.getChangingConfigurations());

        scaleDrawable.setChangingConfigurations(SUPER_CONFIG);
        assertEquals(SUPER_CONFIG | CONTAINED_DRAWABLE_CONFIG,
                scaleDrawable.getChangingConfigurations());
    }

    public void testGetPadding() {
        MockDrawable mockDrawable = new MockDrawable();
        ScaleDrawable scaleDrawable = new ScaleDrawable(mockDrawable, Gravity.CENTER, 100, 200);

        // this method will call contained drawable's getPadding method.
        scaleDrawable.getPadding(new Rect());
        assertTrue(mockDrawable.hasCalledGetPadding());

        // input null as param
        try {
            scaleDrawable.getPadding(null);
            fail("Should throw NullPointerException");
        } catch (NullPointerException e) {
        }
    }

    public void testSetVisible() {
        MockDrawable mockDrawable = new MockDrawable();
        ScaleDrawable scaleDrawable = new ScaleDrawable(mockDrawable, Gravity.CENTER, 100, 200);
        assertTrue(scaleDrawable.isVisible());

        assertTrue(scaleDrawable.setVisible(false, false));
        assertFalse(scaleDrawable.isVisible());
        assertTrue(mockDrawable.hasCalledSetVisible());

        mockDrawable.reset();
        assertFalse(scaleDrawable.setVisible(false, false));
        assertFalse(scaleDrawable.isVisible());
        assertTrue(mockDrawable.hasCalledSetVisible());

        mockDrawable.reset();
        assertTrue(scaleDrawable.setVisible(true, false));
        assertTrue(scaleDrawable.isVisible());
        assertTrue(mockDrawable.hasCalledSetVisible());
    }

    public void testSetAlpha() {
        MockDrawable mockDrawable = new MockDrawable();
        ScaleDrawable scaleDrawable = new ScaleDrawable(mockDrawable, Gravity.CENTER, 100, 200);

        // this method will call contained drawable's setAlpha method.
        scaleDrawable.setAlpha(100);
        assertTrue(mockDrawable.hasCalledSetAlpha());

        mockDrawable.reset();
        scaleDrawable.setAlpha(Integer.MAX_VALUE);
        assertTrue(mockDrawable.hasCalledSetAlpha());

        mockDrawable.reset();
        scaleDrawable.setAlpha(-1);
        assertTrue(mockDrawable.hasCalledSetAlpha());
    }

    public void testSetColorFilter() {
        MockDrawable mockDrawable = new MockDrawable();
        ScaleDrawable scaleDrawable = new ScaleDrawable(mockDrawable, Gravity.CENTER, 100, 200);

        // this method will call contained drawable's setColorFilter method.
        scaleDrawable.setColorFilter(new ColorFilter());
        assertTrue(mockDrawable.hasCalledSetColorFilter());

        mockDrawable.reset();
        scaleDrawable.setColorFilter(null);
        assertTrue(mockDrawable.hasCalledSetColorFilter());
    }

    public void testGetOpacity() {
        MockDrawable mockDrawable = new MockDrawable();
        ScaleDrawable scaleDrawable = new ScaleDrawable(mockDrawable, Gravity.CENTER, 100, 200);

        // this method will call contained drawable's getOpacity method.
        scaleDrawable.getOpacity();
        assertTrue(mockDrawable.hasCalledGetOpacity());
    }

    public void testIsStateful() {
        MockDrawable mockDrawable = new MockDrawable();
        ScaleDrawable scaleDrawable = new ScaleDrawable(mockDrawable, Gravity.CENTER, 100, 200);

        // this method will call contained drawable's isStateful method.
        scaleDrawable.isStateful();
        assertTrue(mockDrawable.hasCalledIsStateful());
    }

    public void testOnStateChange() {
        MockDrawable mockDrawable = new MockDrawable();
        MockScaleDrawable mockScaleDrawable = new MockScaleDrawable(
                mockDrawable, Gravity.CENTER, 100, 200);

        assertFalse(mockScaleDrawable.onStateChange(StateSet.WILD_CARD));
        assertTrue(mockDrawable.hasCalledSetState());
        assertTrue(mockScaleDrawable.hasCalledOnBoundsChange());

        mockDrawable.reset();
        mockScaleDrawable.reset();
        assertFalse(mockScaleDrawable.onStateChange(null));
        assertTrue(mockDrawable.hasCalledSetState());
        assertTrue(mockScaleDrawable.hasCalledOnBoundsChange());
    }

    public void testOnLevelChange() {
        MockDrawable mockDrawable = new MockDrawable();
        MockScaleDrawable mockScaleDrawable = new MockScaleDrawable(
                mockDrawable, Gravity.CENTER, 100, 200);

        assertTrue(mockScaleDrawable.onLevelChange(0));
        assertFalse(mockDrawable.hasCalledOnLevelChange());
        assertTrue(mockScaleDrawable.hasCalledOnBoundsChange());

        mockDrawable.reset();
        mockScaleDrawable.reset();
        assertTrue(mockScaleDrawable.onLevelChange(Integer.MIN_VALUE));
        assertTrue(mockDrawable.hasCalledOnLevelChange());
        assertTrue(mockScaleDrawable.hasCalledOnBoundsChange());
    }

    public void testOnBoundsChange() {
        MockDrawable mockDrawable = new MockDrawable();
        float scaleWidth = 0.3f;
        float scaleHeight = 0.3f;
        MockScaleDrawable mockScaleDrawable = new MockScaleDrawable(
                mockDrawable, Gravity.LEFT, scaleWidth, scaleHeight);
        Rect bounds = new Rect(2, 2, 26, 32);
        mockDrawable.setBounds(bounds);
        mockScaleDrawable.onBoundsChange(bounds);
        Rect expected = new Rect();
        Gravity.apply(Gravity.LEFT, bounds.width() - (int) (bounds.width() * scaleWidth),
                bounds.height() - (int) (bounds.height() * scaleHeight), bounds, expected);
        assertEquals(expected.left, mockDrawable.getBounds().left);
        assertEquals(expected.top, mockDrawable.getBounds().top);
        assertEquals(expected.right, mockDrawable.getBounds().right);
        assertEquals(expected.bottom, mockDrawable.getBounds().bottom);

        scaleWidth = 0.6f;
        scaleHeight = 0.7f;
        int level = 4000;
        mockScaleDrawable = new MockScaleDrawable(
                mockDrawable, Gravity.BOTTOM | Gravity.RIGHT, scaleWidth, scaleHeight);
        mockDrawable.setBounds(bounds);
        mockScaleDrawable.setLevel(level);
        mockScaleDrawable.onBoundsChange(bounds);
        Gravity.apply(Gravity.BOTTOM | Gravity.RIGHT,
                bounds.width() - (int) (bounds.width() * scaleWidth * (10000 - level) / 10000),
                bounds.height() - (int) (bounds.height() * scaleHeight * (10000 - level) / 10000),
                bounds, expected);
        assertEquals(expected.left, mockDrawable.getBounds().left);
        assertEquals(expected.top, mockDrawable.getBounds().top);
        assertEquals(expected.right, mockDrawable.getBounds().right);
        assertEquals(expected.bottom, mockDrawable.getBounds().bottom);

        scaleWidth = 0f;
        scaleHeight = -0.3f;
        mockScaleDrawable = new MockScaleDrawable(
                mockDrawable, Gravity.BOTTOM | Gravity.RIGHT, scaleWidth, scaleHeight);
        mockDrawable.setBounds(bounds);
        mockScaleDrawable.onBoundsChange(bounds);
        assertEquals(bounds.left, mockDrawable.getBounds().left);
        assertEquals(bounds.top, mockDrawable.getBounds().top);
        assertEquals(bounds.right, mockDrawable.getBounds().right);
        assertEquals(bounds.bottom, mockDrawable.getBounds().bottom);

        scaleWidth = 1f;
        scaleHeight = 1.7f;
        mockScaleDrawable = new MockScaleDrawable(
                mockDrawable, Gravity.BOTTOM | Gravity.RIGHT, scaleWidth, scaleHeight);
        mockDrawable.setBounds(bounds);
        mockScaleDrawable.onBoundsChange(bounds);
        assertEquals(bounds.left, mockDrawable.getBounds().left);
        assertEquals(bounds.top, mockDrawable.getBounds().top);
        assertEquals(bounds.right, mockDrawable.getBounds().right);
        assertEquals(bounds.bottom, mockDrawable.getBounds().bottom);
    }

    public void testGetIntrinsicWidth() {
        MockDrawable mockDrawable = new MockDrawable();
        ScaleDrawable scaleDrawable = new ScaleDrawable(mockDrawable, Gravity.CENTER, 100, 200);

        // this method will call contained drawable's getIntrinsicWidth method.
        scaleDrawable.getIntrinsicWidth();
        assertTrue(mockDrawable.hasCalledGetIntrinsicWidth());
    }

    public void testGetIntrinsicHeight() {
        MockDrawable mockDrawable = new MockDrawable();
        ScaleDrawable scaleDrawable = new ScaleDrawable(mockDrawable, Gravity.CENTER, 100, 200);

        // this method will call contained drawable's getIntrinsicHeight method.
        scaleDrawable.getIntrinsicHeight();
        assertTrue(mockDrawable.hasCalledGetIntrinsicHeight());
    }

    @SuppressWarnings("deprecation")
    public void testGetConstantState() {
        ScaleDrawable scaleDrawable = new ScaleDrawable(new BitmapDrawable(),
                Gravity.CENTER, 100, 200);

        ConstantState constantState = scaleDrawable.getConstantState();
        assertNotNull(constantState);
        assertEquals(0, constantState.getChangingConfigurations());

        scaleDrawable.setChangingConfigurations(1);
        constantState = scaleDrawable.getConstantState();
        assertNotNull(constantState);
        assertEquals(1, constantState.getChangingConfigurations());
    }

    @SuppressWarnings("deprecation")
    public void testInflate() throws XmlPullParserException, IOException {
        ScaleDrawable scaleDrawable = new ScaleDrawable(new BitmapDrawable(),
                Gravity.RIGHT, 100, 200);

        Resources res = mContext.getResources();
        XmlResourceParser parser = res.getXml(R.xml.scaledrawable);
        AttributeSet attrs = DrawableTestUtils.getAttributeSet(parser, "scale_allattrs");
        scaleDrawable.inflate(res, parser, attrs);
        int bitmapSize = (int) Math.ceil(48.0 *
                res.getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
        assertEquals(bitmapSize, scaleDrawable.getIntrinsicWidth());
        assertEquals(bitmapSize, scaleDrawable.getIntrinsicHeight());

        parser = res.getXml(R.xml.scaledrawable);
        attrs = DrawableTestUtils.getAttributeSet(parser, "scale_nodrawable");
        try {
            scaleDrawable.inflate(res, parser, attrs);
            fail("Should throw IllegalArgumentException");
        } catch (IllegalArgumentException e) {
        }

        try {
            scaleDrawable.inflate(null, parser, attrs);
            fail("Should throw NullPointerException if resource is null");
        } catch (NullPointerException e) {
        }

        try {
            scaleDrawable.inflate(res, null, attrs);
            fail("Should throw NullPointerException if parser is null");
        } catch (NullPointerException e) {
        }

        try {
            scaleDrawable.inflate(res, parser, null);
            fail("Should throw NullPointerException if attribute set is null");
        } catch (NullPointerException e) {
        }
    }

    public void testMutate() {
        Resources resources = mContext.getResources();
        ScaleDrawable d1 = (ScaleDrawable) resources.getDrawable(R.drawable.scaledrawable);
        ScaleDrawable d2 = (ScaleDrawable) resources.getDrawable(R.drawable.scaledrawable);
        ScaleDrawable d3 = (ScaleDrawable) resources.getDrawable(R.drawable.scaledrawable);

        d1.setAlpha(100);
        assertEquals(100, ((BitmapDrawable) d1.getDrawable()).getPaint().getAlpha());
        assertEquals(100, ((BitmapDrawable) d2.getDrawable()).getPaint().getAlpha());
        assertEquals(100, ((BitmapDrawable) d3.getDrawable()).getPaint().getAlpha());

        d1.mutate();
        d1.setAlpha(200);
        assertEquals(200, ((BitmapDrawable) d1.getDrawable()).getPaint().getAlpha());
        assertEquals(100, ((BitmapDrawable) d2.getDrawable()).getPaint().getAlpha());
        assertEquals(100, ((BitmapDrawable) d3.getDrawable()).getPaint().getAlpha());

        d2.setAlpha(50);
        assertEquals(200, ((BitmapDrawable) d1.getDrawable()).getPaint().getAlpha());
        assertEquals(50, ((BitmapDrawable) d2.getDrawable()).getPaint().getAlpha());
        assertEquals(50, ((BitmapDrawable) d3.getDrawable()).getPaint().getAlpha());
    }

    private static class MockDrawable extends Drawable {
        private boolean mCalledDraw = false;
        private boolean mCalledGetPadding = false;
        private boolean mCalledSetVisible = false;
        private boolean mCalledSetAlpha = false;
        private boolean mCalledGetOpacity = false;
        private boolean mCalledSetColorFilter = false;
        private boolean mCalledIsStateful = false;
        private boolean mCalledGetIntrinsicWidth = false;
        private boolean mCalledGetIntrinsicHeight = false;
        private boolean mCalledSetState = false;
        private boolean mCalledOnLevelChange = false;

        @Override
        public void draw(Canvas canvas) {
            mCalledDraw = true;
        }

        @Override
        public int getOpacity() {
            mCalledGetOpacity = true;
            return 0;
        }

        @Override
        public void setAlpha(int alpha) {
            mCalledSetAlpha = true;
        }

        @Override
        public void setColorFilter(ColorFilter cf) {
            mCalledSetColorFilter = true;
        }

        @Override
        public boolean getPadding(Rect padding) {
            mCalledGetPadding = true;
            return super.getPadding(padding);
        }

        @Override
        public boolean setVisible(boolean visible, boolean restart) {
            mCalledSetVisible = true;
            return super.setVisible(visible, restart);
        }

        @Override
        public boolean isStateful() {
            mCalledIsStateful = true;
            return super.isStateful();
        }

        @Override
        public int getIntrinsicWidth() {
            mCalledGetIntrinsicWidth = true;
            return super.getIntrinsicWidth();
        }

        @Override
        public int getIntrinsicHeight() {
            mCalledGetIntrinsicHeight = true;
            return super.getIntrinsicHeight();

        }

        @Override
        public boolean setState(final int[] stateSet) {
            mCalledSetState = true;
            return super.setState(stateSet);
        }

        @Override
        protected boolean onLevelChange(int level) {
            mCalledOnLevelChange = true;
            return super.onLevelChange(level);
        }

        public boolean hasCalledDraw() {
            return mCalledDraw;
        }

        public boolean hasCalledGetPadding() {
            return mCalledGetPadding;
        }

        public boolean hasCalledSetVisible() {
            return mCalledSetVisible;
        }

        public boolean hasCalledSetAlpha() {
            return mCalledSetAlpha;
        }

        public boolean hasCalledGetOpacity() {
            return mCalledGetOpacity;
        }

        public boolean hasCalledSetColorFilter() {
            return mCalledSetColorFilter;
        }

        public boolean hasCalledIsStateful() {
            return mCalledIsStateful;
        }

        public boolean hasCalledGetIntrinsicWidth() {
            return mCalledGetIntrinsicWidth;
        }

        public boolean hasCalledGetIntrinsicHeight() {
            return mCalledGetIntrinsicHeight;
        }

        public boolean hasCalledSetState() {
            return mCalledSetState;
        }

        public boolean hasCalledOnLevelChange() {
            return mCalledOnLevelChange;
        }

        public void reset() {
            mCalledDraw = false;
            mCalledGetPadding = false;
            mCalledSetVisible = false;
            mCalledSetAlpha = false;
            mCalledGetOpacity = false;
            mCalledSetColorFilter = false;
            mCalledIsStateful = false;
            mCalledGetIntrinsicWidth = false;
            mCalledGetIntrinsicHeight = false;
            mCalledSetState = false;
            mCalledOnLevelChange = false;
        }
    }

    private static class MockScaleDrawable extends ScaleDrawable {
        private boolean mCalledOnBoundsChange = false;

        MockScaleDrawable() {
            super(null, Gravity.CENTER, 100, 200);
        }

        public MockScaleDrawable(Drawable drawable, int gravity,
                float scaleWidth, float scaleHeight) {
            super(drawable, gravity, scaleWidth, scaleHeight);
        }

        @Override
        protected boolean onStateChange(int[] state) {
            return super.onStateChange(state);
        }

        @Override
        protected boolean onLevelChange(int level) {
            return super.onLevelChange(level);
        }

        @Override
        protected void onBoundsChange(Rect bounds) {
            mCalledOnBoundsChange = true;
            super.onBoundsChange(bounds);
        }

        public boolean hasCalledOnBoundsChange() {
            return mCalledOnBoundsChange;
        }

        public void reset() {
            mCalledOnBoundsChange = false;
        }
    }
}
