/*
 * Copyright (C) 2010 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;


import com.android.ide.common.rendering.api.LayoutLog;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.impl.DelegateManager;
import com.android.tools.layoutlib.annotations.LayoutlibDelegate;

import android.graphics.Matrix.ScaleToFit;

import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;

import libcore.util.NativeAllocationRegistry_Delegate;

/**
 * Delegate implementing the native methods of android.graphics.Matrix
 *
 * Through the layoutlib_create tool, the original native methods of Matrix have been replaced
 * by calls to methods of the same name in this delegate class.
 *
 * This class behaves like the original native implementation, but in Java, keeping previously
 * native data into its own objects and mapping them to int that are sent back and forth between
 * it and the original Matrix class.
 *
 * @see DelegateManager
 *
 */
public final class Matrix_Delegate {

    private final static int MATRIX_SIZE = 9;

    // ---- delegate manager ----
    private static final DelegateManager<Matrix_Delegate> sManager =
            new DelegateManager<Matrix_Delegate>(Matrix_Delegate.class);
    private static long sFinalizer = -1;

    // ---- delegate data ----
    private float mValues[] = new float[MATRIX_SIZE];

    // ---- Public Helper methods ----

    public static Matrix_Delegate getDelegate(long native_instance) {
        return sManager.getDelegate(native_instance);
    }

    /**
     * Returns an {@link AffineTransform} matching the given Matrix.
     */
    public static AffineTransform getAffineTransform(Matrix m) {
        Matrix_Delegate delegate = sManager.getDelegate(m.native_instance);
        if (delegate == null) {
            return null;
        }

        return delegate.getAffineTransform();
    }

    public static boolean hasPerspective(Matrix m) {
        Matrix_Delegate delegate = sManager.getDelegate(m.native_instance);
        if (delegate == null) {
            return false;
        }

        return delegate.hasPerspective();
    }

    /**
     * Sets the content of the matrix with the content of another matrix.
     */
    public void set(Matrix_Delegate matrix) {
        System.arraycopy(matrix.mValues, 0, mValues, 0, MATRIX_SIZE);
    }

    /**
     * Sets the content of the matrix with the content of another matrix represented as an array
     * of values.
     */
    public void set(float[] values) {
        System.arraycopy(values, 0, mValues, 0, MATRIX_SIZE);
    }

    /**
     * Resets the matrix to be the identity matrix.
     */
    public void reset() {
        reset(mValues);
    }

    /**
     * Returns whether or not the matrix is identity.
     */
    public boolean isIdentity() {
        for (int i = 0, k = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++, k++) {
                if (mValues[k] != ((i==j) ? 1 : 0)) {
                    return false;
                }
            }
        }

