/*
 * 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.graphics.drawable;

import com.android.layoutlib.bridge.impl.DelegateManager;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;

import android.annotation.NonNull;
import android.content.res.Resources;
import android.content.res.Resources.Theme;
import android.content.res.TypedArray;
import android.graphics.BaseCanvas_Delegate;
import android.graphics.Canvas_Delegate;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Paint.Join;
import android.graphics.Paint_Delegate;
import android.graphics.Path;
import android.graphics.Path.FillType;
import android.graphics.PathMeasure;
import android.graphics.Path_Delegate;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.Region.Op;
import android.graphics.Shader_Delegate;
import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.Log;
import android.util.MathUtils;
import android.util.PathParser_Delegate;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.function.Consumer;

import static android.graphics.Canvas.CLIP_SAVE_FLAG;
import static android.graphics.Canvas.MATRIX_SAVE_FLAG;
import static android.graphics.Paint.Cap.BUTT;
import static android.graphics.Paint.Cap.ROUND;
import static android.graphics.Paint.Cap.SQUARE;
import static android.graphics.Paint.Join.BEVEL;
import static android.graphics.Paint.Join.MITER;
import static android.graphics.Paint.Style;

/**
 * Delegate used to provide new implementation of a select few methods of {@link VectorDrawable}
 * <p>
 * Through the layoutlib_create tool, the original  methods of VectorDrawable have been replaced by
 * calls to methods of the same name in this delegate class.
 */
@SuppressWarnings("unused")
public class VectorDrawable_Delegate {
    private static final String LOGTAG = VectorDrawable_Delegate.class.getSimpleName();
    private static final boolean DBG_VECTOR_DRAWABLE = false;

    private static final DelegateManager<VNativeObject> sPathManager =
            new DelegateManager<>(VNativeObject.class);

    private static long addNativeObject(VNativeObject object) {
        long ptr = sPathManager.addNewDelegate(object);
        object.setNativePtr(ptr);

        return ptr;
    }

    /**
     * Obtains styled attributes from the theme, if available, or unstyled resources if the theme is
     * null.
     */
    private static TypedArray obtainAttributes(
            Resources res, Theme theme, AttributeSet set, int[] attrs) {
        if (theme == null) {
            return res.obtainAttributes(set, attrs);
        }
        return theme.obtainStyledAttributes(set, attrs, 0, 0);
    }

    private static int applyAlpha(int color, float alpha) {
        int alphaBytes = Color.alpha(color);
        color &= 0x00FFFFFF;
        color |= ((int) (alphaBytes * alpha)) << 24;
        return color;
    }

    @LayoutlibDelegate
    static long nCreateTree(long rootGroupPtr) {
        return addNativeObject(new VPathRenderer_Delegate(rootGroupPtr));
    }

    @LayoutlibDelegate
    static long nCreateTreeFromCopy(long rendererToCopyPtr, long rootGroupPtr) {
        VPathRenderer_Delegate rendererToCopy = VNativeObject.getDelegate(rendererToCopyPtr);
        return addNativeObject(new VPathRenderer_Delegate(rendererToCopy,
                rootGroupPtr));
    }

    @LayoutlibDelegate
    static void nSetRendererViewportSize(long rendererPtr, float viewportWidth,
            float viewportHeight) {
        VPathRenderer_Delegate nativePathRenderer = VNativeObject.getDelegate(rendererPtr);
        nativePathRenderer.mViewportWidth = viewportWidth;
        nativePathRenderer.mViewportHeight = viewportHeight;
    }

    @LayoutlibDelegate
    static boolean nSetRootAlpha(long rendererPtr, float alpha) {
        VPathRenderer_Delegate nativePathRenderer = VNativeObject.getDelegate(rendererPtr);
        nativePathRenderer.setRootAlpha(alpha);

        return true;
    }

    @LayoutlibDelegate
    static float nGetRootAlpha(long rendererPtr) {
        VPathRenderer_Delegate nativePathRenderer = VNativeObject.getDelegate(rendererPtr);

        return nativePathRenderer.getRootAlpha();
    }

    @LayoutlibDelegate
    static void nSetAntiAlias(long rendererPtr, boolean aa) {
        VPathRenderer_Delegate nativePathRenderer = VNativeObject.getDelegate(rendererPtr);
        nativePathRenderer.setAntiAlias(aa);
    }

    @LayoutlibDelegate
    static void nSetAllowCaching(long rendererPtr, boolean allowCaching) {
        // ignored
    }

    @LayoutlibDelegate
    static int nDraw(long rendererPtr, long canvasWrapperPtr,
            long colorFilterPtr, Rect bounds, boolean needsMirroring, boolean canReuseCache) {
        VPathRenderer_Delegate nativePathRenderer = VNativeObject.getDelegate(rendererPtr);

        Canvas_Delegate.nSave(canvasWrapperPtr, MATRIX_SAVE_FLAG | CLIP_SAVE_FLAG);
        Canvas_Delegate.nClipRect(canvasWrapperPtr,
                bounds.left, bounds.top, bounds.right, bounds.bottom,
                Region.Op.INTERSECT.nativeInt);
        Canvas_Delegate.nTranslate(canvasWrapperPtr, bounds.left, bounds.top);

        if (needsMirroring) {
            Canvas_Delegate.nTranslate(canvasWrapperPtr, bounds.width(), 0);
            Canvas_Delegate.nScale(canvasWrapperPtr, -1.0f, 1.0f);
        }

        // At this point, canvas has been translated to the right position.
        // And we use this bound for the destination rect for the drawBitmap, so
        // we offset to (0, 0);
        bounds.offsetTo(0, 0);
        nativePathRenderer.draw(canvasWrapperPtr, colorFilterPtr, bounds.width(), bounds.height());

        Canvas_Delegate.nRestore(canvasWrapperPtr);

        return bounds.width() * bounds.height();
    }

