/*
 * Copyright (C) 2009 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.shapes.cts;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.drawable.shapes.PathShape;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;

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

@SmallTest
@RunWith(AndroidJUnit4.class)
public class PathShapeTest {
    private static final int TEST_COLOR_1 = 0xFF00FF00;
    private static final int TEST_COLOR_2 = 0xFFFF0000;

    private static final int TOLERANCE = 4;

    @Test
    public void testConstructor() {
        new PathShape(new Path(), 1f, 5f);

        new PathShape(new Path(), -1f, -1f);

        new PathShape(null, 0f, 0f);
    }

    @Test
    public void testDraw() {
        final int SHAPE_SIZE = 200;

        // draw a square rotated by 45 degrees centered on (50, 50)
        Path path = new Path();
        path.moveTo(50, 0);
        path.lineTo(0, 50);
        path.lineTo(50, 100);
        path.lineTo(100, 50);
        path.close();
        PathShape pathShape = new PathShape(path, SHAPE_SIZE, SHAPE_SIZE);
        Bitmap bitmap = Bitmap.createBitmap(SHAPE_SIZE, SHAPE_SIZE, Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Paint paint = new Paint();
        paint.setStyle(Style.FILL);
        paint.setColor(TEST_COLOR_1);
        pathShape.resize(SHAPE_SIZE, SHAPE_SIZE);

        pathShape.draw(canvas, paint);
        // check center point
        assertEquals(TEST_COLOR_1, bitmap.getPixel(50, 50));

        paint.setColor(TEST_COLOR_2);
        // scale down to half size; diagonal is now 50px
        pathShape.resize(SHAPE_SIZE / 2, SHAPE_SIZE / 2);
        pathShape.draw(canvas, paint);
        // count number of pixels with TEST_COLOR_2 horizontally, vertically and diagonally
        int horizontal = 0;
        int vertical = 0;
        int diagonal = 0;
        for (int i = 0; i < 50; i++) {
            if (bitmap.getPixel(25, i) == TEST_COLOR_2) {
                vertical += 1;
            }
            if (bitmap.getPixel(i, 25) == TEST_COLOR_2) {
                horizontal += 1;
            }
            if (bitmap.getPixel(i, i) == TEST_COLOR_2) {
                diagonal += 1;
            }
        }
        assertEquals(50, horizontal, TOLERANCE);
        assertEquals(50, vertical, TOLERANCE);
        assertEquals(25, diagonal, TOLERANCE);
    }

    @Test
    public void testClone() throws CloneNotSupportedException {
        PathShape pathShape = new PathShape(new Path(), 1f, 5f);
        pathShape.resize(100f, 200f);
        PathShape clonedShape = pathShape.clone();
        assertEquals(100f, pathShape.getWidth(), 0.0f);
        assertEquals(200f, pathShape.getHeight(), 0.0f);

        assertNotSame(pathShape, clonedShape);
        assertEquals(pathShape.getWidth(), clonedShape.getWidth(), 0.0f);
        assertEquals(pathShape.getHeight(), clonedShape.getHeight(), 0.0f);
    }

    @Test
    public void testGetOutline() {
        Outline outline = new Outline();
        PathShape shape;

        // This is a no-op. Just make sure it doesn't crash.
        outline.setEmpty();
        shape = new PathShape(new Path(), 0, 0);
        shape.getOutline(outline);
        assertTrue(outline.isEmpty());
    }
}