        return true;
    }

    private static float[] setValues(AffineTransform matrix, float[] values) {
        values[0] = (float) matrix.getScaleX();
        values[1] = (float) matrix.getShearX();
        values[2] = (float) matrix.getTranslateX();
        values[3] = (float) matrix.getShearY();
        values[4] = (float) matrix.getScaleY();
        values[5] = (float) matrix.getTranslateY();
        values[6] = 0.f;
        values[7] = 0.f;
        values[8] = 1.f;

        return values;
    }

    public static float[] makeValues(AffineTransform matrix) {
        return setValues(matrix, new float[MATRIX_SIZE]);
    }

    public static Matrix_Delegate make(AffineTransform matrix) {
        return new Matrix_Delegate(makeValues(matrix));
    }

    public boolean mapRect(RectF dst, RectF src) {
        // array with 4 corners
        float[] corners = new float[] {
                src.left, src.top,
                src.right, src.top,
                src.right, src.bottom,
                src.left, src.bottom,
        };

        // apply the transform to them.
        mapPoints(corners);

        // now put the result in the rect. We take the min/max of Xs and min/max of Ys
        dst.left = Math.min(Math.min(corners[0], corners[2]), Math.min(corners[4], corners[6]));
        dst.right = Math.max(Math.max(corners[0], corners[2]), Math.max(corners[4], corners[6]));

        dst.top = Math.min(Math.min(corners[1], corners[3]), Math.min(corners[5], corners[7]));
        dst.bottom = Math.max(Math.max(corners[1], corners[3]), Math.max(corners[5], corners[7]));


        return (computeTypeMask() & kRectStaysRect_Mask) != 0;
    }


    /**
     * Returns an {@link AffineTransform} matching the matrix.
     */
    public AffineTransform getAffineTransform() {
        return getAffineTransform(mValues);
    }

    public boolean hasPerspective() {
        return (mValues[6] != 0 || mValues[7] != 0 || mValues[8] != 1);
    }



    // ---- native methods ----

    @LayoutlibDelegate
    /*package*/ static long nCreate(long native_src_or_zero) {
        // create the delegate
        Matrix_Delegate newDelegate = new Matrix_Delegate();

        // copy from values if needed.
        if (native_src_or_zero > 0) {
            Matrix_Delegate oldDelegate = sManager.getDelegate(native_src_or_zero);
            if (oldDelegate != null) {
                System.arraycopy(
                        oldDelegate.mValues, 0,
                        newDelegate.mValues, 0,
                        MATRIX_SIZE);
            }
        }

        return sManager.addNewDelegate(newDelegate);
    }

    @LayoutlibDelegate
    /*package*/ static boolean nIsIdentity(long native_object) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d == null) {
            return false;
        }

        return d.isIdentity();
    }

    @LayoutlibDelegate
    /*package*/ static boolean nIsAffine(long native_object) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d == null) {
            return true;
        }

        return (d.computeTypeMask() & kPerspective_Mask) == 0;
    }

    @LayoutlibDelegate
    /*package*/ static boolean nRectStaysRect(long native_object) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d == null) {
            return true;
        }

        return (d.computeTypeMask() & kRectStaysRect_Mask) != 0;
    }

    @LayoutlibDelegate
    /*package*/ static void nReset(long native_object) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d == null) {
            return;
        }

        reset(d.mValues);
    }

    @LayoutlibDelegate
    /*package*/ static void nSet(long native_object, long other) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d == null) {
            return;
        }

        Matrix_Delegate src = sManager.getDelegate(other);
        if (src == null) {
            return;
        }

        System.arraycopy(src.mValues, 0, d.mValues, 0, MATRIX_SIZE);
    }

    @LayoutlibDelegate
    /*package*/ static void nSetTranslate(long native_object, float dx, float dy) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d == null) {
            return;
        }

        setTranslate(d.mValues, dx, dy);
    }

    @LayoutlibDelegate
    /*package*/ static void nSetScale(long native_object, float sx, float sy,
            float px, float py) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d == null) {
            return;
        }

        d.mValues = getScale(sx, sy, px, py);
    }

    @LayoutlibDelegate
    /*package*/ static void nSetScale(long native_object, float sx, float sy) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d == null) {
            return;
        }

        d.mValues[0] = sx;
        d.mValues[1] = 0;
        d.mValues[2] = 0;
        d.mValues[3] = 0;
        d.mValues[4] = sy;
        d.mValues[5] = 0;
        d.mValues[6] = 0;
        d.mValues[7] = 0;
        d.mValues[8] = 1;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetRotate(long native_object, float degrees, float px, float py) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d == null) {
            return;
        }

        d.mValues = getRotate(degrees, px, py);
    }

    @LayoutlibDelegate
    /*package*/ static void nSetRotate(long native_object, float degrees) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d == null) {
            return;
        }

        setRotate(d.mValues, degrees);
    }

    @LayoutlibDelegate
    /*package*/ static void nSetSinCos(long native_object, float sinValue, float cosValue,
            float px, float py) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d == null) {
            return;
        }

        // TODO: do it in one pass

        // translate so that the pivot is in 0,0
        setTranslate(d.mValues, -px, -py);

        // scale
        d.postTransform(getRotate(sinValue, cosValue));
        // translate back the pivot
        d.postTransform(getTranslate(px, py));
    }

    @LayoutlibDelegate
    /*package*/ static void nSetSinCos(long native_object, float sinValue, float cosValue) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d == null) {
            return;
        }

        setRotate(d.mValues, sinValue, cosValue);
    }

    @LayoutlibDelegate
    /*package*/ static void nSetSkew(long native_object, float kx, float ky,
            float px, float py) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d == null) {
            return;
        }

        d.mValues = getSkew(kx, ky, px, py);
    }

    @LayoutlibDelegate
    /*package*/ static void nSetSkew(long native_object, float kx, float ky) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d == null) {
            return;
        }

        d.mValues[0] = 1;
        d.mValues[1] = kx;
        d.mValues[2] = -0;
        d.mValues[3] = ky;
        d.mValues[4] = 1;
        d.mValues[5] = 0;
        d.mValues[6] = 0;
        d.mValues[7] = 0;
        d.mValues[8] = 1;
    }

    @LayoutlibDelegate
    /*package*/ static void nSetConcat(long native_object, long a, long b) {
        if (a == native_object) {
            nPreConcat(native_object, b);
            return;
        } else if (b == native_object) {
            nPostConcat(native_object, a);
            return;
        }

        Matrix_Delegate d = sManager.getDelegate(native_object);
        Matrix_Delegate a_mtx = sManager.getDelegate(a);
        Matrix_Delegate b_mtx = sManager.getDelegate(b);
        if (d != null && a_mtx != null && b_mtx != null) {
            multiply(d.mValues, a_mtx.mValues, b_mtx.mValues);
        }
    }

    @LayoutlibDelegate
    /*package*/ static void nPreTranslate(long native_object, float dx, float dy) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d != null) {
            d.preTransform(getTranslate(dx, dy));
        }
    }

    @LayoutlibDelegate
    /*package*/ static void nPreScale(long native_object, float sx, float sy,
            float px, float py) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d != null) {
            d.preTransform(getScale(sx, sy, px, py));
        }
    }

    @LayoutlibDelegate
    /*package*/ static void nPreScale(long native_object, float sx, float sy) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d != null) {
            d.preTransform(getScale(sx, sy));
        }
    }

    @LayoutlibDelegate
    /*package*/ static void nPreRotate(long native_object, float degrees,
            float px, float py) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d != null) {
            d.preTransform(getRotate(degrees, px, py));
        }
    }

    @LayoutlibDelegate
    /*package*/ static void nPreRotate(long native_object, float degrees) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d != null) {

            double rad = Math.toRadians(degrees);
            float sin = (float) Math.sin(rad);
            float cos = (float) Math.cos(rad);

            d.preTransform(getRotate(sin, cos));
        }
    }

    @LayoutlibDelegate
    /*package*/ static void nPreSkew(long native_object, float kx, float ky,
            float px, float py) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d != null) {
            d.preTransform(getSkew(kx, ky, px, py));
        }
    }

    @LayoutlibDelegate
    /*package*/ static void nPreSkew(long native_object, float kx, float ky) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d != null) {
            d.preTransform(getSkew(kx, ky));
        }
    }

    @LayoutlibDelegate
    /*package*/ static void nPreConcat(long native_object, long other_matrix) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        Matrix_Delegate other = sManager.getDelegate(other_matrix);
        if (d != null && other != null) {
            d.preTransform(other.mValues);
        }
    }

    @LayoutlibDelegate
    /*package*/ static void nPostTranslate(long native_object, float dx, float dy) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d != null) {
            d.postTransform(getTranslate(dx, dy));
        }
    }

    @LayoutlibDelegate
    /*package*/ static void nPostScale(long native_object, float sx, float sy,
            float px, float py) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d != null) {
            d.postTransform(getScale(sx, sy, px, py));
        }
    }

    @LayoutlibDelegate
    /*package*/ static void nPostScale(long native_object, float sx, float sy) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d != null) {
            d.postTransform(getScale(sx, sy));
        }
    }

    @LayoutlibDelegate
    /*package*/ static void nPostRotate(long native_object, float degrees,
            float px, float py) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d != null) {
            d.postTransform(getRotate(degrees, px, py));
        }
    }

    @LayoutlibDelegate
    /*package*/ static void nPostRotate(long native_object, float degrees) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d != null) {
            d.postTransform(getRotate(degrees));
        }
    }

    @LayoutlibDelegate
    /*package*/ static void nPostSkew(long native_object, float kx, float ky,
            float px, float py) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d != null) {
            d.postTransform(getSkew(kx, ky, px, py));
        }
    }

    @LayoutlibDelegate
    /*package*/ static void nPostSkew(long native_object, float kx, float ky) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d != null) {
            d.postTransform(getSkew(kx, ky));
        }
    }

    @LayoutlibDelegate
    /*package*/ static void nPostConcat(long native_object, long other_matrix) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        Matrix_Delegate other = sManager.getDelegate(other_matrix);
        if (d != null && other != null) {
            d.postTransform(other.mValues);
        }
    }

    @LayoutlibDelegate
    /*package*/ static boolean nSetRectToRect(long native_object, RectF src,
            RectF dst, int stf) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d == null) {
            return false;
        }

        if (src.isEmpty()) {
            reset(d.mValues);
            return false;
        }

        if (dst.isEmpty()) {
            d.mValues[0] = d.mValues[1] = d.mValues[2] = d.mValues[3] = d.mValues[4] = d.mValues[5]
               = d.mValues[6] = d.mValues[7] = 0;
            d.mValues[8] = 1;
        } else {
            float    tx, sx = dst.width() / src.width();
            float    ty, sy = dst.height() / src.height();
            boolean  xLarger = false;

            if (stf != ScaleToFit.FILL.nativeInt) {
                if (sx > sy) {
                    xLarger = true;
                    sx = sy;
                } else {
                    sy = sx;
                }
            }

            tx = dst.left - src.left * sx;
            ty = dst.top - src.top * sy;
            if (stf == ScaleToFit.CENTER.nativeInt || stf == ScaleToFit.END.nativeInt) {
                float diff;

                if (xLarger) {
                    diff = dst.width() - src.width() * sy;
                } else {
                    diff = dst.height() - src.height() * sy;
                }

                if (stf == ScaleToFit.CENTER.nativeInt) {
                    diff = diff / 2;
                }

                if (xLarger) {
                    tx += diff;
                } else {
                    ty += diff;
                }
            }

            d.mValues[0] = sx;
            d.mValues[4] = sy;
            d.mValues[2] = tx;
            d.mValues[5] = ty;
            d.mValues[1]  = d.mValues[3] = d.mValues[6] = d.mValues[7] = 0;

        }
        // shared cleanup
        d.mValues[8] = 1;
        return true;
    }

    @LayoutlibDelegate
    /*package*/ static boolean nSetPolyToPoly(long native_object, float[] src, int srcIndex,
            float[] dst, int dstIndex, int pointCount) {
        // FIXME
        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
                "Matrix.setPolyToPoly is not supported.",
                null, null /*data*/);
        return false;
    }

    @LayoutlibDelegate
    /*package*/ static boolean nInvert(long native_object, long inverse) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d == null) {
            return false;
        }

        Matrix_Delegate inv_mtx = sManager.getDelegate(inverse);
        if (inv_mtx == null) {
            return false;
        }

        float det = d.mValues[0] * (d.mValues[4] * d.mValues[8] - d.mValues[5] * d.mValues[7])
                  + d.mValues[1] * (d.mValues[5] * d.mValues[6] - d.mValues[3] * d.mValues[8])
                  + d.mValues[2] * (d.mValues[3] * d.mValues[7] - d.mValues[4] * d.mValues[6]);

        if (det == 0.0) {
            return false;
        }

        inv_mtx.mValues[0] = (d.mValues[4] * d.mValues[8] - d.mValues[5] * d.mValues[7]) / det;
        inv_mtx.mValues[1] = (d.mValues[2] * d.mValues[7] - d.mValues[1] * d.mValues[8]) / det;
        inv_mtx.mValues[2] = (d.mValues[1] * d.mValues[5] - d.mValues[2] * d.mValues[4]) / det;
        inv_mtx.mValues[3] = (d.mValues[5] * d.mValues[6] - d.mValues[3] * d.mValues[8]) / det;
        inv_mtx.mValues[4] = (d.mValues[0] * d.mValues[8] - d.mValues[2] * d.mValues[6]) / det;
        inv_mtx.mValues[5] = (d.mValues[2] * d.mValues[3] - d.mValues[0] * d.mValues[5]) / det;
        inv_mtx.mValues[6] = (d.mValues[3] * d.mValues[7] - d.mValues[4] * d.mValues[6]) / det;
        inv_mtx.mValues[7] = (d.mValues[1] * d.mValues[6] - d.mValues[0] * d.mValues[7]) / det;
        inv_mtx.mValues[8] = (d.mValues[0] * d.mValues[4] - d.mValues[1] * d.mValues[3]) / det;

        return true;
    }

    @LayoutlibDelegate
    /*package*/ static void nMapPoints(long native_object, float[] dst, int dstIndex,
            float[] src, int srcIndex, int ptCount, boolean isPts) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d == null) {
            return;
        }

        if (isPts) {
            d.mapPoints(dst, dstIndex, src, srcIndex, ptCount);
        } else {
            d.mapVectors(dst, dstIndex, src, srcIndex, ptCount);
        }
    }

    @LayoutlibDelegate
    /*package*/ static boolean nMapRect(long native_object, RectF dst, RectF src) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d == null) {
            return false;
        }

        return d.mapRect(dst, src);
    }

    @LayoutlibDelegate
    /*package*/ static float nMapRadius(long native_object, float radius) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d == null) {
            return 0.f;
        }

        float[] src = new float[] { radius, 0.f, 0.f, radius };
        d.mapVectors(src, 0, src, 0, 2);

        float l1 = (float) Math.hypot(src[0], src[1]);
        float l2 = (float) Math.hypot(src[2], src[3]);
        return (float) Math.sqrt(l1 * l2);
    }

    @LayoutlibDelegate
    /*package*/ static void nGetValues(long native_object, float[] values) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d == null) {
            return;
        }

        System.arraycopy(d.mValues, 0, values, 0, MATRIX_SIZE);
    }

    @LayoutlibDelegate
    /*package*/ static void nSetValues(long native_object, float[] values) {
        Matrix_Delegate d = sManager.getDelegate(native_object);
        if (d == null) {
            return;
        }

        System.arraycopy(values, 0, d.mValues, 0, MATRIX_SIZE);
    }

    @LayoutlibDelegate
    /*package*/ static boolean nEquals(long native_a, long native_b) {
        Matrix_Delegate a = sManager.getDelegate(native_a);
        if (a == null) {
            return false;
        }

        Matrix_Delegate b = sManager.getDelegate(native_b);
        if (b == null) {
            return false;
        }

        for (int i = 0 ; i < MATRIX_SIZE ; i++) {
            if (a.mValues[i] != b.mValues[i]) {
                return false;
            }
        }

        return true;
    }

    @LayoutlibDelegate
    /*package*/ static long nGetNativeFinalizer() {
        synchronized (Matrix_Delegate.class) {
            if (sFinalizer == -1) {
                sFinalizer = NativeAllocationRegistry_Delegate.createFinalizer(sManager::removeJavaReferenceFor);
            }
        }
        return sFinalizer;
    }

    // ---- Private helper methods ----

    /*package*/ static AffineTransform getAffineTransform(float[] matrix) {
        // the AffineTransform constructor takes the value in a different order
        // for a matrix [ 0 1 2 ]
        //              [ 3 4 5 ]
        // the order is 0, 3, 1, 4, 2, 5...
        return new AffineTransform(
                matrix[0], matrix[3], matrix[1],
                matrix[4], matrix[2], matrix[5]);
    }

    /**
     * Reset a matrix to the identity
     */
    private static void reset(float[] mtx) {
        for (int i = 0, k = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++, k++) {
                mtx[k] = ((i==j) ? 1 : 0);
            }
        }
    }

    @SuppressWarnings("unused")
    private final static int kIdentity_Mask      = 0;
    private final static int kTranslate_Mask     = 0x01;  //!< set if the matrix has translation
    private final static int kScale_Mask         = 0x02;  //!< set if the matrix has X or Y scale
    private final static int kAffine_Mask        = 0x04;  //!< set if the matrix skews or rotates
    private final static int kPerspective_Mask   = 0x08;  //!< set if the matrix is in perspective
    private final static int kRectStaysRect_Mask = 0x10;
    @SuppressWarnings("unused")
    private final static int kUnknown_Mask       = 0x80;

    @SuppressWarnings("unused")
    private final static int kAllMasks           = kTranslate_Mask |
                                                   kScale_Mask |
                                                   kAffine_Mask |
                                                   kPerspective_Mask |
                                                   kRectStaysRect_Mask;

    // these guys align with the masks, so we can compute a mask from a variable 0/1
    @SuppressWarnings("unused")
    private final static int kTranslate_Shift = 0;
    @SuppressWarnings("unused")
    private final static int kScale_Shift = 1;
    @SuppressWarnings("unused")
    private final static int kAffine_Shift = 2;
    @SuppressWarnings("unused")
    private final static int kPerspective_Shift = 3;
    private final static int kRectStaysRect_Shift = 4;

    private int computeTypeMask() {
        int mask = 0;

        if (mValues[6] != 0. || mValues[7] != 0. || mValues[8] != 1.) {
            mask |= kPerspective_Mask;
        }

        if (mValues[2] != 0. || mValues[5] != 0.) {
            mask |= kTranslate_Mask;
        }

        float m00 = mValues[0];
        float m01 = mValues[1];
        float m10 = mValues[3];
        float m11 = mValues[4];

        if (m01 != 0. || m10 != 0.) {
            mask |= kAffine_Mask;
        }

        if (m00 != 1. || m11 != 1.) {
            mask |= kScale_Mask;
        }

        if ((mask & kPerspective_Mask) == 0) {
            // map non-zero to 1
            int im00 = m00 != 0 ? 1 : 0;
            int im01 = m01 != 0 ? 1 : 0;
            int im10 = m10 != 0 ? 1 : 0;
            int im11 = m11 != 0 ? 1 : 0;

            // record if the (p)rimary and (s)econdary diagonals are all 0 or
            // all non-zero (answer is 0 or 1)
            int dp0 = (im00 | im11) ^ 1;  // true if both are 0
            int dp1 = im00 & im11;        // true if both are 1
            int ds0 = (im01 | im10) ^ 1;  // true if both are 0
            int ds1 = im01 & im10;        // true if both are 1

            // return 1 if primary is 1 and secondary is 0 or
            // primary is 0 and secondary is 1
            mask |= ((dp0 & ds1) | (dp1 & ds0)) << kRectStaysRect_Shift;
        }

        return mask;
    }

    private Matrix_Delegate() {
        reset();
    }

    private Matrix_Delegate(float[] values) {
        System.arraycopy(values, 0, mValues, 0, MATRIX_SIZE);
    }

    /**
     * Adds the given transformation to the current Matrix
     * <p/>This in effect does this = this*matrix
     * @param matrix
     */
    private void postTransform(float[] matrix) {
        float[] tmp = new float[9];
        multiply(tmp, mValues, matrix);
        mValues = tmp;
    }

    /**
     * Adds the given transformation to the current Matrix
     * <p/>This in effect does this = matrix*this
     * @param matrix
     */
    private void preTransform(float[] matrix) {
        float[] tmp = new float[9];
        multiply(tmp, matrix, mValues);
        mValues = tmp;
    }

    /**
     * Apply this matrix to the array of 2D points specified by src, and write
      * the transformed points into the array of points specified by dst. The
      * two arrays represent their "points" as pairs of floats [x, y].
      *
      * @param dst   The array of dst points (x,y pairs)
      * @param dstIndex The index of the first [x,y] pair of dst floats
      * @param src   The array of src points (x,y pairs)
      * @param srcIndex The index of the first [x,y] pair of src floats
      * @param pointCount The number of points (x,y pairs) to transform
      */

     private void mapPoints(float[] dst, int dstIndex, float[] src, int srcIndex,
                           int pointCount) {
         final int count = pointCount * 2;

         float[] tmpDest = dst;
         boolean inPlace = dst == src;
         if (inPlace) {
             tmpDest = new float[dstIndex + count];
         }

         for (int i = 0 ; i < count ; i += 2) {
             // just in case we are doing in place, we better put this in temp vars
             float x = mValues[0] * src[i + srcIndex] +
                       mValues[1] * src[i + srcIndex + 1] +
                       mValues[2];
             float y = mValues[3] * src[i + srcIndex] +
                       mValues[4] * src[i + srcIndex + 1] +
                       mValues[5];

             tmpDest[i + dstIndex]     = x;
             tmpDest[i + dstIndex + 1] = y;
         }

         if (inPlace) {
             System.arraycopy(tmpDest, dstIndex, dst, dstIndex, count);
         }
     }

     /**
      * Apply this matrix to the array of 2D points, and write the transformed
      * points back into the array
      *
      * @param pts The array [x0, y0, x1, y1, ...] of points to transform.
      */

     private void mapPoints(float[] pts) {
         mapPoints(pts, 0, pts, 0, pts.length >> 1);
     }

     private void mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex, int ptCount) {
         if (hasPerspective()) {
             // transform the (0,0) point
             float[] origin = new float[] { 0.f, 0.f};
             mapPoints(origin);

             // translate the vector data as points
             mapPoints(dst, dstIndex, src, srcIndex, ptCount);

             // then substract the transformed origin.
             final int count = ptCount * 2;
             for (int i = 0 ; i < count ; i += 2) {
                 dst[dstIndex + i] = dst[dstIndex + i] - origin[0];
                 dst[dstIndex + i + 1] = dst[dstIndex + i + 1] - origin[1];
             }
         } else {
             // make a copy of the matrix
             Matrix_Delegate copy = new Matrix_Delegate(mValues);

             // remove the translation
             setTranslate(copy.mValues, 0, 0);

             // map the content as points.
             copy.mapPoints(dst, dstIndex, src, srcIndex, ptCount);
         }
     }

    /**
     * multiply two matrices and store them in a 3rd.
     * <p/>This in effect does dest = a*b
     * dest cannot be the same as a or b.
     */
     /*package*/ static void multiply(float dest[], float[] a, float[] b) {
        // first row
        dest[0] = b[0] * a[0] + b[1] * a[3] + b[2] * a[6];
        dest[1] = b[0] * a[1] + b[1] * a[4] + b[2] * a[7];
        dest[2] = b[0] * a[2] + b[1] * a[5] + b[2] * a[8];

        // 2nd row
        dest[3] = b[3] * a[0] + b[4] * a[3] + b[5] * a[6];
        dest[4] = b[3] * a[1] + b[4] * a[4] + b[5] * a[7];
        dest[5] = b[3] * a[2] + b[4] * a[5] + b[5] * a[8];

        // 3rd row
        dest[6] = b[6] * a[0] + b[7] * a[3] + b[8] * a[6];
        dest[7] = b[6] * a[1] + b[7] * a[4] + b[8] * a[7];
        dest[8] = b[6] * a[2] + b[7] * a[5] + b[8] * a[8];
    }

    /**
     * Returns a matrix that represents a given translate
     * @param dx
     * @param dy
     * @return
     */
    /*package*/ static float[] getTranslate(float dx, float dy) {
        return setTranslate(new float[9], dx, dy);
    }

    /*package*/ static float[] setTranslate(float[] dest, float dx, float dy) {
        dest[0] = 1;
        dest[1] = 0;
        dest[2] = dx;
        dest[3] = 0;
        dest[4] = 1;
        dest[5] = dy;
        dest[6] = 0;
        dest[7] = 0;
        dest[8] = 1;
        return dest;
    }

    /*package*/ static float[] getScale(float sx, float sy) {
        return new float[] { sx, 0, 0, 0, sy, 0, 0, 0, 1 };
    }

    /**
     * Returns a matrix that represents the given scale info.
     * @param sx
     * @param sy
     * @param px
     * @param py
     */
    /*package*/ static float[] getScale(float sx, float sy, float px, float py) {
        float[] tmp = new float[9];
        float[] tmp2 = new float[9];

        // TODO: do it in one pass

        // translate tmp so that the pivot is in 0,0
        setTranslate(tmp, -px, -py);

        // scale into tmp2
        multiply(tmp2, tmp, getScale(sx, sy));

        // translate back the pivot back into tmp
        multiply(tmp, tmp2, getTranslate(px, py));

        return tmp;
    }


    /*package*/ static float[] getRotate(float degrees) {
        double rad = Math.toRadians(degrees);
        float sin = (float)Math.sin(rad);
        float cos = (float)Math.cos(rad);

        return getRotate(sin, cos);
    }

    /*package*/ static float[] getRotate(float sin, float cos) {
        return setRotate(new float[9], sin, cos);
    }

    /*package*/ static float[] setRotate(float[] dest, float degrees) {
        double rad = Math.toRadians(degrees);
        float sin = (float)Math.sin(rad);
        float cos = (float)Math.cos(rad);

        return setRotate(dest, sin, cos);
    }

    /*package*/ static float[] setRotate(float[] dest, float sin, float cos) {
        dest[0] = cos;
        dest[1] = -sin;
        dest[2] = 0;
        dest[3] = sin;
        dest[4] = cos;
        dest[5] = 0;
        dest[6] = 0;
        dest[7] = 0;
        dest[8] = 1;
        return dest;
    }

    /*package*/ static float[] getRotate(float degrees, float px, float py) {
        float[] tmp = new float[9];
        float[] tmp2 = new float[9];

        // TODO: do it in one pass

        // translate so that the pivot is in 0,0
        setTranslate(tmp, -px, -py);

        // rotate into tmp2
        double rad = Math.toRadians(degrees);
        float cos = (float)Math.cos(rad);
        float sin = (float)Math.sin(rad);
        multiply(tmp2, tmp, getRotate(sin, cos));

        // translate back the pivot back into tmp
        multiply(tmp, tmp2, getTranslate(px, py));

        return tmp;
    }

    /*package*/ static float[] getSkew(float kx, float ky) {
        return new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 };
    }

    /*package*/ static float[] getSkew(float kx, float ky, float px, float py) {
        float[] tmp = new float[9];
        float[] tmp2 = new float[9];

        // TODO: do it in one pass

        // translate so that the pivot is in 0,0
        setTranslate(tmp, -px, -py);

        // skew into tmp2
        multiply(tmp2, tmp, new float[] { 1, kx, 0, ky, 1, 0, 0, 0, 1 });
        // translate back the pivot back into tmp
        multiply(tmp, tmp2, getTranslate(px, py));

        return tmp;
    }
}