    @LayoutlibDelegate
    static long nCreateFullPath() {
        return addNativeObject(new VFullPath_Delegate());
    }

    @LayoutlibDelegate
    static long nCreateFullPath(long nativeFullPathPtr) {
        VFullPath_Delegate original = VNativeObject.getDelegate(nativeFullPathPtr);
        return addNativeObject(new VFullPath_Delegate(original));
    }

    @LayoutlibDelegate
    static boolean nGetFullPathProperties(long pathPtr, byte[] propertiesData,
            int length) {
        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);

        ByteBuffer properties = ByteBuffer.wrap(propertiesData);
        properties.order(ByteOrder.nativeOrder());

        properties.putFloat(VFullPath_Delegate.STROKE_WIDTH_INDEX * 4, path.getStrokeWidth());
        properties.putInt(VFullPath_Delegate.STROKE_COLOR_INDEX * 4, path.getStrokeColor());
        properties.putFloat(VFullPath_Delegate.STROKE_ALPHA_INDEX * 4, path.getStrokeAlpha());
        properties.putInt(VFullPath_Delegate.FILL_COLOR_INDEX * 4, path.getFillColor());
        properties.putFloat(VFullPath_Delegate.FILL_ALPHA_INDEX * 4, path.getStrokeAlpha());
        properties.putFloat(VFullPath_Delegate.TRIM_PATH_START_INDEX * 4, path.getTrimPathStart());
        properties.putFloat(VFullPath_Delegate.TRIM_PATH_END_INDEX * 4, path.getTrimPathEnd());
        properties.putFloat(VFullPath_Delegate.TRIM_PATH_OFFSET_INDEX * 4,
                path.getTrimPathOffset());
        properties.putInt(VFullPath_Delegate.STROKE_LINE_CAP_INDEX * 4, path.getStrokeLineCap());
        properties.putInt(VFullPath_Delegate.STROKE_LINE_JOIN_INDEX * 4, path.getStrokeLineJoin());
        properties.putFloat(VFullPath_Delegate.STROKE_MITER_LIMIT_INDEX * 4,
                path.getStrokeMiterlimit());
        properties.putInt(VFullPath_Delegate.FILL_TYPE_INDEX * 4, path.getFillType());

        return true;
    }

    @LayoutlibDelegate
    static void nUpdateFullPathProperties(long pathPtr, float strokeWidth,
            int strokeColor, float strokeAlpha, int fillColor, float fillAlpha, float trimPathStart,
            float trimPathEnd, float trimPathOffset, float strokeMiterLimit, int strokeLineCap,
            int strokeLineJoin, int fillType) {
        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);

        path.setStrokeWidth(strokeWidth);
        path.setStrokeColor(strokeColor);
        path.setStrokeAlpha(strokeAlpha);
        path.setFillColor(fillColor);
        path.setFillAlpha(fillAlpha);
        path.setTrimPathStart(trimPathStart);
        path.setTrimPathEnd(trimPathEnd);
        path.setTrimPathOffset(trimPathOffset);
        path.setStrokeMiterlimit(strokeMiterLimit);
        path.setStrokeLineCap(strokeLineCap);
        path.setStrokeLineJoin(strokeLineJoin);
        path.setFillType(fillType);
    }

    @LayoutlibDelegate
    static void nUpdateFullPathFillGradient(long pathPtr, long fillGradientPtr) {
        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);

        path.setFillGradient(fillGradientPtr);
    }

    @LayoutlibDelegate
    static void nUpdateFullPathStrokeGradient(long pathPtr, long strokeGradientPtr) {
        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);

        path.setStrokeGradient(strokeGradientPtr);
    }

    @LayoutlibDelegate
    static long nCreateClipPath() {
        return addNativeObject(new VClipPath_Delegate());
    }

    @LayoutlibDelegate
    static long nCreateClipPath(long clipPathPtr) {
        VClipPath_Delegate original = VNativeObject.getDelegate(clipPathPtr);
        return addNativeObject(new VClipPath_Delegate(original));
    }

    @LayoutlibDelegate
    static long nCreateGroup() {
        return addNativeObject(new VGroup_Delegate());
    }

    @LayoutlibDelegate
    static long nCreateGroup(long groupPtr) {
        VGroup_Delegate original = VNativeObject.getDelegate(groupPtr);
        return addNativeObject(new VGroup_Delegate(original, new ArrayMap<>()));
    }

    @LayoutlibDelegate
    static void nSetName(long nodePtr, String name) {
        VNativeObject group = VNativeObject.getDelegate(nodePtr);
        group.setName(name);
    }

    @LayoutlibDelegate
    static boolean nGetGroupProperties(long groupPtr, float[] propertiesData,
            int length) {
        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);

        FloatBuffer properties = FloatBuffer.wrap(propertiesData);

        properties.put(VGroup_Delegate.ROTATE_INDEX, group.getRotation());
        properties.put(VGroup_Delegate.PIVOT_X_INDEX, group.getPivotX());
        properties.put(VGroup_Delegate.PIVOT_Y_INDEX, group.getPivotY());
        properties.put(VGroup_Delegate.SCALE_X_INDEX, group.getScaleX());
        properties.put(VGroup_Delegate.SCALE_Y_INDEX, group.getScaleY());
        properties.put(VGroup_Delegate.TRANSLATE_X_INDEX, group.getTranslateX());
        properties.put(VGroup_Delegate.TRANSLATE_Y_INDEX, group.getTranslateY());

        return true;
    }
    @LayoutlibDelegate
    static void nUpdateGroupProperties(long groupPtr, float rotate, float pivotX,
            float pivotY, float scaleX, float scaleY, float translateX, float translateY) {
        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);

        group.setRotation(rotate);
        group.setPivotX(pivotX);
        group.setPivotY(pivotY);
        group.setScaleX(scaleX);
        group.setScaleY(scaleY);
        group.setTranslateX(translateX);
        group.setTranslateY(translateY);
    }

    @LayoutlibDelegate
    static void nAddChild(long groupPtr, long nodePtr) {
        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
        group.mChildren.add(VNativeObject.getDelegate(nodePtr));
    }

    @LayoutlibDelegate
    static void nSetPathString(long pathPtr, String pathString, int length) {
        VPath_Delegate path = VNativeObject.getDelegate(pathPtr);
        path.setPathData(PathParser_Delegate.createNodesFromPathData(pathString));
    }

    /**
     * The setters and getters below for paths and groups are here temporarily, and will be removed
     * once the animation in AVD is replaced with RenderNodeAnimator, in which case the animation
     * will modify these properties in native. By then no JNI hopping would be necessary for VD
     * during animation, and these setters and getters will be obsolete.
     */
    // Setters and getters during animation.
    @LayoutlibDelegate
    static float nGetRotation(long groupPtr) {
        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
        return group.getRotation();
    }

    @LayoutlibDelegate
    static void nSetRotation(long groupPtr, float rotation) {
        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
        group.setRotation(rotation);
    }

    @LayoutlibDelegate
    static float nGetPivotX(long groupPtr) {
        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
        return group.getPivotX();
    }

    @LayoutlibDelegate
    static void nSetPivotX(long groupPtr, float pivotX) {
        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
        group.setPivotX(pivotX);
    }

    @LayoutlibDelegate
    static float nGetPivotY(long groupPtr) {
        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
        return group.getPivotY();
    }

    @LayoutlibDelegate
    static void nSetPivotY(long groupPtr, float pivotY) {
        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
        group.setPivotY(pivotY);
    }

    @LayoutlibDelegate
    static float nGetScaleX(long groupPtr) {
        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
        return group.getScaleX();
    }

    @LayoutlibDelegate
    static void nSetScaleX(long groupPtr, float scaleX) {
        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
        group.setScaleX(scaleX);
    }

    @LayoutlibDelegate
    static float nGetScaleY(long groupPtr) {
        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
        return group.getScaleY();
    }

    @LayoutlibDelegate
    static void nSetScaleY(long groupPtr, float scaleY) {
        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
        group.setScaleY(scaleY);
    }

    @LayoutlibDelegate
    static float nGetTranslateX(long groupPtr) {
        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
        return group.getTranslateX();
    }

    @LayoutlibDelegate
    static void nSetTranslateX(long groupPtr, float translateX) {
        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
        group.setTranslateX(translateX);
    }

    @LayoutlibDelegate
    static float nGetTranslateY(long groupPtr) {
        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
        return group.getTranslateY();
    }

    @LayoutlibDelegate
    static void nSetTranslateY(long groupPtr, float translateY) {
        VGroup_Delegate group = VNativeObject.getDelegate(groupPtr);
        group.setTranslateY(translateY);
    }

    @LayoutlibDelegate
    static void nSetPathData(long pathPtr, long pathDataPtr) {
        VPath_Delegate path = VNativeObject.getDelegate(pathPtr);
        path.setPathData(PathParser_Delegate.getDelegate(pathDataPtr).getPathDataNodes());
    }

    @LayoutlibDelegate
    static float nGetStrokeWidth(long pathPtr) {
        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
        return path.getStrokeWidth();
    }

    @LayoutlibDelegate
    static void nSetStrokeWidth(long pathPtr, float width) {
        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
        path.setStrokeWidth(width);
    }

    @LayoutlibDelegate
    static int nGetStrokeColor(long pathPtr) {
        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
        return path.getStrokeColor();
    }

    @LayoutlibDelegate
    static void nSetStrokeColor(long pathPtr, int strokeColor) {
        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
        path.setStrokeColor(strokeColor);
    }

    @LayoutlibDelegate
    static float nGetStrokeAlpha(long pathPtr) {
        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
        return path.getStrokeAlpha();
    }

    @LayoutlibDelegate
    static void nSetStrokeAlpha(long pathPtr, float alpha) {
        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
        path.setStrokeAlpha(alpha);
    }

    @LayoutlibDelegate
    static int nGetFillColor(long pathPtr) {
        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
        return path.getFillColor();
    }

    @LayoutlibDelegate
    static void nSetFillColor(long pathPtr, int fillColor) {
        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
        path.setFillColor(fillColor);
    }

    @LayoutlibDelegate
    static float nGetFillAlpha(long pathPtr) {
        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
        return path.getFillAlpha();
    }

    @LayoutlibDelegate
    static void nSetFillAlpha(long pathPtr, float fillAlpha) {
        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
        path.setFillAlpha(fillAlpha);
    }

    @LayoutlibDelegate
    static float nGetTrimPathStart(long pathPtr) {
        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
        return path.getTrimPathStart();
    }

    @LayoutlibDelegate
    static void nSetTrimPathStart(long pathPtr, float trimPathStart) {
        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
        path.setTrimPathStart(trimPathStart);
    }

    @LayoutlibDelegate
    static float nGetTrimPathEnd(long pathPtr) {
        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
        return path.getTrimPathEnd();
    }

    @LayoutlibDelegate
    static void nSetTrimPathEnd(long pathPtr, float trimPathEnd) {
        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
        path.setTrimPathEnd(trimPathEnd);
    }

    @LayoutlibDelegate
    static float nGetTrimPathOffset(long pathPtr) {
        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
        return path.getTrimPathOffset();
    }

    @LayoutlibDelegate
    static void nSetTrimPathOffset(long pathPtr, float trimPathOffset) {
        VFullPath_Delegate path = VNativeObject.getDelegate(pathPtr);
        path.setTrimPathOffset(trimPathOffset);
    }

    /**
     * Base class for all the internal Delegates that does two functions:
     * <ol>
     *     <li>Serves as base class to store all the delegates in one {@link DelegateManager}
     *     <li>Provides setName for all the classes. {@link VPathRenderer_Delegate} does actually
     *     not need it
     * </ol>
     */
    abstract static class VNativeObject {
        long mNativePtr = 0;

        @NonNull
        static <T> T getDelegate(long nativePtr) {
            //noinspection unchecked
            T vNativeObject = (T) sPathManager.getDelegate(nativePtr);

            assert vNativeObject != null;
            return vNativeObject;
        }

        abstract void setName(String name);

        void setNativePtr(long nativePtr) {
            mNativePtr = nativePtr;
        }

        /**
         * Method to explicitly dispose native objects
         */
        void dispose() {
        }
    }

    private static class VClipPath_Delegate extends VPath_Delegate {
        private VClipPath_Delegate() {
            // Empty constructor.
        }

        private VClipPath_Delegate(VClipPath_Delegate copy) {
            super(copy);
        }

        @Override
        public boolean isClipPath() {
            return true;
        }
    }

    static class VFullPath_Delegate extends VPath_Delegate {
        // These constants need to be kept in sync with their values in VectorDrawable.VFullPath
        private static final int STROKE_WIDTH_INDEX = 0;
        private static final int STROKE_COLOR_INDEX = 1;
        private static final int STROKE_ALPHA_INDEX = 2;
        private static final int FILL_COLOR_INDEX = 3;
        private static final int FILL_ALPHA_INDEX = 4;
        private static final int TRIM_PATH_START_INDEX = 5;
        private static final int TRIM_PATH_END_INDEX = 6;
        private static final int TRIM_PATH_OFFSET_INDEX = 7;
        private static final int STROKE_LINE_CAP_INDEX = 8;
        private static final int STROKE_LINE_JOIN_INDEX = 9;
        private static final int STROKE_MITER_LIMIT_INDEX = 10;
        private static final int FILL_TYPE_INDEX = 11;

        private static final int LINECAP_BUTT = 0;
        private static final int LINECAP_ROUND = 1;
        private static final int LINECAP_SQUARE = 2;

        private static final int LINEJOIN_MITER = 0;
        private static final int LINEJOIN_ROUND = 1;
        private static final int LINEJOIN_BEVEL = 2;

        @NonNull
        public Consumer<Float> getFloatPropertySetter(int propertyIdx) {
            switch (propertyIdx) {
                case STROKE_WIDTH_INDEX:
                    return this::setStrokeWidth;
                case STROKE_ALPHA_INDEX:
                    return this::setStrokeAlpha;
                case FILL_ALPHA_INDEX:
                    return this::setFillAlpha;
                case TRIM_PATH_START_INDEX:
                    return this::setTrimPathStart;
                case TRIM_PATH_END_INDEX:
                    return this::setTrimPathEnd;
                case TRIM_PATH_OFFSET_INDEX:
                    return this::setTrimPathOffset;
            }

            assert false : ("Invalid VFullPath_Delegate property index " + propertyIdx);
            return t -> {};
        }

        @NonNull
        public Consumer<Integer> getIntPropertySetter(int propertyIdx) {
            switch (propertyIdx) {
                case STROKE_COLOR_INDEX:
                    return this::setStrokeColor;
                case FILL_COLOR_INDEX:
                    return this::setFillColor;
            }

            assert false : ("Invalid VFullPath_Delegate property index " + propertyIdx);
            return t -> {};
        }

        /////////////////////////////////////////////////////
        // Variables below need to be copied (deep copy if applicable) for mutation.

        int mStrokeColor = Color.TRANSPARENT;
        float mStrokeWidth = 0;

        int mFillColor = Color.TRANSPARENT;
        long mStrokeGradient = 0;
        long mFillGradient = 0;
        float mStrokeAlpha = 1.0f;
        float mFillAlpha = 1.0f;
        float mTrimPathStart = 0;
        float mTrimPathEnd = 1;
        float mTrimPathOffset = 0;

        Cap mStrokeLineCap = BUTT;
        Join mStrokeLineJoin = MITER;
        float mStrokeMiterlimit = 4;

        int mFillType = 0; // WINDING(0) is the default value. See Path.FillType

        private VFullPath_Delegate() {
            // Empty constructor.
        }

        private VFullPath_Delegate(VFullPath_Delegate copy) {
            super(copy);

            mStrokeColor = copy.mStrokeColor;
            mStrokeWidth = copy.mStrokeWidth;
            mStrokeAlpha = copy.mStrokeAlpha;
            mFillColor = copy.mFillColor;
            mFillAlpha = copy.mFillAlpha;
            mTrimPathStart = copy.mTrimPathStart;
            mTrimPathEnd = copy.mTrimPathEnd;
            mTrimPathOffset = copy.mTrimPathOffset;

            mStrokeLineCap = copy.mStrokeLineCap;
            mStrokeLineJoin = copy.mStrokeLineJoin;
            mStrokeMiterlimit = copy.mStrokeMiterlimit;

            mStrokeGradient = copy.mStrokeGradient;
            mFillGradient = copy.mFillGradient;
            mFillType = copy.mFillType;
        }

        private int getStrokeLineCap() {
            switch (mStrokeLineCap) {
                case BUTT:
                    return LINECAP_BUTT;
                case ROUND:
                    return LINECAP_ROUND;
                case SQUARE:
                    return LINECAP_SQUARE;
                default:
                    assert false;
            }

            return -1;
        }

        private void setStrokeLineCap(int cap) {
            switch (cap) {
                case LINECAP_BUTT:
                    mStrokeLineCap = BUTT;
                    break;
                case LINECAP_ROUND:
                    mStrokeLineCap = ROUND;
                    break;
                case LINECAP_SQUARE:
                    mStrokeLineCap = SQUARE;
                    break;
                default:
                    assert false;
            }
        }

        private int getStrokeLineJoin() {
            switch (mStrokeLineJoin) {
                case MITER:
                    return LINEJOIN_MITER;
                case ROUND:
                    return LINEJOIN_ROUND;
                case BEVEL:
                    return LINEJOIN_BEVEL;
                default:
                    assert false;
            }

            return -1;
        }

        private void setStrokeLineJoin(int join) {
            switch (join) {
                case LINEJOIN_BEVEL:
                    mStrokeLineJoin = BEVEL;
                    break;
                case LINEJOIN_MITER:
                    mStrokeLineJoin = MITER;
                    break;
                case LINEJOIN_ROUND:
                    mStrokeLineJoin = Join.ROUND;
                    break;
                default:
                    assert false;
            }
        }

        private int getStrokeColor() {
            return mStrokeColor;
        }

        private void setStrokeColor(int strokeColor) {
            mStrokeColor = strokeColor;
        }

        private float getStrokeWidth() {
            return mStrokeWidth;
        }

        private void setStrokeWidth(float strokeWidth) {
            mStrokeWidth = strokeWidth;
        }

        private float getStrokeAlpha() {
            return mStrokeAlpha;
        }

        private void setStrokeAlpha(float strokeAlpha) {
            mStrokeAlpha = strokeAlpha;
        }

        private int getFillColor() {
            return mFillColor;
        }

        private void setFillColor(int fillColor) {
            mFillColor = fillColor;
        }

        private float getFillAlpha() {
            return mFillAlpha;
        }

        private void setFillAlpha(float fillAlpha) {
            mFillAlpha = fillAlpha;
        }

        private float getTrimPathStart() {
            return mTrimPathStart;
        }

        private void setTrimPathStart(float trimPathStart) {
            mTrimPathStart = trimPathStart;
        }

        private float getTrimPathEnd() {
            return mTrimPathEnd;
        }

        private void setTrimPathEnd(float trimPathEnd) {
            mTrimPathEnd = trimPathEnd;
        }

        private float getTrimPathOffset() {
            return mTrimPathOffset;
        }

        private void setTrimPathOffset(float trimPathOffset) {
            mTrimPathOffset = trimPathOffset;
        }

        private void setStrokeMiterlimit(float limit) {
            mStrokeMiterlimit = limit;
        }

        private float getStrokeMiterlimit() {
            return mStrokeMiterlimit;
        }

        private void setStrokeGradient(long gradientPtr) {
            mStrokeGradient = gradientPtr;
        }

        private void setFillGradient(long gradientPtr) {
            mFillGradient = gradientPtr;
        }

        private void setFillType(int fillType) {
            mFillType = fillType;
        }

        private int getFillType() {
            return mFillType;
        }
    }

    static class VGroup_Delegate extends VNativeObject {
        // This constants need to be kept in sync with their definitions in VectorDrawable.Group
        private static final int ROTATE_INDEX = 0;
        private static final int PIVOT_X_INDEX = 1;
        private static final int PIVOT_Y_INDEX = 2;
        private static final int SCALE_X_INDEX = 3;
        private static final int SCALE_Y_INDEX = 4;
        private static final int TRANSLATE_X_INDEX = 5;
        private static final int TRANSLATE_Y_INDEX = 6;

        public Consumer<Float> getPropertySetter(int propertyIdx) {
            switch (propertyIdx) {
                case ROTATE_INDEX:
                    return this::setRotation;
                case PIVOT_X_INDEX:
                    return this::setPivotX;
                case PIVOT_Y_INDEX:
                    return this::setPivotY;
                case SCALE_X_INDEX:
                    return this::setScaleX;
                case SCALE_Y_INDEX:
                    return this::setScaleY;
                case TRANSLATE_X_INDEX:
                    return this::setTranslateX;
                case TRANSLATE_Y_INDEX:
                    return this::setTranslateY;
            }

            assert false : ("Invalid VGroup_Delegate property index " + propertyIdx);
            return t -> {};
        }

        /////////////////////////////////////////////////////
        // Variables below need to be copied (deep copy if applicable) for mutation.
        final ArrayList<Object> mChildren = new ArrayList<>();
        // mStackedMatrix is only used temporarily when drawing, it combines all
        // the parents' local matrices with the current one.
        private final Matrix mStackedMatrix = new Matrix();
        // mLocalMatrix is updated based on the update of transformation information,
        // either parsed from the XML or by animation.
        private final Matrix mLocalMatrix = new Matrix();
        private float mRotate = 0;
        private float mPivotX = 0;
        private float mPivotY = 0;
        private float mScaleX = 1;
        private float mScaleY = 1;
        private float mTranslateX = 0;
        private float mTranslateY = 0;
        private int mChangingConfigurations;
        private String mGroupName = null;

        private VGroup_Delegate(VGroup_Delegate copy, ArrayMap<String, Object> targetsMap) {
            mRotate = copy.mRotate;
            mPivotX = copy.mPivotX;
            mPivotY = copy.mPivotY;
            mScaleX = copy.mScaleX;
            mScaleY = copy.mScaleY;
            mTranslateX = copy.mTranslateX;
            mTranslateY = copy.mTranslateY;
            mGroupName = copy.mGroupName;
            mChangingConfigurations = copy.mChangingConfigurations;
            if (mGroupName != null) {
                targetsMap.put(mGroupName, this);
            }

            mLocalMatrix.set(copy.mLocalMatrix);
        }

        private VGroup_Delegate() {
        }

        private void updateLocalMatrix() {
            // The order we apply is the same as the
            // RenderNode.cpp::applyViewPropertyTransforms().
            mLocalMatrix.reset();
            mLocalMatrix.postTranslate(-mPivotX, -mPivotY);
            mLocalMatrix.postScale(mScaleX, mScaleY);
            mLocalMatrix.postRotate(mRotate, 0, 0);
            mLocalMatrix.postTranslate(mTranslateX + mPivotX, mTranslateY + mPivotY);
        }

        /* Setters and Getters, used by animator from AnimatedVectorDrawable. */
        private float getRotation() {
            return mRotate;
        }

        private void setRotation(float rotation) {
            if (rotation != mRotate) {
                mRotate = rotation;
                updateLocalMatrix();
            }
        }

        private float getPivotX() {
            return mPivotX;
        }

        private void setPivotX(float pivotX) {
            if (pivotX != mPivotX) {
                mPivotX = pivotX;
                updateLocalMatrix();
            }
        }

        private float getPivotY() {
            return mPivotY;
        }

        private void setPivotY(float pivotY) {
            if (pivotY != mPivotY) {
                mPivotY = pivotY;
                updateLocalMatrix();
            }
        }

        private float getScaleX() {
            return mScaleX;
        }

        private void setScaleX(float scaleX) {
            if (scaleX != mScaleX) {
                mScaleX = scaleX;
                updateLocalMatrix();
            }
        }

        private float getScaleY() {
            return mScaleY;
        }

        private void setScaleY(float scaleY) {
            if (scaleY != mScaleY) {
                mScaleY = scaleY;
                updateLocalMatrix();
            }
        }

        private float getTranslateX() {
            return mTranslateX;
        }

        private void setTranslateX(float translateX) {
            if (translateX != mTranslateX) {
                mTranslateX = translateX;
                updateLocalMatrix();
            }
        }

        private float getTranslateY() {
            return mTranslateY;
        }

        private void setTranslateY(float translateY) {
            if (translateY != mTranslateY) {
                mTranslateY = translateY;
                updateLocalMatrix();
            }
        }

        @Override
        public void setName(String name) {
            mGroupName = name;
        }

        @Override
        protected void dispose() {
            mChildren.stream().filter(child -> child instanceof VNativeObject).forEach(child
                    -> {
                VNativeObject nativeObject = (VNativeObject) child;
                if (nativeObject.mNativePtr != 0) {
                    sPathManager.removeJavaReferenceFor(nativeObject.mNativePtr);
                    nativeObject.mNativePtr = 0;
                }
                nativeObject.dispose();
            });
            mChildren.clear();
        }

        @Override
        protected void finalize() throws Throwable {
            super.finalize();
        }
    }

    public static class VPath_Delegate extends VNativeObject {
        protected PathParser_Delegate.PathDataNode[] mNodes = null;
        String mPathName;
        int mChangingConfigurations;

        public VPath_Delegate() {
            // Empty constructor.
        }

        public VPath_Delegate(VPath_Delegate copy) {
            mPathName = copy.mPathName;
            mChangingConfigurations = copy.mChangingConfigurations;
            mNodes = copy.mNodes != null ? PathParser_Delegate.deepCopyNodes(copy.mNodes) : null;
        }

        public void toPath(Path path) {
            path.reset();
            if (mNodes != null) {
                PathParser_Delegate.PathDataNode.nodesToPath(mNodes,
                        Path_Delegate.getDelegate(path.mNativePath));
            }
        }

        @Override
        public void setName(String name) {
            mPathName = name;
        }

        public boolean isClipPath() {
            return false;
        }

        private void setPathData(PathParser_Delegate.PathDataNode[] nodes) {
            if (!PathParser_Delegate.canMorph(mNodes, nodes)) {
                // This should not happen in the middle of animation.
                mNodes = PathParser_Delegate.deepCopyNodes(nodes);
            } else {
                PathParser_Delegate.updateNodes(mNodes, nodes);
            }
        }

        @Override
        void dispose() {
            mNodes = null;
        }
    }

    static class VPathRenderer_Delegate extends VNativeObject {
        /* Right now the internal data structure is organized as a tree.
         * Each node can be a group node, or a path.
         * A group node can have groups or paths as children, but a path node has
         * no children.
         * One example can be:
         *                 Root Group
         *                /    |     \
         *           Group    Path    Group
         *          /     \             |
         *         Path   Path         Path
         *
         */
        // Variables that only used temporarily inside the draw() call, so there
        // is no need for deep copying.
        private final Path mPath;
        private final Path mRenderPath;
        private final Matrix mFinalPathMatrix = new Matrix();
        private final long mRootGroupPtr;
        private float mViewportWidth = 0;
        private float mViewportHeight = 0;
        private float mRootAlpha = 1.0f;
        private Paint mStrokePaint;
        private Paint mFillPaint;
        private PathMeasure mPathMeasure;
        private boolean mAntiAlias = true;

        private VPathRenderer_Delegate(long rootGroupPtr) {
            mRootGroupPtr = rootGroupPtr;
            mPath = new Path();
            mRenderPath = new Path();
        }

        private VPathRenderer_Delegate(VPathRenderer_Delegate rendererToCopy,
                long rootGroupPtr) {
            this(rootGroupPtr);
            mViewportWidth = rendererToCopy.mViewportWidth;
            mViewportHeight = rendererToCopy.mViewportHeight;
            mRootAlpha = rendererToCopy.mRootAlpha;
        }

        private float getRootAlpha() {
            return mRootAlpha;
        }

        void setRootAlpha(float alpha) {
            mRootAlpha = alpha;
        }

        private void drawGroupTree(VGroup_Delegate currentGroup, Matrix currentMatrix,
                long canvasPtr, int w, int h, long filterPtr) {
            // Calculate current group's matrix by preConcat the parent's and
            // and the current one on the top of the stack.
            // Basically the Mfinal = Mviewport * M0 * M1 * M2;
            // Mi the local matrix at level i of the group tree.
            currentGroup.mStackedMatrix.set(currentMatrix);
            currentGroup.mStackedMatrix.preConcat(currentGroup.mLocalMatrix);

            // Save the current clip information, which is local to this group.
            Canvas_Delegate.nSave(canvasPtr, MATRIX_SAVE_FLAG | CLIP_SAVE_FLAG);
            // Draw the group tree in the same order as the XML file.
            for (int i = 0; i < currentGroup.mChildren.size(); i++) {
                Object child = currentGroup.mChildren.get(i);
                if (child instanceof VGroup_Delegate) {
                    VGroup_Delegate childGroup = (VGroup_Delegate) child;
                    drawGroupTree(childGroup, currentGroup.mStackedMatrix,
                            canvasPtr, w, h, filterPtr);
                } else if (child instanceof VPath_Delegate) {
                    VPath_Delegate childPath = (VPath_Delegate) child;
                    drawPath(currentGroup, childPath, canvasPtr, w, h, filterPtr);
                }
            }
            Canvas_Delegate.nRestore(canvasPtr);
        }

        public void draw(long canvasPtr, long filterPtr, int w, int h) {
            // Traverse the tree in pre-order to draw.
            drawGroupTree(VNativeObject.getDelegate(mRootGroupPtr), Matrix.IDENTITY_MATRIX, canvasPtr, w, h, filterPtr);
        }

        private void drawPath(VGroup_Delegate VGroup, VPath_Delegate VPath, long canvasPtr,
                int w,
                int h,
                long filterPtr) {
            final float scaleX = w / mViewportWidth;
            final float scaleY = h / mViewportHeight;
            final float minScale = Math.min(scaleX, scaleY);
            final Matrix groupStackedMatrix = VGroup.mStackedMatrix;

            mFinalPathMatrix.set(groupStackedMatrix);
            mFinalPathMatrix.postScale(scaleX, scaleY);

            final float matrixScale = getMatrixScale(groupStackedMatrix);
            if (matrixScale == 0) {
                // When either x or y is scaled to 0, we don't need to draw anything.
                return;
            }
            VPath.toPath(mPath);
            final Path path = mPath;

            mRenderPath.reset();

            if (VPath.isClipPath()) {
                mRenderPath.setFillType(FillType.WINDING);
                mRenderPath.addPath(path, mFinalPathMatrix);
                Canvas_Delegate.nClipPath(canvasPtr, mRenderPath.mNativePath, Op
                        .INTERSECT.nativeInt);
            } else {
                VFullPath_Delegate fullPath = (VFullPath_Delegate) VPath;
                if (fullPath.mTrimPathStart != 0.0f || fullPath.mTrimPathEnd != 1.0f) {
                    float start = (fullPath.mTrimPathStart + fullPath.mTrimPathOffset) % 1.0f;
                    float end = (fullPath.mTrimPathEnd + fullPath.mTrimPathOffset) % 1.0f;

                    if (mPathMeasure == null) {
                        mPathMeasure = new PathMeasure();
                    }
                    mPathMeasure.setPath(mPath, false);

                    float len = mPathMeasure.getLength();
                    start = start * len;
                    end = end * len;
                    path.reset();
                    if (start > end) {
                        mPathMeasure.getSegment(start, len, path, true);
                        mPathMeasure.getSegment(0f, end, path, true);
                    } else {
                        mPathMeasure.getSegment(start, end, path, true);
                    }
                    path.rLineTo(0, 0); // fix bug in measure
                }
                mRenderPath.addPath(path, mFinalPathMatrix);

                if (fullPath.mFillColor != Color.TRANSPARENT) {
                    if (mFillPaint == null) {
                        mFillPaint = new Paint();
                        mFillPaint.setStyle(Style.FILL);
                        mFillPaint.setAntiAlias(mAntiAlias);
                    }

                    final Paint fillPaint = mFillPaint;
                    fillPaint.setColor(applyAlpha(applyAlpha(fullPath.mFillColor, fullPath
                      .mFillAlpha), getRootAlpha()));
                    Paint_Delegate fillPaintDelegate = Paint_Delegate.getDelegate(fillPaint
                            .getNativeInstance());
                    // mFillPaint can not be null at this point so we will have a delegate
                    assert fillPaintDelegate != null;
                    fillPaintDelegate.setColorFilter(filterPtr);

                    Shader_Delegate shaderDelegate =
                            Shader_Delegate.getDelegate(fullPath.mFillGradient);
                    if (shaderDelegate != null) {
                        // If there is a shader, apply the local transformation to make sure
                        // the gradient is transformed to match the viewport
                        shaderDelegate.setLocalMatrix(mFinalPathMatrix.native_instance);
                        shaderDelegate.setAlpha(fullPath.mFillAlpha);
                    }

                    fillPaintDelegate.setShader(fullPath.mFillGradient);
                    Path_Delegate.nSetFillType(mRenderPath.mNativePath, fullPath.mFillType);
                    BaseCanvas_Delegate.nDrawPath(canvasPtr, mRenderPath.mNativePath, fillPaint
                            .getNativeInstance());
                    if (shaderDelegate != null) {
                        // Remove the local matrix
                        shaderDelegate.setLocalMatrix(0);
                    }
                }

                if (fullPath.mStrokeColor != Color.TRANSPARENT) {
                    if (mStrokePaint == null) {
                        mStrokePaint = new Paint();
                        mStrokePaint.setStyle(Style.STROKE);
                        mStrokePaint.setAntiAlias(mAntiAlias);
                    }

                    final Paint strokePaint = mStrokePaint;
                    if (fullPath.mStrokeLineJoin != null) {
                        strokePaint.setStrokeJoin(fullPath.mStrokeLineJoin);
                    }

                    if (fullPath.mStrokeLineCap != null) {
                        strokePaint.setStrokeCap(fullPath.mStrokeLineCap);
                    }

                    strokePaint.setStrokeMiter(fullPath.mStrokeMiterlimit);
                    strokePaint.setColor(applyAlpha(applyAlpha(fullPath.mStrokeColor, fullPath
                      .mStrokeAlpha), getRootAlpha()));
                    Paint_Delegate strokePaintDelegate = Paint_Delegate.getDelegate(strokePaint
                            .getNativeInstance());
                    // mStrokePaint can not be null at this point so we will have a delegate
                    assert strokePaintDelegate != null;
                    strokePaintDelegate.setColorFilter(filterPtr);
                    final float finalStrokeScale = minScale * matrixScale;
                    strokePaint.setStrokeWidth(fullPath.mStrokeWidth * finalStrokeScale);
                    Shader_Delegate strokeShaderDelegate =
                            Shader_Delegate.getDelegate(fullPath.mStrokeGradient);
                    if (strokeShaderDelegate != null) {
                        strokeShaderDelegate.setAlpha(fullPath.mStrokeAlpha);
                    }
                    strokePaintDelegate.setShader(fullPath.mStrokeGradient);
                    BaseCanvas_Delegate.nDrawPath(canvasPtr, mRenderPath.mNativePath, strokePaint
                            .getNativeInstance());
                }
            }
        }

        private float getMatrixScale(Matrix groupStackedMatrix) {
            // Given unit vectors A = (0, 1) and B = (1, 0).
            // After matrix mapping, we got A' and B'. Let theta = the angel b/t A' and B'.
            // Therefore, the final scale we want is min(|A'| * sin(theta), |B'| * sin(theta)),
            // which is (|A'| * |B'| * sin(theta)) / max (|A'|, |B'|);
            // If  max (|A'|, |B'|) = 0, that means either x or y has a scale of 0.
            //
            // For non-skew case, which is most of the cases, matrix scale is computing exactly the
            // scale on x and y axis, and take the minimal of these two.
            // For skew case, an unit square will mapped to a parallelogram. And this function will
            // return the minimal height of the 2 bases.
            float[] unitVectors = new float[]{0, 1, 1, 0};
            groupStackedMatrix.mapVectors(unitVectors);
            float scaleX = MathUtils.mag(unitVectors[0], unitVectors[1]);
            float scaleY = MathUtils.mag(unitVectors[2], unitVectors[3]);
            float crossProduct = MathUtils.cross(unitVectors[0], unitVectors[1],
                    unitVectors[2], unitVectors[3]);
            float maxScale = MathUtils.max(scaleX, scaleY);

            float matrixScale = 0;
            if (maxScale > 0) {
                matrixScale = MathUtils.abs(crossProduct) / maxScale;
            }
            if (DBG_VECTOR_DRAWABLE) {
                Log.d(LOGTAG, "Scale x " + scaleX + " y " + scaleY + " final " + matrixScale);
            }
            return matrixScale;
        }

        private void setAntiAlias(boolean aa) {
            mAntiAlias = aa;
        }

        @Override
        public void setName(String name) {
        }

        @Override
        protected void finalize() throws Throwable {
            // The mRootGroupPtr is not explicitly freed by anything in the VectorDrawable so we
            // need to free it here.
            VNativeObject nativeObject = sPathManager.getDelegate(mRootGroupPtr);
            sPathManager.removeJavaReferenceFor(mRootGroupPtr);
            assert nativeObject != null;
            nativeObject.dispose();

            super.finalize();
        }
    }
}
